Skip to content

Commit

Permalink
Add the logtostdout and colorlogtostdout flag to allow logging to stdout
Browse files Browse the repository at this point in the history
Currently, glog allowed to use logtostderr to send error logs to stderr,
but many log tailers would regard logs from stderr as error logs. So we
want to send non-error logs to stdout and only send error logs to stderr
according to the stderrthreshold.
  • Loading branch information
git-hulk committed Feb 13, 2022
1 parent aa94e6b commit 0df1696
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 22 deletions.
6 changes: 6 additions & 0 deletions src/glog/logging.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,12 @@ typedef void(*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l, vo
// Set whether appending a timestamp to the log file name
DECLARE_bool(timestamp_in_logfile_name);

// Set whether log messages go to stdout instead of logfiles
DECLARE_bool(logtostdout);

// Set color messages logged to stdout (if supported by terminal).
DECLARE_bool(colorlogtostdout);

// Set whether log messages go to stderr instead of logfiles
DECLARE_bool(logtostderr);

Expand Down
25 changes: 22 additions & 3 deletions src/googletest.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ static inline void CaptureTestOutput(int fd, const string & filename) {
CHECK(s_captured_streams[fd] == NULL);
s_captured_streams[fd] = new CapturedStream(fd, filename);
}
static inline void CaptureTestStdout() {
CaptureTestOutput(STDOUT_FILENO, FLAGS_test_tmpdir + "/captured.out");
}
static inline void CaptureTestStderr() {
CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
}
Expand Down Expand Up @@ -504,9 +507,16 @@ static inline void WriteToFile(const string& body, const string& file) {
fclose(fp);
}

static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
CapturedStream* cap = s_captured_streams[STDERR_FILENO];
CHECK(cap) << ": did you forget CaptureTestStderr()?";
static inline bool MungeAndDiffTestStderrOrStdout(const string& golden_filename,
bool is_stdout) {
CapturedStream* cap;
if ( !is_stdout ) {
cap = s_captured_streams[STDERR_FILENO];
CHECK(cap) << ": did you forget CaptureTestStderr()?";
} else {
cap = s_captured_streams[STDOUT_FILENO];
CHECK(cap) << ": did you forget CaptureTestStdout()?";
}

cap->StopCapture();

Expand Down Expand Up @@ -536,6 +546,15 @@ static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
return true;
}


static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
return MungeAndDiffTestStderrOrStdout(golden_filename, false);
}

static inline bool MungeAndDiffTestStdout(const string& golden_filename) {
return MungeAndDiffTestStderrOrStdout(golden_filename, true);
}

// Save flags used from logging_unittest.cc.
#ifndef HAVE_LIB_GFLAGS
struct FlagSaver {
Expand Down
65 changes: 47 additions & 18 deletions src/logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
"log messages go to stderr in addition to logfiles");
GLOG_DEFINE_bool(colorlogtostderr, false,
"color messages logged to stderr (if supported by terminal)");
GLOG_DEFINE_bool(colorlogtostdout, false,
"color messages logged to stdout (if supported by terminal)");
GLOG_DEFINE_bool(logtostdout, BoolFromEnv("GOOGLE_LOGTOSTDOUT", false),
"log messages go to stdout instead of logfiles");
#ifdef GLOG_OS_LINUX
GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. "
"Logs can grow very quickly and they are rarely read before they "
Expand Down Expand Up @@ -739,43 +743,61 @@ inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
LogDestination::addresses_ = addresses;
}

static void ColoredWriteToStderr(LogSeverity severity,
static void ColoredWriteToStderrOrStdout(bool is_stdout, LogSeverity severity,
const char* message, size_t len) {
// We also need to send logs to the stderr when the severity is
// higher or equal to the stderr threshold.
is_stdout = is_stdout && severity < FLAGS_stderrthreshold;

const GLogColor color =
(LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ?
(LogDestination::terminal_supports_color()
&& ((!is_stdout && FLAGS_colorlogtostderr)
|| (is_stdout && FLAGS_colorlogtostdout))) ?
SeverityToColor(severity) : COLOR_DEFAULT;

FILE *output_fd = is_stdout ? stdout : stderr;
// Avoid using cerr from this module since we may get called during
// exit code, and cerr may be partially or fully destroyed by then.
if (COLOR_DEFAULT == color) {
fwrite(message, len, 1, stderr);
fwrite(message, len, 1, output_fd);
return;
}
#ifdef GLOG_OS_WINDOWS
const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
const HANDLE output_handle = GetStdHandle(is_stdout ?
STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);

// Gets the current text color.
CONSOLE_SCREEN_BUFFER_INFO buffer_info;
GetConsoleScreenBufferInfo(stderr_handle, &buffer_info);
GetConsoleScreenBufferInfo(output_handle, &buffer_info);
const WORD old_color_attrs = buffer_info.wAttributes;

// We need to flush the stream buffers into the console before each
// SetConsoleTextAttribute call lest it affect the text that is already
// printed but has not yet reached the console.
fflush(stderr);
SetConsoleTextAttribute(stderr_handle,
fflush(output_fd);
SetConsoleTextAttribute(output_handle,
GetColorAttribute(color) | FOREGROUND_INTENSITY);
fwrite(message, len, 1, stderr);
fflush(stderr);
fwrite(message, len, 1, output_fd);
fflush(output_fd);
// Restores the text color.
SetConsoleTextAttribute(stderr_handle, old_color_attrs);
SetConsoleTextAttribute(output_handle, old_color_attrs);
#else
fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color));
fwrite(message, len, 1, stderr);
fprintf(stderr, "\033[m"); // Resets the terminal to default.
fprintf(output_fd, "\033[0;3%sm", GetAnsiColorCode(color));
fwrite(message, len, 1, output_fd);
fprintf(output_fd, "\033[m"); // Resets the terminal to default.
#endif // GLOG_OS_WINDOWS
}

static void ColoredWriteToStdout(LogSeverity severity,
const char* message, size_t len) {
ColoredWriteToStderrOrStdout(true, severity, message, len);
}

static void ColoredWriteToStderr(LogSeverity severity,
const char* message, size_t len) {
ColoredWriteToStderrOrStdout(false, severity, message, len);
}

static void WriteToStderr(const char* message, size_t len) {
// Avoid using cerr from this module since we may get called during
// exit code, and cerr may be partially or fully destroyed by then.
Expand Down Expand Up @@ -848,7 +870,9 @@ inline void LogDestination::LogToAllLogfiles(LogSeverity severity,
const char* message,
size_t len) {

if ( FLAGS_logtostderr ) { // global flag: never log to file
if ( FLAGS_logtostdout ) { // global flag: never log to file
ColoredWriteToStdout(severity, message, len);
} else if ( FLAGS_logtostderr ) { // global flag: never log to file
ColoredWriteToStderr(severity, message, len);
} else {
for (int i = severity; i >= 0; --i) {
Expand Down Expand Up @@ -1812,9 +1836,14 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
// global flag: never log to file if set. Also -- don't log to a
// file if we haven't parsed the command line flags to get the
// program name.
if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) {
ColoredWriteToStderr(data_->severity_,
data_->message_text_, data_->num_chars_to_log_);
if (FLAGS_logtostderr || FLAGS_logtostdout || !IsGoogleLoggingInitialized()) {
if ( FLAGS_logtostdout ) {
ColoredWriteToStdout(data_->severity_, data_->message_text_,
data_->num_chars_to_log_);
} else {
ColoredWriteToStderr(data_->severity_, data_->message_text_,
data_->num_chars_to_log_);
}

// this could be protected by a flag if necessary.
LogDestination::LogToSinks(data_->severity_,
Expand Down Expand Up @@ -1862,7 +1891,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
fatal_time = logmsgtime_.timestamp();
}

if (!FLAGS_logtostderr) {
if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
for (int i = 0; i < NUM_SEVERITIES; ++i) {
if (LogDestination::log_destinations_[i]) {
LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0);
Expand Down
18 changes: 18 additions & 0 deletions src/logging_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@ int main(int argc, char **argv) {

FLAGS_logtostderr = false;

FLAGS_logtostdout = true;
FLAGS_stderrthreshold = NUM_SEVERITIES;
CaptureTestStdout();
TestRawLogging();
TestLoggingLevels();
TestLogString();
TestLogSink();
TestLogToString();
TestLogSinkWaitTillSent();
TestCHECK();
TestDCHECK();
TestSTREQ();
EXPECT_TRUE(
MungeAndDiffTestStdout(FLAGS_test_srcdir + "/src/logging_unittest.out"));
FLAGS_logtostdout = false;

TestBasename();
TestBasenameAppendWhenNoTimestamp();
TestTwoProcessesWrite();
Expand Down Expand Up @@ -1263,6 +1279,8 @@ class TestWaitingLogSink : public LogSink {
// Check that LogSink::WaitTillSent can be used in the advertised way.
// We also do golden-stderr comparison.
static void TestLogSinkWaitTillSent() {
// Clear global_messages here to make sure that this test case can be reentered
global_messages.clear();
{ TestWaitingLogSink sink;
// Sleeps give the sink threads time to do all their work,
// so that we get a reliable log capture to compare to the golden file.
Expand Down
150 changes: 150 additions & 0 deletions src/logging_unittest.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected info
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected warning
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK:
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
Loading

0 comments on commit 0df1696

Please sign in to comment.