@@ -122,6 +122,10 @@ GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
122122 "log messages go to stderr in addition to logfiles");
123123GLOG_DEFINE_bool (colorlogtostderr, false ,
124124 " color messages logged to stderr (if supported by terminal)" );
125+ GLOG_DEFINE_bool (colorlogtostdout, false ,
126+ " color messages logged to stdout (if supported by terminal)" );
127+ GLOG_DEFINE_bool (logtostdout, BoolFromEnv(" GOOGLE_LOGTOSTDOUT" , false ),
128+ "log messages go to stdout instead of logfiles");
125129#ifdef GLOG_OS_LINUX
126130GLOG_DEFINE_bool (drop_log_memory, true , " Drop in-memory buffers of log contents. "
127131 " Logs can grow very quickly and they are rarely read before they "
@@ -739,43 +743,63 @@ inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
739743 LogDestination::addresses_ = addresses;
740744}
741745
742- static void ColoredWriteToStderr (LogSeverity severity,
743- const char * message, size_t len) {
744- const GLogColor color =
745- (LogDestination::terminal_supports_color () && FLAGS_colorlogtostderr) ?
746- SeverityToColor (severity) : COLOR_DEFAULT;
746+ static void ColoredWriteToStderrOrStdout (FILE* output, LogSeverity severity,
747+ const char * message, size_t len) {
748+ bool is_stdout = (output == stdout);
749+ const GLogColor color = (LogDestination::terminal_supports_color () &&
750+ ((!is_stdout && FLAGS_colorlogtostderr) ||
751+ (is_stdout && FLAGS_colorlogtostdout)))
752+ ? SeverityToColor (severity)
753+ : COLOR_DEFAULT;
747754
748755 // Avoid using cerr from this module since we may get called during
749756 // exit code, and cerr may be partially or fully destroyed by then.
750757 if (COLOR_DEFAULT == color) {
751- fwrite (message, len, 1 , stderr );
758+ fwrite (message, len, 1 , output );
752759 return ;
753760 }
754761#ifdef GLOG_OS_WINDOWS
755- const HANDLE stderr_handle = GetStdHandle (STD_ERROR_HANDLE);
762+ const HANDLE output_handle =
763+ GetStdHandle (is_stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
756764
757765 // Gets the current text color.
758766 CONSOLE_SCREEN_BUFFER_INFO buffer_info;
759- GetConsoleScreenBufferInfo (stderr_handle , &buffer_info);
767+ GetConsoleScreenBufferInfo (output_handle , &buffer_info);
760768 const WORD old_color_attrs = buffer_info.wAttributes ;
761769
762770 // We need to flush the stream buffers into the console before each
763771 // SetConsoleTextAttribute call lest it affect the text that is already
764772 // printed but has not yet reached the console.
765- fflush (stderr );
766- SetConsoleTextAttribute (stderr_handle ,
773+ fflush (output );
774+ SetConsoleTextAttribute (output_handle ,
767775 GetColorAttribute (color) | FOREGROUND_INTENSITY);
768- fwrite (message, len, 1 , stderr );
769- fflush (stderr );
776+ fwrite (message, len, 1 , output );
777+ fflush (output );
770778 // Restores the text color.
771- SetConsoleTextAttribute (stderr_handle , old_color_attrs);
779+ SetConsoleTextAttribute (output_handle , old_color_attrs);
772780#else
773- fprintf (stderr , " \033 [0;3%sm" , GetAnsiColorCode (color));
774- fwrite (message, len, 1 , stderr );
775- fprintf (stderr , " \033 [m" ); // Resets the terminal to default.
781+ fprintf (output , " \033 [0;3%sm" , GetAnsiColorCode (color));
782+ fwrite (message, len, 1 , output );
783+ fprintf (output , " \033 [m" ); // Resets the terminal to default.
776784#endif // GLOG_OS_WINDOWS
777785}
778786
787+ static void ColoredWriteToStdout (LogSeverity severity, const char * message,
788+ size_t len) {
789+ FILE* output = stdout;
790+ // We also need to send logs to the stderr when the severity is
791+ // higher or equal to the stderr threshold.
792+ if (severity >= FLAGS_stderrthreshold) {
793+ output = stderr;
794+ }
795+ ColoredWriteToStderrOrStdout (output, severity, message, len);
796+ }
797+
798+ static void ColoredWriteToStderr (LogSeverity severity, const char * message,
799+ size_t len) {
800+ ColoredWriteToStderrOrStdout (stderr, severity, message, len);
801+ }
802+
779803static void WriteToStderr (const char * message, size_t len) {
780804 // Avoid using cerr from this module since we may get called during
781805 // exit code, and cerr may be partially or fully destroyed by then.
@@ -847,8 +871,9 @@ inline void LogDestination::LogToAllLogfiles(LogSeverity severity,
847871 time_t timestamp,
848872 const char * message,
849873 size_t len) {
850-
851- if ( FLAGS_logtostderr ) { // global flag: never log to file
874+ if (FLAGS_logtostdout) { // global flag: never log to file
875+ ColoredWriteToStdout (severity, message, len);
876+ } else if (FLAGS_logtostderr) { // global flag: never log to file
852877 ColoredWriteToStderr (severity, message, len);
853878 } else {
854879 for (int i = severity; i >= 0 ; --i) {
@@ -1812,9 +1837,14 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
18121837 // global flag: never log to file if set. Also -- don't log to a
18131838 // file if we haven't parsed the command line flags to get the
18141839 // program name.
1815- if (FLAGS_logtostderr || !IsGoogleLoggingInitialized ()) {
1816- ColoredWriteToStderr (data_->severity_ ,
1817- data_->message_text_ , data_->num_chars_to_log_ );
1840+ if (FLAGS_logtostderr || FLAGS_logtostdout || !IsGoogleLoggingInitialized ()) {
1841+ if (FLAGS_logtostdout) {
1842+ ColoredWriteToStdout (data_->severity_ , data_->message_text_ ,
1843+ data_->num_chars_to_log_ );
1844+ } else {
1845+ ColoredWriteToStderr (data_->severity_ , data_->message_text_ ,
1846+ data_->num_chars_to_log_ );
1847+ }
18181848
18191849 // this could be protected by a flag if necessary.
18201850 LogDestination::LogToSinks (data_->severity_ ,
@@ -1824,7 +1854,6 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
18241854 (data_->num_chars_to_log_ -
18251855 data_->num_prefix_chars_ - 1 ) );
18261856 } else {
1827-
18281857 // log this message to all log files of severity <= severity_
18291858 LogDestination::LogToAllLogfiles (data_->severity_ , logmsgtime_.timestamp (),
18301859 data_->message_text_ ,
@@ -1862,7 +1891,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
18621891 fatal_time = logmsgtime_.timestamp ();
18631892 }
18641893
1865- if (!FLAGS_logtostderr) {
1894+ if (!FLAGS_logtostderr && !FLAGS_logtostdout ) {
18661895 for (int i = 0 ; i < NUM_SEVERITIES; ++i) {
18671896 if (LogDestination::log_destinations_[i]) {
18681897 LogDestination::log_destinations_[i]->logger_ ->Write (true , 0 , " " , 0 );
0 commit comments