mirror of
https://github.com/mii443/mozc.git
synced 2025-08-23 00:25:34 +00:00
Rebase mozc onto Abseil logging library.
This is a relatively large update with several breaking changes. - Most of the code in `//base:logging` is now removed. - Logging calls are now handled by `@com_google_absl//absl/log`. This means: - Log message formats will change. - Important: If you have existing log files and run non-release builds (more precisely `!defined(MOZC_NO_LOGGING)`), your files will contain mixed formats after this commit. You may want to remove or rename the existing one. - Flag deprecations - `--colored_log`: they're not supported by Abseil. - `--logtostderr`: this flag had a inconsistent behavior with a google-internal flag of the same name (nor it doesn't make sense for mozc to consolidate the semantics), and is not provided by Abseil. - Note: There's no longer a way to disable log files in debug builds. A configuration option might be added later if this proves problematic. The Abseil logging library is packed with many features. It provides out-of-box integration with the Windows debugger and allows you to adjust the verbosity of your logs using command-line flags (e.g., `--stderrthreshold=0` to see all INFO level logs and above). For a full list of features, take a look at their documentation and source code. PiperOrigin-RevId: 610006013
This commit is contained in:
committed by
Hiroyuki Komatsu
parent
78aee2ace9
commit
c77285efa0
@ -128,12 +128,11 @@ bazel test base:util_test --config oss_linux -c dbg
|
|||||||
### Output logs to stderr
|
### Output logs to stderr
|
||||||
|
|
||||||
```
|
```
|
||||||
bazel test base:util_test --config oss_linux --test_arg=--logtostderr --test_output=all
|
bazel test base:util_test --config oss_linux --test_arg=--stderrthreshold=0 --test_output=all
|
||||||
```
|
```
|
||||||
|
|
||||||
* The `--test_arg=--logtostderr --test_output=all` flags shows the output of
|
* The `--test_arg=--stderrthreshold=0 --test_output=all` flags shows the
|
||||||
unitests to stderr.
|
output of unitests to stderr.
|
||||||
|
|
||||||
|
|
||||||
## Build Mozc on other Linux environment
|
## Build Mozc on other Linux environment
|
||||||
|
|
||||||
|
@ -202,7 +202,6 @@ Java_com_google_android_apps_inputmethod_libs_mozc_session_MozcJNI_initialize(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozc::Logging::InitLogStream(""); // Android doesn't stream log to a file.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ mozc_cc_library(
|
|||||||
copts = ["-DMOZC_BUILDTOOL_BUILD"],
|
copts = ["-DMOZC_BUILDTOOL_BUILD"],
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":log_file",
|
||||||
":system_util",
|
":system_util",
|
||||||
"@com_google_absl//absl/flags:flag",
|
"@com_google_absl//absl/flags:flag",
|
||||||
] + mozc_select(
|
] + mozc_select(
|
||||||
@ -81,6 +82,7 @@ mozc_cc_library(
|
|||||||
hdrs = ["init_mozc.h"],
|
hdrs = ["init_mozc.h"],
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":log_file",
|
||||||
"@com_google_absl//absl/flags:flag",
|
"@com_google_absl//absl/flags:flag",
|
||||||
] + mozc_select(
|
] + mozc_select(
|
||||||
android = ["//base"],
|
android = ["//base"],
|
||||||
@ -128,49 +130,24 @@ mozc_cc_library(
|
|||||||
|
|
||||||
mozc_cc_library(
|
mozc_cc_library(
|
||||||
name = "logging",
|
name = "logging",
|
||||||
srcs = ["logging.cc"],
|
|
||||||
hdrs = ["logging.h"],
|
hdrs = ["logging.h"],
|
||||||
linkopts = mozc_select(
|
deps = [
|
||||||
# Android requires linking logging library.
|
"@com_google_absl//absl/log",
|
||||||
android = ["-llog"],
|
"@com_google_absl//absl/log:check",
|
||||||
),
|
|
||||||
deps = mozc_select(
|
|
||||||
default = [
|
|
||||||
"@com_google_absl//absl/log",
|
|
||||||
"@com_google_absl//absl/log:check",
|
|
||||||
"//base:vlog",
|
|
||||||
],
|
|
||||||
oss = [
|
|
||||||
":clock",
|
|
||||||
":const",
|
|
||||||
":singleton",
|
|
||||||
"@com_google_absl//absl/strings",
|
|
||||||
"@com_google_absl//absl/strings:str_format",
|
|
||||||
],
|
|
||||||
wasm = [
|
|
||||||
":clock",
|
|
||||||
":const",
|
|
||||||
":singleton",
|
|
||||||
"@com_google_absl//absl/strings",
|
|
||||||
"@com_google_absl//absl/strings:str_format",
|
|
||||||
],
|
|
||||||
) + [
|
|
||||||
"@com_google_absl//absl/flags:flag",
|
|
||||||
"@com_google_absl//absl/status",
|
|
||||||
"@com_google_absl//absl/status:statusor",
|
|
||||||
"@com_google_absl//absl/synchronization",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
mozc_cc_test(
|
mozc_cc_library(
|
||||||
name = "logging_test",
|
name = "log_file",
|
||||||
size = "small",
|
srcs = ["log_file.cc"],
|
||||||
srcs = ["logging_test.cc"],
|
hdrs = ["log_file.h"],
|
||||||
requires_full_emulation = False,
|
|
||||||
deps = [
|
deps = [
|
||||||
":logging",
|
":file_stream",
|
||||||
"//testing:gunit_main",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/strings:str_format",
|
"@com_google_absl//absl/log:log_entry",
|
||||||
|
"@com_google_absl//absl/log:log_sink",
|
||||||
|
"@com_google_absl//absl/log:log_sink_registry",
|
||||||
|
"@com_google_absl//absl/synchronization",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -182,6 +159,7 @@ mozc_cc_library(
|
|||||||
":logging",
|
":logging",
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/flags:flag",
|
"@com_google_absl//absl/flags:flag",
|
||||||
|
"@com_google_absl//absl/log:flags",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
'file_stream.cc',
|
'file_stream.cc',
|
||||||
'file_util.cc',
|
'file_util.cc',
|
||||||
'init_mozc.cc',
|
'init_mozc.cc',
|
||||||
'logging.cc',
|
'log_file.cc',
|
||||||
'mmap.cc',
|
'mmap.cc',
|
||||||
'random.cc',
|
'random.cc',
|
||||||
'strings/unicode.cc',
|
'strings/unicode.cc',
|
||||||
@ -118,6 +118,7 @@
|
|||||||
'gen_character_set#host',
|
'gen_character_set#host',
|
||||||
'hash',
|
'hash',
|
||||||
'singleton',
|
'singleton',
|
||||||
|
'absl.gyp:absl_log',
|
||||||
'absl.gyp:absl_random',
|
'absl.gyp:absl_random',
|
||||||
'absl.gyp:absl_status',
|
'absl.gyp:absl_status',
|
||||||
'absl.gyp:absl_strings',
|
'absl.gyp:absl_strings',
|
||||||
|
@ -104,7 +104,6 @@
|
|||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
'sources': [
|
'sources': [
|
||||||
'container/bitarray_test.cc',
|
'container/bitarray_test.cc',
|
||||||
'logging_test.cc',
|
|
||||||
'mmap_test.cc',
|
'mmap_test.cc',
|
||||||
'random_test.h',
|
'random_test.h',
|
||||||
'singleton_test.cc',
|
'singleton_test.cc',
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include "absl/flags/parse.h"
|
#include "absl/flags/parse.h"
|
||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
#include "base/logging.h"
|
#include "base/log_file.h"
|
||||||
|
|
||||||
#ifndef MOZC_BUILDTOOL_BUILD
|
#ifndef MOZC_BUILDTOOL_BUILD
|
||||||
#include "base/system_util.h"
|
#include "base/system_util.h"
|
||||||
@ -52,6 +52,15 @@ ABSL_FLAG(std::string, log_dir, "",
|
|||||||
"If specified, logfiles are written into this directory "
|
"If specified, logfiles are written into this directory "
|
||||||
"instead of the default logging directory.");
|
"instead of the default logging directory.");
|
||||||
|
|
||||||
|
ABSL_RETIRED_FLAG(
|
||||||
|
bool, logtostderr, false,
|
||||||
|
"[Deprecated; no-op] Log messages only go to stderr, not log files.");
|
||||||
|
|
||||||
|
ABSL_RETIRED_FLAG(
|
||||||
|
bool, colored_log, true,
|
||||||
|
"[Deprecated; no-op] Enables colored log messages on tty devices");
|
||||||
|
|
||||||
|
|
||||||
ABSL_FLAG(std::string, program_invocation_name, "",
|
ABSL_FLAG(std::string, program_invocation_name, "",
|
||||||
"Program name copied from argv[0].");
|
"Program name copied from argv[0].");
|
||||||
|
|
||||||
@ -107,7 +116,7 @@ void InitMozc(const char *arg0, int *argc, char ***argv) {
|
|||||||
ParseCommandLineFlags(*argc, *argv);
|
ParseCommandLineFlags(*argc, *argv);
|
||||||
|
|
||||||
const std::string program_name = *argc > 0 ? (*argv)[0] : "UNKNOWN";
|
const std::string program_name = *argc > 0 ? (*argv)[0] : "UNKNOWN";
|
||||||
Logging::InitLogStream(GetLogFilePathFromProgramName(program_name));
|
RegisterLogFileSink(GetLogFilePathFromProgramName(program_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozc
|
} // namespace mozc
|
||||||
|
71
src/base/log_file.cc
Normal file
71
src/base/log_file.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "base/log_file.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "absl/base/thread_annotations.h"
|
||||||
|
#include "absl/log/log_entry.h"
|
||||||
|
#include "absl/log/log_sink.h"
|
||||||
|
#include "absl/log/log_sink_registry.h"
|
||||||
|
#include "absl/synchronization/mutex.h"
|
||||||
|
#include "base/file_stream.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class LogFileSink : public absl::LogSink {
|
||||||
|
public:
|
||||||
|
explicit LogFileSink(const std::string &path) : file_(path) {}
|
||||||
|
|
||||||
|
void Send(const absl::LogEntry &entry) override {
|
||||||
|
absl::MutexLock lock(&mutex_);
|
||||||
|
file_ << entry.text_message_with_prefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Flush() override {
|
||||||
|
absl::MutexLock lock(&mutex_);
|
||||||
|
file_.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
absl::Mutex mutex_;
|
||||||
|
OutputFileStream file_ ABSL_GUARDED_BY(mutex_);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void RegisterLogFileSink(const std::string &path) {
|
||||||
|
#if !defined(MOZC_NO_LOGGING) && !defined(__ANDROID__)
|
||||||
|
absl::AddLogSink(new LogFileSink(path));
|
||||||
|
#endif // !MOZC_NO_LOGGING && !__ANDROID__
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozc
|
44
src/base/log_file.h
Normal file
44
src/base/log_file.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MOZC_BASE_LOG_FILE_H_
|
||||||
|
#define MOZC_BASE_LOG_FILE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
|
||||||
|
// Registers an `absl::LogSink` tied to a file at `path`.
|
||||||
|
//
|
||||||
|
// This function becomes no-op when MOZC_NO_LOGGING or __ANDROID__ is defined.
|
||||||
|
void RegisterLogFileSink(const std::string &path);
|
||||||
|
|
||||||
|
} // namespace mozc
|
||||||
|
|
||||||
|
#endif // MOZC_BASE_LOG_FILE_H_
|
@ -1,404 +0,0 @@
|
|||||||
// Copyright 2010-2021, Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#include <android/log.h>
|
|
||||||
#endif // __ANDROID__
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define NO_MINMAX
|
|
||||||
#include <windows.h>
|
|
||||||
#else // _WIN32
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <codecvt>
|
|
||||||
#endif // _WIN32
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <locale>
|
|
||||||
#endif // _WIN32
|
|
||||||
#include <memory>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#include "base/const.h"
|
|
||||||
#endif // __ANDROID__
|
|
||||||
#include "absl/flags/flag.h"
|
|
||||||
#include "absl/strings/str_cat.h"
|
|
||||||
#include "absl/strings/string_view.h"
|
|
||||||
#include "absl/synchronization/mutex.h"
|
|
||||||
#include "base/clock.h"
|
|
||||||
#include "base/singleton.h"
|
|
||||||
|
|
||||||
ABSL_FLAG(bool, colored_log, true,
|
|
||||||
"Enables colored log messages on tty devices");
|
|
||||||
ABSL_FLAG(bool, logtostderr, false,
|
|
||||||
"log messages go to stderr instead of logfiles")
|
|
||||||
.OnUpdate([] {
|
|
||||||
mozc::Logging::SetLogToStderr(absl::GetFlag(FLAGS_logtostderr));
|
|
||||||
});
|
|
||||||
|
|
||||||
namespace mozc {
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
namespace {
|
|
||||||
// In order to make logging.h independent from <android/log.h>, we use the
|
|
||||||
// raw number to define the following constants. Check the equality here
|
|
||||||
// just in case.
|
|
||||||
#define COMPARE_LOG_LEVEL(mozc_log_level, android_log_level) \
|
|
||||||
static_assert( \
|
|
||||||
static_cast<int>(mozc_log_level) == static_cast<int>(android_log_level), \
|
|
||||||
"Checking Android log level constants.")
|
|
||||||
COMPARE_LOG_LEVEL(LOG_UNKNOWN, ANDROID_LOG_UNKNOWN);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_DEFAULT, ANDROID_LOG_DEFAULT);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_VERBOSE, ANDROID_LOG_VERBOSE);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_DEBUG, ANDROID_LOG_DEBUG);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_INFO, ANDROID_LOG_INFO);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_WARNING, ANDROID_LOG_WARN);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_ERROR, ANDROID_LOG_ERROR);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_FATAL, ANDROID_LOG_FATAL);
|
|
||||||
COMPARE_LOG_LEVEL(LOG_SILENT, ANDROID_LOG_SILENT);
|
|
||||||
#undef COMPARE_LOG_LEVEL
|
|
||||||
} // namespace
|
|
||||||
#endif // __ANDROID__
|
|
||||||
|
|
||||||
// Use the same implementation both for Opt and Debug.
|
|
||||||
std::string Logging::GetLogMessageHeader() {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
// On Android, other records are not needed because they are added by
|
|
||||||
// Android's logging framework.
|
|
||||||
return absl::StrCat(pthread_self(), " "); // returns unsigned long.
|
|
||||||
|
|
||||||
#else // __ANDROID__
|
|
||||||
|
|
||||||
const absl::Time at = Clock::GetAbslTime();
|
|
||||||
const absl::TimeZone tz = Clock::GetTimeZone();
|
|
||||||
const std::string timestamp = absl::FormatTime("%Y-%m-%d %H:%M:%S ", at, tz);
|
|
||||||
|
|
||||||
#if defined(__wasm__)
|
|
||||||
return absl::StrCat(timestamp, ::getpid(), " ",
|
|
||||||
static_cast<unsigned int>(pthread_self()));
|
|
||||||
#elif defined(__linux__)
|
|
||||||
return absl::StrCat(timestamp, ::getpid(), " ",
|
|
||||||
// It returns unsigned long.
|
|
||||||
pthread_self());
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#ifdef __LP64__
|
|
||||||
return absl::StrCat(timestamp, ::getpid(), " ",
|
|
||||||
reinterpret_cast<uint64_t>(pthread_self()));
|
|
||||||
#else // __LP64__
|
|
||||||
return absl::StrCat(timestamp, ::getpid(), " ", ::getpid(),
|
|
||||||
reinterpret_cast<uint32_t>(pthread_self()));
|
|
||||||
#endif // __LP64__
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
return absl::StrCat(timestamp, ::GetCurrentProcessId(), " ",
|
|
||||||
::GetCurrentThreadId());
|
|
||||||
#endif // _WIN32
|
|
||||||
#endif // __ANDROID__
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
void Logging::InitLogStream(const std::string &log_file_path) {}
|
|
||||||
|
|
||||||
void Logging::CloseLogStream() {}
|
|
||||||
|
|
||||||
WorkingLogStream &Logging::GetWorkingLogStream() {
|
|
||||||
// Never called.
|
|
||||||
return *(new WorkingLogStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logging::FinalizeWorkingLogStream(LogSeverity severity,
|
|
||||||
WorkingLogStream *working_stream) {
|
|
||||||
// Never called.
|
|
||||||
delete working_stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
NullLogStream &Logging::GetNullLogStream() {
|
|
||||||
return *(Singleton<NullLogStream>::get());
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Logging::GetLogSeverityName(LogSeverity severity) { return ""; }
|
|
||||||
|
|
||||||
const char *Logging::GetBeginColorEscapeSequence(LogSeverity severity) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Logging::GetEndColorEscapeSequence() { return ""; }
|
|
||||||
|
|
||||||
void Logging::SetLogToStderr(bool log_to_stderr) {}
|
|
||||||
|
|
||||||
#else // MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class LogStreamImpl {
|
|
||||||
public:
|
|
||||||
LogStreamImpl();
|
|
||||||
~LogStreamImpl();
|
|
||||||
|
|
||||||
void Init(const std::string &log_file_path);
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
bool support_color() const { return support_color_; }
|
|
||||||
|
|
||||||
void Write(LogSeverity, const std::string &log);
|
|
||||||
void set_log_to_stderr(bool log_to_stderr) {
|
|
||||||
#if defined(__ANDROID__)
|
|
||||||
// Android uses Android's log library.
|
|
||||||
use_cerr_ = false;
|
|
||||||
#else // __ANDROID__
|
|
||||||
absl::MutexLock l(&mutex_);
|
|
||||||
use_cerr_ = log_to_stderr;
|
|
||||||
#endif // !__ANDROID__
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ResetUnlocked();
|
|
||||||
|
|
||||||
// Real backing log stream.
|
|
||||||
// This is not thread-safe so must be guarded.
|
|
||||||
// If std::cerr is real log stream, this is empty.
|
|
||||||
std::unique_ptr<std::ostream> real_log_stream_;
|
|
||||||
bool support_color_ = false;
|
|
||||||
bool use_cerr_ = false;
|
|
||||||
absl::Mutex mutex_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void LogStreamImpl::Write(LogSeverity severity, const std::string &log) {
|
|
||||||
absl::MutexLock l(&mutex_);
|
|
||||||
if (use_cerr_) {
|
|
||||||
std::cerr << log;
|
|
||||||
} else {
|
|
||||||
#if defined(__ANDROID__)
|
|
||||||
__android_log_write(severity, kProductPrefix,
|
|
||||||
const_cast<char *>(log.c_str()));
|
|
||||||
#else // __ANDROID__
|
|
||||||
// Since our logging mechanism is essentially singleton, it is indeed
|
|
||||||
// possible that this method is called before |Logging::InitLogStream()|.
|
|
||||||
// b/32360767 is an example, where |SystemUtil::GetLoggingDirectory()|
|
|
||||||
// called as a preparation for |Logging::InitLogStream()| internally
|
|
||||||
// triggered |LOG(ERROR)|.
|
|
||||||
if (real_log_stream_) {
|
|
||||||
*real_log_stream_ << log;
|
|
||||||
real_log_stream_->flush();
|
|
||||||
}
|
|
||||||
#endif // !__ANDROID__
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogStreamImpl::LogStreamImpl() { Reset(); }
|
|
||||||
|
|
||||||
// Initializes real log stream.
|
|
||||||
// After initialization, use_cerr_ and real_log_stream_ become like following:
|
|
||||||
// OS, --logtostderr => use_cerr_, real_log_stream_
|
|
||||||
// Android, * => false, empty
|
|
||||||
// Others, true => true, empty
|
|
||||||
// Others, false => true, initialized
|
|
||||||
void LogStreamImpl::Init(const std::string &log_file_path) {
|
|
||||||
absl::MutexLock l(&mutex_);
|
|
||||||
ResetUnlocked();
|
|
||||||
|
|
||||||
if (use_cerr_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if defined(_WIN32)
|
|
||||||
// On Windows, just create a stream.
|
|
||||||
// Since Windows uses UTF-16 for internationalized file names, we should
|
|
||||||
// convert the encoding of the given |log_file_path| from UTF-8 to UTF-16.
|
|
||||||
// NOTE: To avoid circular dependency, |Util::Utf8ToWide| shouldn't be used
|
|
||||||
// here.
|
|
||||||
DCHECK_NE(log_file_path.size(), 0);
|
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf8_to_wide;
|
|
||||||
real_log_stream_ = std::make_unique<std::ofstream>(
|
|
||||||
utf8_to_wide.from_bytes(log_file_path).c_str(), std::ios::app);
|
|
||||||
#elif !defined(__ANDROID__)
|
|
||||||
// On non-Android platform, change file mode in addition.
|
|
||||||
// Android uses logcat instead of log file.
|
|
||||||
DCHECK_NE(log_file_path.size(), 0);
|
|
||||||
real_log_stream_ =
|
|
||||||
std::make_unique<std::ofstream>(log_file_path.c_str(), std::ios::app);
|
|
||||||
::chmod(log_file_path.c_str(), 0600);
|
|
||||||
#endif // !(_WIN32 ||__ANDROID__)
|
|
||||||
DCHECK(!use_cerr_ || !real_log_stream_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogStreamImpl::Reset() {
|
|
||||||
absl::MutexLock l(&mutex_);
|
|
||||||
ResetUnlocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogStreamImpl::ResetUnlocked() {
|
|
||||||
real_log_stream_.reset();
|
|
||||||
#if defined(__ANDROID__) || defined(_WIN32)
|
|
||||||
// On Android, the standard log library is used.
|
|
||||||
// On Windows, coloring is disabled
|
|
||||||
// because cmd.exe doesn't support ANSI color escape sequences.
|
|
||||||
// TODO(team): Considers to use SetConsoleTextAttribute on Windows.
|
|
||||||
support_color_ = false;
|
|
||||||
#else // __ANDROID__, _WIN32
|
|
||||||
support_color_ = (use_cerr_ && absl::GetFlag(FLAGS_colored_log) &&
|
|
||||||
::isatty(::fileno(stderr)));
|
|
||||||
#endif // !(__ANDROID__ || _WIN32)
|
|
||||||
// use_cerr_ is updated by ABSL_FLAG.OnUpdate().
|
|
||||||
}
|
|
||||||
|
|
||||||
LogStreamImpl::~LogStreamImpl() { Reset(); }
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void Logging::InitLogStream(const std::string &log_file_path) {
|
|
||||||
Singleton<LogStreamImpl>::get()->Init(log_file_path);
|
|
||||||
WorkingLogStream &stream = GetWorkingLogStream();
|
|
||||||
stream << "Log file created at: " << Logging::GetLogMessageHeader();
|
|
||||||
FinalizeWorkingLogStream(LogSeverity::LOG_INFO, &stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logging::CloseLogStream() { Singleton<LogStreamImpl>::get()->Reset(); }
|
|
||||||
|
|
||||||
WorkingLogStream &Logging::GetWorkingLogStream() {
|
|
||||||
return *(new WorkingLogStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logging::FinalizeWorkingLogStream(LogSeverity severity,
|
|
||||||
WorkingLogStream *working_stream) {
|
|
||||||
*working_stream << std::endl;
|
|
||||||
Singleton<LogStreamImpl>::get()->Write(severity, working_stream->str());
|
|
||||||
// The working stream is new'd in LogStreamImpl::GetWorkingLogStream().
|
|
||||||
// Must be deleted by finalizer.
|
|
||||||
delete working_stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
NullLogStream &Logging::GetNullLogStream() {
|
|
||||||
return *(Singleton<NullLogStream>::get());
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
// ANSI Color escape sequences.
|
|
||||||
// FYI: Other escape sequences are here.
|
|
||||||
// Black: "\x1b[30m"
|
|
||||||
// Green "\x1b[32m"
|
|
||||||
// Blue: "\x1b[34m"
|
|
||||||
// Magenta: "\x1b[35m"
|
|
||||||
// White "\x1b[37m"
|
|
||||||
constexpr const char kClearEscapeSequence[] = "\x1b[0m";
|
|
||||||
constexpr const char kRedEscapeSequence[] = "\x1b[31m";
|
|
||||||
constexpr const char kYellowEscapeSequence[] = "\x1b[33m";
|
|
||||||
constexpr const char kCyanEscapeSequence[] = "\x1b[36m";
|
|
||||||
|
|
||||||
constexpr struct SeverityProperty {
|
|
||||||
public:
|
|
||||||
const char *label;
|
|
||||||
const char *color_escape_sequence;
|
|
||||||
} kSeverityProperties[] = {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
{"UNKNOWN", kCyanEscapeSequence}, {"DEFAULT", kCyanEscapeSequence},
|
|
||||||
{"VERBOSE", kCyanEscapeSequence}, {"DEBUG", kCyanEscapeSequence},
|
|
||||||
{"INFO", kCyanEscapeSequence}, {"WARNING", kYellowEscapeSequence},
|
|
||||||
{"ERROR", kRedEscapeSequence}, {"FATAL", kRedEscapeSequence},
|
|
||||||
{"SILENT", kCyanEscapeSequence},
|
|
||||||
#else // __ANDROID__
|
|
||||||
{"INFO", kCyanEscapeSequence},
|
|
||||||
{"WARNING", kYellowEscapeSequence},
|
|
||||||
{"ERROR", kRedEscapeSequence},
|
|
||||||
{"FATAL", kRedEscapeSequence},
|
|
||||||
#endif // !__ANDROID__
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
const char *Logging::GetLogSeverityName(LogSeverity severity) {
|
|
||||||
return kSeverityProperties[severity].label;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Logging::GetBeginColorEscapeSequence(LogSeverity severity) {
|
|
||||||
if (Singleton<LogStreamImpl>::get()->support_color()) {
|
|
||||||
return kSeverityProperties[severity].color_escape_sequence;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Logging::GetEndColorEscapeSequence() {
|
|
||||||
if (Singleton<LogStreamImpl>::get()->support_color()) {
|
|
||||||
return kClearEscapeSequence;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logging::SetLogToStderr(bool log_to_stderr) {
|
|
||||||
Singleton<LogStreamImpl>::get()->set_log_to_stderr(log_to_stderr);
|
|
||||||
}
|
|
||||||
#endif // !MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
LogFinalizer::LogFinalizer(LogSeverity severity) : severity_(severity) {}
|
|
||||||
|
|
||||||
LogFinalizer::~LogFinalizer() {
|
|
||||||
Logging::FinalizeWorkingLogStream(severity_, working_stream_);
|
|
||||||
if (severity_ >= LOG_FATAL) {
|
|
||||||
// On windows, call exception handler to
|
|
||||||
// make stack trace and minidump
|
|
||||||
#ifdef _WIN32
|
|
||||||
::RaiseException(::GetLastError(), EXCEPTION_NONCONTINUABLE, 0, nullptr);
|
|
||||||
#else // _WIN32
|
|
||||||
mozc::Logging::CloseLogStream();
|
|
||||||
exit(-1);
|
|
||||||
#endif // !_WIN32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorkingLogStream::Append(size_t count, const char ch) {
|
|
||||||
while (count-- > 0) {
|
|
||||||
os_.put(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorkingLogStream::Append(const absl::string_view v) {
|
|
||||||
os_.write(v.data(), v.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFinalizer::operator&(WorkingLogStream &working_stream) {
|
|
||||||
working_stream_ = &working_stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NullLogFinalizer::OnFatal() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
::RaiseException(::GetLastError(), EXCEPTION_NONCONTINUABLE, 0, nullptr);
|
|
||||||
#else // _WIN32
|
|
||||||
exit(-1);
|
|
||||||
#endif // !_WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mozc
|
|
@ -30,335 +30,37 @@
|
|||||||
#ifndef MOZC_BASE_LOGGING_H_
|
#ifndef MOZC_BASE_LOGGING_H_
|
||||||
#define MOZC_BASE_LOGGING_H_
|
#define MOZC_BASE_LOGGING_H_
|
||||||
|
|
||||||
#include <string>
|
// These includes are kept for legacy reasons. Prefer including them directly,
|
||||||
|
// unless you use DFATAL severity backported below.
|
||||||
|
#include "absl/log/check.h" // IWYU pragma: keep
|
||||||
|
#include "absl/log/log.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
// Note that abseil HEAD has ABSL_LTS_RELEASE_VERSION undefined.
|
||||||
#include <iostream>
|
#if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20240116
|
||||||
#include <sstream>
|
// Older version of abseil doesn't ship with DFATAL. This is a very hacky
|
||||||
#include <type_traits>
|
// backport that needs to be removed as soon as we migrate to Abseil LTS
|
||||||
|
// 20240116.
|
||||||
#include "absl/flags/declare.h"
|
|
||||||
#include "absl/flags/flag.h"
|
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "absl/status/statusor.h"
|
|
||||||
#include "absl/strings/string_view.h"
|
|
||||||
|
|
||||||
ABSL_DECLARE_FLAG(bool, logtostderr);
|
|
||||||
|
|
||||||
namespace mozc {
|
|
||||||
|
|
||||||
enum LogSeverity {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
// Defined in <android/log.h>
|
|
||||||
LOG_UNKNOWN = 0, // ANDROID_LOG_UNKNOWN
|
|
||||||
LOG_DEFAULT = 1, // ANDROID_LOG_DEFAULT
|
|
||||||
LOG_VERBOSE = 2, // ANDROID_LOG_VERBOSE
|
|
||||||
LOG_DEBUG = 3, // ANDROID_LOG_DEBUG
|
|
||||||
LOG_INFO = 4, // ANDROID_LOG_INFO
|
|
||||||
LOG_WARNING = 5, // ANDROID_LOG_WARN
|
|
||||||
LOG_ERROR = 6, // ANDROID_LOG_ERROR
|
|
||||||
LOG_FATAL = 7, // ANDROID_LOG_FATAL
|
|
||||||
LOG_SILENT = 8, // ANDROID_LOG_SILENT
|
|
||||||
LOG_SEVERITY_SIZE = 9,
|
|
||||||
#else // __ANDROID__
|
|
||||||
LOG_INFO = 0,
|
|
||||||
LOG_WARNING = 1,
|
|
||||||
LOG_ERROR = 2,
|
|
||||||
// Special hack for Windows build, where ERROR is defined as 0 in wingdi.h.
|
|
||||||
#ifdef _WIN32
|
|
||||||
LOG_0 = LOG_ERROR,
|
|
||||||
#endif // _WIN32
|
|
||||||
LOG_FATAL = 3,
|
|
||||||
LOG_SEVERITY_SIZE = 4,
|
|
||||||
#endif // !__ANDROID__
|
|
||||||
};
|
|
||||||
|
|
||||||
// DFATAL is FATAL in debug mode, ERROR in normal mode
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define LOG_DFATAL LOG_FATAL
|
#define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
|
||||||
|
ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition)
|
||||||
|
|
||||||
|
namespace absl {
|
||||||
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
static constexpr absl::LogSeverity kLogDebugFatal = absl::LogSeverity::kFatal;
|
||||||
|
ABSL_NAMESPACE_END
|
||||||
|
} // namespace absl
|
||||||
#else // DEBUG
|
#else // DEBUG
|
||||||
#define LOG_DFATAL LOG_ERROR
|
#define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
|
||||||
|
ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition)
|
||||||
|
|
||||||
|
namespace absl {
|
||||||
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
static constexpr absl::LogSeverity kLogDebugFatal = absl::LogSeverity::kError;
|
||||||
|
ABSL_NAMESPACE_END
|
||||||
|
} // namespace absl
|
||||||
#endif // !DEBUG
|
#endif // !DEBUG
|
||||||
|
#endif // ABSL_LTS_RELEASE_VERSION < 20240116
|
||||||
|
|
||||||
class WorkingLogStream;
|
|
||||||
class NullLogStream;
|
|
||||||
|
|
||||||
class Logging {
|
|
||||||
public:
|
|
||||||
Logging() = delete;
|
|
||||||
Logging(const Logging &) = delete;
|
|
||||||
Logging &operator=(const Logging &) = delete;
|
|
||||||
// Initializes log stream with the output file path and --logtostderr.
|
|
||||||
static void InitLogStream(const std::string &log_file_path);
|
|
||||||
|
|
||||||
// Closes the logging stream
|
|
||||||
static void CloseLogStream();
|
|
||||||
|
|
||||||
// Gets working log stream. The log message can be written to the stream.
|
|
||||||
// The stream must be finalized by FinalizeWorkingLogStream().
|
|
||||||
static WorkingLogStream &GetWorkingLogStream();
|
|
||||||
|
|
||||||
// Finalizes the working stream.
|
|
||||||
// - Appends std::endl to working stream.
|
|
||||||
// - Writes the content to real backing logging stream, which is initialized
|
|
||||||
// by InitLogStream().
|
|
||||||
// - Deletes the working stream object.
|
|
||||||
static void FinalizeWorkingLogStream(LogSeverity, WorkingLogStream *);
|
|
||||||
|
|
||||||
// Gets NullLogStream for MOZC_NO_LOGGING mode
|
|
||||||
static NullLogStream &GetNullLogStream();
|
|
||||||
|
|
||||||
// Converts LogSeverity to the string name
|
|
||||||
static const char *GetLogSeverityName(LogSeverity severity);
|
|
||||||
|
|
||||||
// Returns "YYYY-MM-DD HH:MM:SS PID TID", e.g. "2008 11-16 19:40:21 100 20"
|
|
||||||
static std::string GetLogMessageHeader();
|
|
||||||
|
|
||||||
// Gets an escape sequence to colorize log messages on tty devices.
|
|
||||||
static const char *GetBeginColorEscapeSequence(LogSeverity severity);
|
|
||||||
static const char *GetEndColorEscapeSequence();
|
|
||||||
|
|
||||||
static void SetLogToStderr(bool log_to_stderr);
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace logging_internal {
|
|
||||||
|
|
||||||
// Based on
|
|
||||||
// https://github.com/abseil/abseil-cpp/blob/master/absl/strings/internal/has_absl_stringify.h
|
|
||||||
//
|
|
||||||
// This can be removed once Abseil LTS supports `absl::HasAbslStringify`.
|
|
||||||
template <typename T, typename = void>
|
|
||||||
struct HasAbslStringify : std::false_type {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct HasAbslStringify<
|
|
||||||
T, std::void_t<decltype(AbslStringify(std::declval<WorkingLogStream &>(),
|
|
||||||
std::declval<const T &>()))>>
|
|
||||||
: std::true_type {};
|
|
||||||
|
|
||||||
} // namespace logging_internal
|
|
||||||
|
|
||||||
// WorkingLogStream is a std::ostringstream that also implements Abseil's Sink.
|
|
||||||
class WorkingLogStream {
|
|
||||||
public:
|
|
||||||
WorkingLogStream() = default;
|
|
||||||
|
|
||||||
// Sink methods.
|
|
||||||
// https://github.com/abseil/abseil-cpp/blob/master/absl/strings/internal/stringify_sink.h
|
|
||||||
void Append(size_t count, char ch);
|
|
||||||
void Append(absl::string_view v);
|
|
||||||
friend void AbslFormatFlush(WorkingLogStream *sink, absl::string_view v) {
|
|
||||||
sink->Append(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T,
|
|
||||||
std::enable_if_t<logging_internal::HasAbslStringify<T>::value,
|
|
||||||
std::nullptr_t> = nullptr>
|
|
||||||
WorkingLogStream &operator<<(const T &v) {
|
|
||||||
AbslStringify(*this, v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template <typename T,
|
|
||||||
std::enable_if_t<!logging_internal::HasAbslStringify<T>::value,
|
|
||||||
std::nullptr_t> = nullptr>
|
|
||||||
WorkingLogStream &operator<<(const T &v) {
|
|
||||||
os_ << v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
WorkingLogStream &operator<<(std::ostream &(*func)(std::ostream &)) {
|
|
||||||
os_ << func;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string str() const { return os_.str(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::ostringstream os_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Finalizer to flush/delete working log stream.
|
|
||||||
// Finalizer takes woking log stream instance through operator&()
|
|
||||||
// and finalizes it in destructor.
|
|
||||||
class LogFinalizer {
|
|
||||||
public:
|
|
||||||
explicit LogFinalizer(LogSeverity severity);
|
|
||||||
~LogFinalizer();
|
|
||||||
|
|
||||||
void operator&(WorkingLogStream &);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const LogSeverity severity_;
|
|
||||||
WorkingLogStream *working_stream_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// When using NullLogStream, all debug message will be stripped
|
|
||||||
class NullLogStream {
|
|
||||||
public:
|
|
||||||
template <typename T>
|
|
||||||
NullLogStream &operator<<(const T &value) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
NullLogStream &operator<<(std::ostream &(*pfunc)(std::ostream &)) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class NullLogFinalizer {
|
|
||||||
public:
|
|
||||||
explicit NullLogFinalizer(LogSeverity severity) : severity_(severity) {}
|
|
||||||
|
|
||||||
~NullLogFinalizer() {
|
|
||||||
if (severity_ >= LOG_FATAL) {
|
|
||||||
OnFatal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator&(NullLogStream &) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void OnFatal();
|
|
||||||
|
|
||||||
const LogSeverity severity_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace mozc
|
|
||||||
|
|
||||||
// ad-hoc porting of google-glog
|
|
||||||
#ifdef MOZC_NO_LOGGING // don't use logging feature.
|
|
||||||
|
|
||||||
// in release binary, we don't want to evaluate the outputs for logging.
|
|
||||||
// LOG(FATAL) is an exception.
|
|
||||||
#define LOG(severity) \
|
|
||||||
(mozc::LOG_##severity < mozc::LOG_FATAL) \
|
|
||||||
? (void)0 \
|
|
||||||
: mozc::NullLogFinalizer(mozc::LOG_##severity) & \
|
|
||||||
mozc::Logging::GetNullLogStream()
|
|
||||||
|
|
||||||
// To suppress the "statement has no effect" waring, (void) is
|
|
||||||
// inserted. This technique is suggested by the gcc manual
|
|
||||||
// -Wunused-variable section.
|
|
||||||
#define LOG_IF(severity, condition) \
|
|
||||||
(mozc::LOG_##severity < mozc::LOG_FATAL || !(condition)) \
|
|
||||||
? (void)0 \
|
|
||||||
: mozc::NullLogFinalizer(mozc::LOG_##severity) & \
|
|
||||||
mozc::Logging::GetNullLogStream()
|
|
||||||
|
|
||||||
#define CHECK(condition) \
|
|
||||||
(condition) ? (void)0 \
|
|
||||||
: mozc::NullLogFinalizer(mozc::LOG_FATAL) & \
|
|
||||||
mozc::Logging::GetNullLogStream()
|
|
||||||
|
|
||||||
#else // MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
#define LOG(severity) \
|
|
||||||
mozc::LogFinalizer(mozc::LOG_##severity) & \
|
|
||||||
mozc::Logging::GetWorkingLogStream() \
|
|
||||||
<< mozc::Logging::GetLogMessageHeader() << " " << __FILE__ << "(" \
|
|
||||||
<< __LINE__ << ") " \
|
|
||||||
<< mozc::Logging::GetBeginColorEscapeSequence(mozc::LOG_##severity) \
|
|
||||||
<< "LOG(" << mozc::Logging::GetLogSeverityName(mozc::LOG_##severity) \
|
|
||||||
<< ")" << mozc::Logging::GetEndColorEscapeSequence() << " "
|
|
||||||
|
|
||||||
#define LOG_IF(severity, condition) \
|
|
||||||
(!(condition)) \
|
|
||||||
? (void)0 \
|
|
||||||
: mozc::LogFinalizer(mozc::LOG_##severity) & \
|
|
||||||
mozc::Logging::GetWorkingLogStream() \
|
|
||||||
<< mozc::Logging::GetLogMessageHeader() << " " << __FILE__ \
|
|
||||||
<< "(" << __LINE__ << ") " \
|
|
||||||
<< mozc::Logging::GetBeginColorEscapeSequence( \
|
|
||||||
mozc::LOG_##severity) \
|
|
||||||
<< "LOG(" \
|
|
||||||
<< mozc::Logging::GetLogSeverityName(mozc::LOG_##severity) \
|
|
||||||
<< ")" << mozc::Logging::GetEndColorEscapeSequence() << " [" \
|
|
||||||
<< #condition << "] "
|
|
||||||
|
|
||||||
#define CHECK(condition) \
|
|
||||||
(condition) \
|
|
||||||
? (void)0 \
|
|
||||||
: mozc::LogFinalizer(mozc::LOG_FATAL) & \
|
|
||||||
mozc::Logging::GetWorkingLogStream() \
|
|
||||||
<< mozc::Logging::GetLogMessageHeader() << " " << __FILE__ \
|
|
||||||
<< "(" << __LINE__ << ") " \
|
|
||||||
<< mozc::Logging::GetBeginColorEscapeSequence(mozc::LOG_FATAL) \
|
|
||||||
<< "CHECK" << mozc::Logging::GetEndColorEscapeSequence() \
|
|
||||||
<< " [" << #condition << "] "
|
|
||||||
#endif // !MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
#define CHECK_EQ(a, b) CHECK((a) == (b))
|
|
||||||
#define CHECK_NE(a, b) CHECK((a) != (b))
|
|
||||||
#define CHECK_GE(a, b) CHECK((a) >= (b))
|
|
||||||
#define CHECK_LE(a, b) CHECK((a) <= (b))
|
|
||||||
#define CHECK_GT(a, b) CHECK((a) > (b))
|
|
||||||
#define CHECK_LT(a, b) CHECK((a) < (b))
|
|
||||||
|
|
||||||
// Debug build
|
|
||||||
#if defined(DEBUG) || defined(_DEBUG)
|
|
||||||
|
|
||||||
#define DLOG(severity) LOG(severity)
|
|
||||||
#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
|
|
||||||
#define DCHECK(condition) CHECK(condition)
|
|
||||||
#define DCHECK_EQ(a, b) CHECK_EQ(a, b)
|
|
||||||
#define DCHECK_NE(a, b) CHECK_NE(a, b)
|
|
||||||
#define DCHECK_GE(a, b) CHECK_GE(a, b)
|
|
||||||
#define DCHECK_LE(a, b) CHECK_LE(a, b)
|
|
||||||
#define DCHECK_GT(a, b) CHECK_GT(a, b)
|
|
||||||
#define DCHECK_LT(a, b) CHECK_LT(a, b)
|
|
||||||
|
|
||||||
#else // opt build
|
|
||||||
|
|
||||||
#define DLOG(severity) \
|
|
||||||
mozc::NullLogFinalizer(mozc::LOG_##severity) & \
|
|
||||||
mozc::Logging::GetNullLogStream()
|
|
||||||
|
|
||||||
#define DLOG_IF(severity, condition) \
|
|
||||||
(true || !(condition)) ? (void)0 \
|
|
||||||
: mozc::NullLogFinalizer(mozc::LOG_##severity) & \
|
|
||||||
mozc::Logging::GetNullLogStream()
|
|
||||||
|
|
||||||
#define DCHECK(condition) \
|
|
||||||
while (false) CHECK(condition)
|
|
||||||
#define DCHECK_EQ(a, b) \
|
|
||||||
while (false) CHECK_EQ(a, b)
|
|
||||||
#define DCHECK_NE(a, b) \
|
|
||||||
while (false) CHECK_NE(a, b)
|
|
||||||
#define DCHECK_GE(a, b) \
|
|
||||||
while (false) CHECK_GE(a, b)
|
|
||||||
#define DCHECK_LE(a, b) \
|
|
||||||
while (false) CHECK_LE(a, b)
|
|
||||||
#define DCHECK_GT(a, b) \
|
|
||||||
while (false) CHECK_GT(a, b)
|
|
||||||
#define DCHECK_LT(a, b) \
|
|
||||||
while (false) CHECK_LT(a, b)
|
|
||||||
|
|
||||||
#endif // opt build
|
|
||||||
|
|
||||||
#ifndef MOZC_LOG_PROTOBUF
|
|
||||||
#define MOZC_LOG_PROTOBUF(message) ((message).DebugString())
|
#define MOZC_LOG_PROTOBUF(message) ((message).DebugString())
|
||||||
#endif // MOZC_LOG_PROTOBUF
|
|
||||||
|
|
||||||
// CHECK_OK and DCHECK_OK
|
|
||||||
namespace mozc::status_internal {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline const absl::Status &AsStatus(const absl::StatusOr<T> &status_or) {
|
|
||||||
return status_or.status();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const absl::Status &AsStatus(const absl::Status &status) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mozc::status_internal
|
|
||||||
|
|
||||||
#define CHECK_OK(val) \
|
|
||||||
CHECK_EQ(absl::OkStatus(), ::mozc::status_internal::AsStatus(val))
|
|
||||||
#define DCHECK_OK(val) \
|
|
||||||
DCHECK_EQ(absl::OkStatus(), ::mozc::status_internal::AsStatus(val))
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MOZC_LOG_PROTOBUF
|
|
||||||
#define MOZC_LOG_PROTOBUF(message) (message)
|
|
||||||
#endif // !MOZC_LOG_PROTOBUF
|
|
||||||
|
|
||||||
#endif // MOZC_BASE_LOGGING_H_
|
#endif // MOZC_BASE_LOGGING_H_
|
||||||
|
@ -1,226 +0,0 @@
|
|||||||
// Copyright 2010-2021, Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "absl/strings/str_format.h"
|
|
||||||
#include "testing/gunit.h"
|
|
||||||
|
|
||||||
namespace mozc {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
TEST(LoggingTest, CompileTest) {
|
|
||||||
if (false) {
|
|
||||||
LOG(INFO) << "";
|
|
||||||
LOG(WARNING) << "";
|
|
||||||
LOG(ERROR) << "";
|
|
||||||
LOG(DFATAL) << "";
|
|
||||||
LOG(FATAL) << "";
|
|
||||||
}
|
|
||||||
if (false) {
|
|
||||||
DLOG(INFO) << "";
|
|
||||||
DLOG(WARNING) << "";
|
|
||||||
DLOG(ERROR) << "";
|
|
||||||
DLOG(FATAL) << "";
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_IF(INFO, false) << "";
|
|
||||||
LOG_IF(WARNING, false) << "";
|
|
||||||
LOG_IF(ERROR, false) << "";
|
|
||||||
LOG_IF(DFATAL, false) << "";
|
|
||||||
LOG_IF(FATAL, false) << "";
|
|
||||||
|
|
||||||
DLOG_IF(INFO, false) << "";
|
|
||||||
DLOG_IF(WARNING, false) << "";
|
|
||||||
DLOG_IF(ERROR, false) << "";
|
|
||||||
DLOG_IF(FATAL, false) << "";
|
|
||||||
|
|
||||||
CHECK(true) << "";
|
|
||||||
CHECK_EQ(true, true) << "";
|
|
||||||
CHECK_NE(true, false) << "";
|
|
||||||
CHECK_GE(2, 1) << "";
|
|
||||||
CHECK_GE(1, 1) << "";
|
|
||||||
CHECK_LE(1, 2) << "";
|
|
||||||
CHECK_LE(1, 1) << "";
|
|
||||||
CHECK_GT(2, 1) << "";
|
|
||||||
CHECK_LT(1, 2) << "";
|
|
||||||
|
|
||||||
DCHECK(true) << "";
|
|
||||||
DCHECK_EQ(true, true) << "";
|
|
||||||
DCHECK_NE(true, false) << "";
|
|
||||||
DCHECK_GE(2, 1) << "";
|
|
||||||
DCHECK_GE(1, 1) << "";
|
|
||||||
DCHECK_LE(1, 2) << "";
|
|
||||||
DCHECK_LE(1, 1) << "";
|
|
||||||
DCHECK_GT(2, 1) << "";
|
|
||||||
DCHECK_LT(1, 2) << "";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(LoggingTest, SideEffectTest) {
|
|
||||||
bool flag = false;
|
|
||||||
|
|
||||||
#ifdef MOZC_NO_LOGGING
|
|
||||||
// LOG_(INFO|WARNING|ERROR|DFATAL) are not executed on release mode
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(INFO, flag = false) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(WARNING, flag = false) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(ERROR, flag = false) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(DFATAL, flag = false) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
#else // MOZC_NO_LOGGING
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(INFO, flag = false) << "";
|
|
||||||
EXPECT_FALSE(flag);
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(WARNING, flag = false) << "";
|
|
||||||
EXPECT_FALSE(flag);
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(ERROR, flag = false) << "";
|
|
||||||
EXPECT_FALSE(flag);
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(DFATAL, flag = false) << "";
|
|
||||||
EXPECT_FALSE(flag);
|
|
||||||
#endif // !MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
flag = true;
|
|
||||||
LOG_IF(FATAL, flag = false) << "";
|
|
||||||
EXPECT_FALSE(flag);
|
|
||||||
|
|
||||||
flag = false;
|
|
||||||
CHECK(flag = true) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
|
|
||||||
flag = false;
|
|
||||||
CHECK_EQ(true, flag = true) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
|
|
||||||
flag = false;
|
|
||||||
CHECK_NE(false, flag = true) << "";
|
|
||||||
EXPECT_TRUE(flag);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
i = 10;
|
|
||||||
CHECK_GE(20, i = 11) << "";
|
|
||||||
EXPECT_EQ(i, 11);
|
|
||||||
|
|
||||||
i = 10;
|
|
||||||
CHECK_GT(20, i = 11) << "";
|
|
||||||
EXPECT_EQ(i, 11);
|
|
||||||
|
|
||||||
i = 10;
|
|
||||||
CHECK_LE(1, i = 11) << "";
|
|
||||||
EXPECT_EQ(i, 11);
|
|
||||||
|
|
||||||
i = 10;
|
|
||||||
CHECK_LT(1, i = 11) << "";
|
|
||||||
EXPECT_EQ(i, 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
int g_counter = 0;
|
|
||||||
std::string DebugString() {
|
|
||||||
++g_counter;
|
|
||||||
std::ostringstream os;
|
|
||||||
os << g_counter << " test!";
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST(LoggingTest, RightHandSideEvaluation) {
|
|
||||||
g_counter = 0;
|
|
||||||
LOG(INFO) << "test: " << DebugString();
|
|
||||||
LOG(ERROR) << "test: " << DebugString();
|
|
||||||
LOG(WARNING) << "test: " << DebugString();
|
|
||||||
|
|
||||||
#ifdef MOZC_NO_LOGGING
|
|
||||||
EXPECT_EQ(g_counter, 0);
|
|
||||||
#else // MOZC_NO_LOGGING
|
|
||||||
EXPECT_EQ(g_counter, 3);
|
|
||||||
#endif // !MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
g_counter = 0;
|
|
||||||
LOG_IF(INFO, true) << "test: " << DebugString();
|
|
||||||
LOG_IF(ERROR, true) << "test: " << DebugString();
|
|
||||||
LOG_IF(WARNING, true) << "test: " << DebugString();
|
|
||||||
|
|
||||||
#ifdef MOZC_NO_LOGGING
|
|
||||||
EXPECT_EQ(g_counter, 0);
|
|
||||||
#else // MOZC_NO_LOGGING
|
|
||||||
EXPECT_EQ(g_counter, 3);
|
|
||||||
#endif // MOZC_NO_LOGGING
|
|
||||||
|
|
||||||
g_counter = 0;
|
|
||||||
LOG_IF(INFO, false) << "test: " << DebugString();
|
|
||||||
LOG_IF(ERROR, false) << "test: " << DebugString();
|
|
||||||
LOG_IF(WARNING, false) << "test: " << DebugString();
|
|
||||||
|
|
||||||
EXPECT_EQ(g_counter, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StubStringify {
|
|
||||||
template <typename Sink>
|
|
||||||
friend void AbslStringify(Sink &sink, const StubStringify &v) {
|
|
||||||
sink.Append(v.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string str;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(LoggingTest, AbslStringify) {
|
|
||||||
LOG(INFO) << "test: " << StubStringify{"testing info"};
|
|
||||||
LOG(ERROR) << "test: " << StubStringify{"testing error"};
|
|
||||||
LOG(WARNING) << "test: " << StubStringify{"testing warning"};
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(LoggingTest, WorkingLogStreamAsSink) {
|
|
||||||
WorkingLogStream stream;
|
|
||||||
stream.Append("hello");
|
|
||||||
stream.Append(5, 'o');
|
|
||||||
stream.Append(0, 'z');
|
|
||||||
absl::Format(&stream, ", world");
|
|
||||||
EXPECT_EQ(stream.str(), "helloooooo, world");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
} // namespace mozc
|
|
@ -35,8 +35,19 @@
|
|||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
#include "absl/flags/flag.h"
|
#include "absl/flags/flag.h"
|
||||||
|
|
||||||
|
// Note that abseil HEAD has ABSL_LTS_RELEASE_VERSION undefined.
|
||||||
|
#if !defined(ABSL_LTS_RELEASE_VERSION) || ABSL_LTS_RELEASE_VERSION >= 20240116
|
||||||
|
#include "absl/flags/declare.h"
|
||||||
|
#include "absl/log/flags.h" // IWYU pragma: keep
|
||||||
|
#endif // ABSL_LTS_RELEASE_VERSION >= 20240116
|
||||||
|
|
||||||
|
#if !defined(ABSL_LTS_RELEASE_VERSION) || ABSL_LTS_RELEASE_VERSION >= 20240116
|
||||||
|
// Newer version of abseil defines --v flag. We rely on it to avoid symbol
|
||||||
|
// name collision (though not recommended).
|
||||||
|
ABSL_DECLARE_FLAG(int, v);
|
||||||
|
#else // ABSL_LTS_RELEASE_VERSION >= 20240116
|
||||||
ABSL_FLAG(int, v, 0, "Show all VLOG(m) messages for m <= this.");
|
ABSL_FLAG(int, v, 0, "Show all VLOG(m) messages for m <= this.");
|
||||||
|
#endif // ABSL_LTS_RELEASE_VERSION < 20240116
|
||||||
|
|
||||||
namespace mozc::internal {
|
namespace mozc::internal {
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ The usage example is as follows.
|
|||||||
|
|
||||||
Sample Code:
|
Sample Code:
|
||||||
launcher = TestLauncher(gtest_report_dir='/tmp/my_gtest_report_dir')
|
launcher = TestLauncher(gtest_report_dir='/tmp/my_gtest_report_dir')
|
||||||
launcher.AddTest(['/path/to/binary/some_test', '--logtostderr' ])
|
launcher.AddTest(['/path/to/binary/some_test'])
|
||||||
launcher.AddTest(['/path/to/binary/another_test', '--logtostderr' ])
|
launcher.AddTest(['/path/to/binary/another_test'])
|
||||||
...
|
...
|
||||||
launcher.Execute(8) # Execute with specified number of processes.
|
launcher.Execute(8) # Execute with specified number of processes.
|
||||||
This function blocks main thread until all
|
This function blocks main thread until all
|
||||||
|
@ -234,7 +234,6 @@ void Client::DumpHistorySnapshot(const absl::string_view filename,
|
|||||||
OutputFileStream output(snapshot_file, std::ios::app);
|
OutputFileStream output(snapshot_file, std::ios::app);
|
||||||
|
|
||||||
output << "---- Start history snapshot for " << label << std::endl;
|
output << "---- Start history snapshot for " << label << std::endl;
|
||||||
output << "Created at " << Logging::GetLogMessageHeader() << std::endl;
|
|
||||||
output << "Version " << Version::GetMozcVersion() << std::endl;
|
output << "Version " << Version::GetMozcVersion() << std::endl;
|
||||||
for (size_t i = 0; i < history_inputs_.size(); ++i) {
|
for (size_t i = 0; i < history_inputs_.size(); ++i) {
|
||||||
output << absl::StrCat(history_inputs_[i]);
|
output << absl::StrCat(history_inputs_[i]);
|
||||||
|
@ -67,8 +67,6 @@ ABSL_FLAG(bool, test_testsendkey, true, "test TestSendKey");
|
|||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
mozc::InitMozc(argv[0], &argc, &argv);
|
mozc::InitMozc(argv[0], &argc, &argv);
|
||||||
|
|
||||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
|
||||||
|
|
||||||
mozc::client::Client client;
|
mozc::client::Client client;
|
||||||
if (!absl::GetFlag(FLAGS_server_path).empty()) {
|
if (!absl::GetFlag(FLAGS_server_path).empty()) {
|
||||||
client.set_server_program(absl::GetFlag(FLAGS_server_path));
|
client.set_server_program(absl::GetFlag(FLAGS_server_path));
|
||||||
|
@ -139,6 +139,7 @@
|
|||||||
'NDEBUG',
|
'NDEBUG',
|
||||||
'QT_NO_DEBUG',
|
'QT_NO_DEBUG',
|
||||||
'MOZC_NO_LOGGING',
|
'MOZC_NO_LOGGING',
|
||||||
|
'ABSL_MIN_LOG_LEVEL=100',
|
||||||
'IGNORE_HELP_FLAG',
|
'IGNORE_HELP_FLAG',
|
||||||
'IGNORE_INVALID_FLAG'
|
'IGNORE_INVALID_FLAG'
|
||||||
],
|
],
|
||||||
|
@ -248,6 +248,7 @@
|
|||||||
'NDEBUG',
|
'NDEBUG',
|
||||||
'QT_NO_DEBUG',
|
'QT_NO_DEBUG',
|
||||||
'MOZC_NO_LOGGING',
|
'MOZC_NO_LOGGING',
|
||||||
|
'ABSL_MIN_LOG_LEVEL=100',
|
||||||
'IGNORE_HELP_FLAG',
|
'IGNORE_HELP_FLAG',
|
||||||
'IGNORE_INVALID_FLAG'
|
'IGNORE_INVALID_FLAG'
|
||||||
],
|
],
|
||||||
|
@ -154,13 +154,6 @@ IosEngine::InputConfigTuple IosEngine::GetInputConfigTupleFromLayoutName(
|
|||||||
{Request::QWERTY_MOBILE_TO_HALFWIDTHASCII, commands::HALF_ASCII}};
|
{Request::QWERTY_MOBILE_TO_HALFWIDTHASCII, commands::HALF_ASCII}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void IosEngine::InitMozc() {
|
|
||||||
// Output logs to stderr so that they are displayed in XCode's console.
|
|
||||||
// This must be set before Logging::InitLogStream().
|
|
||||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
|
||||||
Logging::InitLogStream("MOZC_IOS_ENGINE");
|
|
||||||
}
|
|
||||||
|
|
||||||
IosEngine::IosEngine(const std::string &data_file_path)
|
IosEngine::IosEngine(const std::string &data_file_path)
|
||||||
: session_handler_(CreateSessionHandler(data_file_path)),
|
: session_handler_(CreateSessionHandler(data_file_path)),
|
||||||
session_id_(0),
|
session_id_(0),
|
||||||
|
@ -63,10 +63,6 @@ class IosEngine {
|
|||||||
|
|
||||||
~IosEngine();
|
~IosEngine();
|
||||||
|
|
||||||
// Initializes global modules. This function should be called before the
|
|
||||||
// initialization of IosEngine.
|
|
||||||
static void InitMozc();
|
|
||||||
|
|
||||||
// The following methods are helpers to populate command proto and send it
|
// The following methods are helpers to populate command proto and send it
|
||||||
// to the session handler. Input to and output from the session handler are
|
// to the session handler. Input to and output from the session handler are
|
||||||
// recorded in |command|. The return value is the return value of
|
// recorded in |command|. The return value is the return value of
|
||||||
|
@ -41,10 +41,6 @@ class SessionHandlerInterface {
|
|||||||
|
|
||||||
namespace ios {
|
namespace ios {
|
||||||
|
|
||||||
void IosEngine::InitMozc() {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
IosEngine::IosEngine(const std::string &data_file_path)
|
IosEngine::IosEngine(const std::string &data_file_path)
|
||||||
: session_handler_(new SessionHandlerInterface), session_id_(0) {}
|
: session_handler_(new SessionHandlerInterface), session_id_(0) {}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
// session_handler_main.cc
|
// session_handler_main.cc
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// session_handler_main --logtostderr --input input.txt --profile /tmp/mozc
|
// session_handler_main --input input.txt --profile /tmp/mozc
|
||||||
// --dictionary oss --engine desktop
|
// --dictionary oss --engine desktop
|
||||||
//
|
//
|
||||||
/* Example of input.txt (tsv format)
|
/* Example of input.txt (tsv format)
|
||||||
|
@ -440,7 +440,9 @@ class SessionTest : public testing::TestWithTempUserProfile {
|
|||||||
constexpr uint32_t kNoModifiers = 0;
|
constexpr uint32_t kNoModifiers = 0;
|
||||||
auto chars_it = chars.begin();
|
auto chars_it = chars.begin();
|
||||||
for (const absl::string_view key : Utf8AsChars(key_strings)) {
|
for (const absl::string_view key : Utf8AsChars(key_strings)) {
|
||||||
CHECK_NE(chars_it, chars.end());
|
// MSVC fails to compile if this is spelled as
|
||||||
|
// `CHECK_NE(chars_it, chars.end())`.
|
||||||
|
CHECK(chars_it != chars.end());
|
||||||
command->Clear();
|
command->Clear();
|
||||||
command->mutable_input()->set_type(commands::Input::SEND_KEY);
|
command->mutable_input()->set_type(commands::Input::SEND_KEY);
|
||||||
commands::KeyEvent *key_event = command->mutable_input()->mutable_key();
|
commands::KeyEvent *key_event = command->mutable_input()->mutable_key();
|
||||||
|
@ -280,7 +280,11 @@ mozc_cc_binary(
|
|||||||
"//unix:icons",
|
"//unix:icons",
|
||||||
],
|
],
|
||||||
defines = mozc_select(
|
defines = mozc_select(
|
||||||
linux = ["MOZC_NO_LOGGING"],
|
linux = [
|
||||||
|
# TODO(komatsu): Define MOZC_NO_LOGGING properly in bazel build.
|
||||||
|
"MOZC_NO_LOGGING",
|
||||||
|
"ABSL_MIN_LOG_LEVEL=100",
|
||||||
|
],
|
||||||
oss_linux = [],
|
oss_linux = [],
|
||||||
),
|
),
|
||||||
deps = [
|
deps = [
|
||||||
|
@ -140,6 +140,7 @@ mozc_cc_library(
|
|||||||
":tip_ui_handler",
|
":tip_ui_handler",
|
||||||
"//base:const",
|
"//base:const",
|
||||||
"//base:file_util",
|
"//base:file_util",
|
||||||
|
"//base:log_file",
|
||||||
"//base:logging",
|
"//base:logging",
|
||||||
"//base:process",
|
"//base:process",
|
||||||
"//base:system_util",
|
"//base:system_util",
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "absl/functional/any_invocable.h"
|
#include "absl/functional/any_invocable.h"
|
||||||
#include "base/const.h"
|
#include "base/const.h"
|
||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
|
#include "base/log_file.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/process.h"
|
#include "base/process.h"
|
||||||
#include "base/system_util.h"
|
#include "base/system_util.h"
|
||||||
@ -509,7 +510,7 @@ class TipTextServiceImpl
|
|||||||
StorePointerForCurrentThread(this);
|
StorePointerForCurrentThread(this);
|
||||||
|
|
||||||
HRESULT result = E_UNEXPECTED;
|
HRESULT result = E_UNEXPECTED;
|
||||||
Logging::InitLogStream(
|
RegisterLogFileSink(
|
||||||
FileUtil::JoinPath(SystemUtil::GetLoggingDirectory(), kLogFileName));
|
FileUtil::JoinPath(SystemUtil::GetLoggingDirectory(), kLogFileName));
|
||||||
|
|
||||||
EnsureKanaLockUnlocked();
|
EnsureKanaLockUnlocked();
|
||||||
|
Reference in New Issue
Block a user