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:
Tomoki Nakagawa
2024-02-24 16:19:34 +00:00
committed by Hiroyuki Komatsu
parent 78aee2ace9
commit c77285efa0
25 changed files with 200 additions and 1025 deletions

View File

@ -128,12 +128,11 @@ bazel test base:util_test --config oss_linux -c dbg
### 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
unitests to stderr.
* The `--test_arg=--stderrthreshold=0 --test_output=all` flags shows the
output of unitests to stderr.
## Build Mozc on other Linux environment

View File

@ -202,7 +202,6 @@ Java_com_google_android_apps_inputmethod_libs_mozc_session_MozcJNI_initialize(
return false;
}
mozc::Logging::InitLogStream(""); // Android doesn't stream log to a file.
return true;
}

View File

@ -53,6 +53,7 @@ mozc_cc_library(
copts = ["-DMOZC_BUILDTOOL_BUILD"],
visibility = ["//:__subpackages__"],
deps = [
":log_file",
":system_util",
"@com_google_absl//absl/flags:flag",
] + mozc_select(
@ -81,6 +82,7 @@ mozc_cc_library(
hdrs = ["init_mozc.h"],
visibility = ["//:__subpackages__"],
deps = [
":log_file",
"@com_google_absl//absl/flags:flag",
] + mozc_select(
android = ["//base"],
@ -128,49 +130,24 @@ mozc_cc_library(
mozc_cc_library(
name = "logging",
srcs = ["logging.cc"],
hdrs = ["logging.h"],
linkopts = mozc_select(
# Android requires linking logging library.
android = ["-llog"],
),
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",
deps = [
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:check",
],
)
mozc_cc_test(
name = "logging_test",
size = "small",
srcs = ["logging_test.cc"],
requires_full_emulation = False,
mozc_cc_library(
name = "log_file",
srcs = ["log_file.cc"],
hdrs = ["log_file.h"],
deps = [
":logging",
"//testing:gunit_main",
"@com_google_absl//absl/strings:str_format",
":file_stream",
"@com_google_absl//absl/base:core_headers",
"@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",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/log:flags",
],
)

View File

@ -102,7 +102,7 @@
'file_stream.cc',
'file_util.cc',
'init_mozc.cc',
'logging.cc',
'log_file.cc',
'mmap.cc',
'random.cc',
'strings/unicode.cc',
@ -118,6 +118,7 @@
'gen_character_set#host',
'hash',
'singleton',
'absl.gyp:absl_log',
'absl.gyp:absl_random',
'absl.gyp:absl_status',
'absl.gyp:absl_strings',

View File

@ -104,7 +104,6 @@
'type': 'executable',
'sources': [
'container/bitarray_test.cc',
'logging_test.cc',
'mmap_test.cc',
'random_test.h',
'singleton_test.cc',

View File

@ -39,7 +39,7 @@
#include "absl/flags/parse.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/log_file.h"
#ifndef MOZC_BUILDTOOL_BUILD
#include "base/system_util.h"
@ -52,6 +52,15 @@ ABSL_FLAG(std::string, log_dir, "",
"If specified, logfiles are written into this 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, "",
"Program name copied from argv[0].");
@ -107,7 +116,7 @@ void InitMozc(const char *arg0, int *argc, char ***argv) {
ParseCommandLineFlags(*argc, *argv);
const std::string program_name = *argc > 0 ? (*argv)[0] : "UNKNOWN";
Logging::InitLogStream(GetLogFilePathFromProgramName(program_name));
RegisterLogFileSink(GetLogFilePathFromProgramName(program_name));
}
} // namespace mozc

71
src/base/log_file.cc Normal file
View 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
View 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_

View File

@ -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

View File

@ -30,335 +30,37 @@
#ifndef 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
#include <iostream>
#include <sstream>
#include <type_traits>
#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
// Note that abseil HEAD has ABSL_LTS_RELEASE_VERSION undefined.
#if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20240116
// Older version of abseil doesn't ship with DFATAL. This is a very hacky
// backport that needs to be removed as soon as we migrate to Abseil LTS
// 20240116.
#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
#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 // 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())
#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_

View File

@ -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

View File

@ -35,8 +35,19 @@
#include "absl/base/attributes.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.");
#endif // ABSL_LTS_RELEASE_VERSION < 20240116
namespace mozc::internal {

View File

@ -36,8 +36,8 @@ The usage example is as follows.
Sample Code:
launcher = TestLauncher(gtest_report_dir='/tmp/my_gtest_report_dir')
launcher.AddTest(['/path/to/binary/some_test', '--logtostderr' ])
launcher.AddTest(['/path/to/binary/another_test', '--logtostderr' ])
launcher.AddTest(['/path/to/binary/some_test'])
launcher.AddTest(['/path/to/binary/another_test'])
...
launcher.Execute(8) # Execute with specified number of processes.
This function blocks main thread until all

View File

@ -234,7 +234,6 @@ void Client::DumpHistorySnapshot(const absl::string_view filename,
OutputFileStream output(snapshot_file, std::ios::app);
output << "---- Start history snapshot for " << label << std::endl;
output << "Created at " << Logging::GetLogMessageHeader() << std::endl;
output << "Version " << Version::GetMozcVersion() << std::endl;
for (size_t i = 0; i < history_inputs_.size(); ++i) {
output << absl::StrCat(history_inputs_[i]);

View File

@ -67,8 +67,6 @@ ABSL_FLAG(bool, test_testsendkey, true, "test TestSendKey");
int main(int argc, char **argv) {
mozc::InitMozc(argv[0], &argc, &argv);
absl::SetFlag(&FLAGS_logtostderr, true);
mozc::client::Client client;
if (!absl::GetFlag(FLAGS_server_path).empty()) {
client.set_server_program(absl::GetFlag(FLAGS_server_path));

View File

@ -139,6 +139,7 @@
'NDEBUG',
'QT_NO_DEBUG',
'MOZC_NO_LOGGING',
'ABSL_MIN_LOG_LEVEL=100',
'IGNORE_HELP_FLAG',
'IGNORE_INVALID_FLAG'
],

View File

@ -248,6 +248,7 @@
'NDEBUG',
'QT_NO_DEBUG',
'MOZC_NO_LOGGING',
'ABSL_MIN_LOG_LEVEL=100',
'IGNORE_HELP_FLAG',
'IGNORE_INVALID_FLAG'
],

View File

@ -154,13 +154,6 @@ IosEngine::InputConfigTuple IosEngine::GetInputConfigTupleFromLayoutName(
{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)
: session_handler_(CreateSessionHandler(data_file_path)),
session_id_(0),

View File

@ -63,10 +63,6 @@ class 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
// to the session handler. Input to and output from the session handler are
// recorded in |command|. The return value is the return value of

View File

@ -41,10 +41,6 @@ class SessionHandlerInterface {
namespace ios {
void IosEngine::InitMozc() {
// Do nothing.
}
IosEngine::IosEngine(const std::string &data_file_path)
: session_handler_(new SessionHandlerInterface), session_id_(0) {}

View File

@ -30,7 +30,7 @@
// session_handler_main.cc
//
// Usage:
// session_handler_main --logtostderr --input input.txt --profile /tmp/mozc
// session_handler_main --input input.txt --profile /tmp/mozc
// --dictionary oss --engine desktop
//
/* Example of input.txt (tsv format)

View File

@ -440,7 +440,9 @@ class SessionTest : public testing::TestWithTempUserProfile {
constexpr uint32_t kNoModifiers = 0;
auto chars_it = chars.begin();
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->mutable_input()->set_type(commands::Input::SEND_KEY);
commands::KeyEvent *key_event = command->mutable_input()->mutable_key();

View File

@ -280,7 +280,11 @@ mozc_cc_binary(
"//unix:icons",
],
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 = [],
),
deps = [

View File

@ -140,6 +140,7 @@ mozc_cc_library(
":tip_ui_handler",
"//base:const",
"//base:file_util",
"//base:log_file",
"//base:logging",
"//base:process",
"//base:system_util",

View File

@ -47,6 +47,7 @@
#include "absl/functional/any_invocable.h"
#include "base/const.h"
#include "base/file_util.h"
#include "base/log_file.h"
#include "base/logging.h"
#include "base/process.h"
#include "base/system_util.h"
@ -509,7 +510,7 @@ class TipTextServiceImpl
StorePointerForCurrentThread(this);
HRESULT result = E_UNEXPECTED;
Logging::InitLogStream(
RegisterLogFileSink(
FileUtil::JoinPath(SystemUtil::GetLoggingDirectory(), kLogFileName));
EnsureKanaLockUnlocked();