logging.cc
Go to the documentation of this file.
1 // Copyright (c) 1999, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite()
31 
32 #include "utilities.h"
33 
34 #include <algorithm>
35 #include <cassert>
36 #include <iomanip>
37 #include <string>
38 #ifdef HAVE_UNISTD_H
39 # include <unistd.h> // For _exit.
40 #endif
41 #include <climits>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #ifdef HAVE_SYS_UTSNAME_H
45 # include <sys/utsname.h> // For uname.
46 #endif
47 #include <ctime>
48 #include <fcntl.h>
49 #include <cstdio>
50 #include <iostream>
51 #include <cstdarg>
52 #include <cstdlib>
53 #ifdef HAVE_PWD_H
54 # include <pwd.h>
55 #endif
56 #ifdef HAVE_SYSLOG_H
57 # include <syslog.h>
58 #endif
59 #include <vector>
60 #include <cerrno> // for errno
61 #include <sstream>
62 #ifdef GLOG_OS_WINDOWS
63 #include "windows/dirent.h"
64 #else
65 #include <dirent.h> // for automatic removal of old logs
66 #endif
67 #include "base/commandlineflags.h" // to get the program name
68 #include <glog/logging.h>
69 #include <glog/raw_logging.h>
70 #include "base/googleinit.h"
71 
72 #ifdef HAVE_STACKTRACE
73 # include "stacktrace.h"
74 #endif
75 
76 #ifdef __ANDROID__
77 #include <android/log.h>
78 #endif
79 
80 using std::string;
81 using std::vector;
82 using std::setw;
83 using std::setfill;
84 using std::hex;
85 using std::dec;
86 using std::min;
87 using std::ostream;
88 using std::ostringstream;
89 
90 using std::FILE;
91 using std::fwrite;
92 using std::fclose;
93 using std::fflush;
94 using std::fprintf;
95 using std::perror;
96 
97 #ifdef __QNX__
98 using std::fdopen;
99 #endif
100 
101 #ifdef _WIN32
102 #define fdopen _fdopen
103 #endif
104 
105 // There is no thread annotation support.
106 #define EXCLUSIVE_LOCKS_REQUIRED(mu)
107 
108 static bool BoolFromEnv(const char *varname, bool defval) {
109  const char* const valstr = getenv(varname);
110  if (!valstr) {
111  return defval;
112  }
113  return memchr("tTyY1\0", valstr[0], 6) != NULL;
114 }
115 
116 GLOG_DEFINE_bool(timestamp_in_logfile_name,
117  BoolFromEnv("GOOGLE_TIMESTAMP_IN_LOGFILE_NAME", true),
118  "put a timestamp at the end of the log file name");
119 GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false),
120  "log messages go to stderr instead of logfiles");
121 GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
122  "log messages go to stderr in addition to logfiles");
123 GLOG_DEFINE_bool(colorlogtostderr, false,
124  "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");
129 #ifdef GLOG_OS_LINUX
130 GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. "
131  "Logs can grow very quickly and they are rarely read before they "
132  "need to be evicted from memory. Instead, drop them from memory "
133  "as soon as they are flushed to disk.");
134 #endif
135 
136 // By default, errors (including fatal errors) get logged to stderr as
137 // well as the file.
138 //
139 // The default is ERROR instead of FATAL so that users can see problems
140 // when they run a program without having to look in another file.
141 DEFINE_int32(stderrthreshold,
143  "log messages at or above this level are copied to stderr in "
144  "addition to logfiles. This flag obsoletes --alsologtostderr.");
145 
146 GLOG_DEFINE_string(alsologtoemail, "",
147  "log messages go to these email addresses "
148  "in addition to logfiles");
149 GLOG_DEFINE_bool(log_prefix, true,
150  "Prepend the log prefix to the start of each log line");
151 GLOG_DEFINE_bool(log_year_in_prefix, true,
152  "Include the year in the log prefix");
153 GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't "
154  "actually get logged anywhere");
155 GLOG_DEFINE_int32(logbuflevel, 0,
156  "Buffer log messages logged at this level or lower"
157  " (-1 means don't buffer; 0 means buffer INFO only;"
158  " ...)");
159 GLOG_DEFINE_int32(logbufsecs, 30,
160  "Buffer log messages for at most this many seconds");
161 
162 GLOG_DEFINE_int32(logcleansecs, 60 * 5, // every 5 minutes
163  "Clean overdue logs every this many seconds");
164 
165 GLOG_DEFINE_int32(logemaillevel, 999,
166  "Email log messages logged at this level or higher"
167  " (0 means email all; 3 means email FATAL only;"
168  " ...)");
169 GLOG_DEFINE_string(logmailer, "",
170  "Mailer used to send logging email");
171 
172 // Compute the default value for --log_dir
173 static const char* DefaultLogDir() {
174  const char* env;
175  env = getenv("GOOGLE_LOG_DIR");
176  if (env != NULL && env[0] != '\0') {
177  return env;
178  }
179  env = getenv("TEST_TMPDIR");
180  if (env != NULL && env[0] != '\0') {
181  return env;
182  }
183  return "";
184 }
185 
186 GLOG_DEFINE_int32(logfile_mode, 0664, "Log file mode/permissions.");
187 
189  "If specified, logfiles are written into this directory instead "
190  "of the default logging directory.");
191 GLOG_DEFINE_string(log_link, "", "Put additional links to the log "
192  "files in this directory");
193 
194 GLOG_DEFINE_uint32(max_log_size, 1800,
195  "approx. maximum log file size (in MB). A value of 0 will "
196  "be silently overridden to 1.");
197 
198 GLOG_DEFINE_bool(stop_logging_if_full_disk, false,
199  "Stop attempting to log to disk if the disk is full.");
200 
201 GLOG_DEFINE_string(log_backtrace_at, "",
202  "Emit a backtrace when logging at file:linenum.");
203 
204 GLOG_DEFINE_bool(log_utc_time, false,
205  "Use UTC time for logging.");
206 
207 // TODO(hamaji): consider windows
208 #define PATH_SEPARATOR '/'
209 
210 #ifndef HAVE_PREAD
211 #if defined(GLOG_OS_WINDOWS)
212 #include <basetsd.h>
213 #define ssize_t SSIZE_T
214 #endif
215 static ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
216  off_t orig_offset = lseek(fd, 0, SEEK_CUR);
217  if (orig_offset == (off_t)-1)
218  return -1;
219  if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
220  return -1;
221  ssize_t len = read(fd, buf, count);
222  if (len < 0)
223  return len;
224  if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
225  return -1;
226  return len;
227 }
228 #endif // !HAVE_PREAD
229 
230 #ifndef HAVE_PWRITE
231 static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) {
232  off_t orig_offset = lseek(fd, 0, SEEK_CUR);
233  if (orig_offset == (off_t)-1)
234  return -1;
235  if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
236  return -1;
237  ssize_t len = write(fd, buf, count);
238  if (len < 0)
239  return len;
240  if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
241  return -1;
242  return len;
243 }
244 #endif // !HAVE_PWRITE
245 
246 static void GetHostName(string* hostname) {
247 #if defined(HAVE_SYS_UTSNAME_H)
248  struct utsname buf;
249  if (uname(&buf) < 0) {
250  // ensure null termination on failure
251  *buf.nodename = '\0';
252  }
253  *hostname = buf.nodename;
254 #elif defined(GLOG_OS_WINDOWS)
255  char buf[MAX_COMPUTERNAME_LENGTH + 1];
256  DWORD len = MAX_COMPUTERNAME_LENGTH + 1;
257  if (GetComputerNameA(buf, &len)) {
258  *hostname = buf;
259  } else {
260  hostname->clear();
261  }
262 #else
263 # warning There is no way to retrieve the host name.
264  *hostname = "(unknown)";
265 #endif
266 }
267 
268 // Returns true iff terminal supports using colors in output.
269 static bool TerminalSupportsColor() {
270  bool term_supports_color = false;
271 #ifdef GLOG_OS_WINDOWS
272  // on Windows TERM variable is usually not set, but the console does
273  // support colors.
274  term_supports_color = true;
275 #else
276  // On non-Windows platforms, we rely on the TERM variable.
277  const char* const term = getenv("TERM");
278  if (term != NULL && term[0] != '\0') {
279  term_supports_color =
280  !strcmp(term, "xterm") ||
281  !strcmp(term, "xterm-color") ||
282  !strcmp(term, "xterm-256color") ||
283  !strcmp(term, "screen-256color") ||
284  !strcmp(term, "konsole") ||
285  !strcmp(term, "konsole-16color") ||
286  !strcmp(term, "konsole-256color") ||
287  !strcmp(term, "screen") ||
288  !strcmp(term, "linux") ||
289  !strcmp(term, "cygwin");
290  }
291 #endif
292  return term_supports_color;
293 }
294 
296 
297 enum GLogColor {
302 };
303 
305  assert(severity >= 0 && severity < NUM_SEVERITIES);
307  switch (severity) {
308  case GLOG_INFO:
310  break;
311  case GLOG_WARNING:
313  break;
314  case GLOG_ERROR:
315  case GLOG_FATAL:
316  color = COLOR_RED;
317  break;
318  default:
319  // should never get here.
320  assert(false);
321  }
322  return color;
323 }
324 
325 #ifdef GLOG_OS_WINDOWS
326 
327 // Returns the character attribute for the given color.
328 static WORD GetColorAttribute(GLogColor color) {
329  switch (color) {
330  case COLOR_RED: return FOREGROUND_RED;
331  case COLOR_GREEN: return FOREGROUND_GREEN;
332  case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
333  default: return 0;
334  }
335 }
336 
337 #else
338 
339 // Returns the ANSI color code for the given color.
340 static const char* GetAnsiColorCode(GLogColor color) {
341  switch (color) {
342  case COLOR_RED: return "1";
343  case COLOR_GREEN: return "2";
344  case COLOR_YELLOW: return "3";
345  case COLOR_DEFAULT: return "";
346  };
347  return NULL; // stop warning about return type.
348 }
349 
350 #endif // GLOG_OS_WINDOWS
351 
352 // Safely get max_log_size, overriding to 1 if it somehow gets defined as 0
353 static uint32 MaxLogSize() {
354  return (FLAGS_max_log_size > 0 && FLAGS_max_log_size < 4096
355  ? FLAGS_max_log_size
356  : 1);
357 }
358 
359 // An arbitrary limit on the length of a single log message. This
360 // is so that streaming can be done more efficiently.
361 const size_t LogMessage::kMaxLogMessageLen = 30000;
362 
364  LogMessageData();
365 
366  int preserved_errno_; // preserved errno
367  // Buffer space; contains complete message text.
368  char message_text_[LogMessage::kMaxLogMessageLen+1];
369  LogStream stream_;
370  char severity_; // What level is this LogMessage logged at?
371  int line_; // line number where logging call is.
372  void (LogMessage::*send_method_)(); // Call this in destructor to send
373  union { // At most one of these is used: union to keep the size low.
374  LogSink* sink_; // NULL or sink to send message to
375  std::vector<std::string>* outvec_; // NULL or vector to push message onto
376  std::string* message_; // NULL or string to write message into
377  };
378  size_t num_prefix_chars_; // # of chars of prefix in this message
379  size_t num_chars_to_log_; // # of chars of msg to send to log
380  size_t num_chars_to_syslog_; // # of chars of msg to send to syslog
381  const char* basename_; // basename of file that called LOG
382  const char* fullname_; // fullname of file that called LOG
383  bool has_been_flushed_; // false => data has not been flushed
384  bool first_fatal_; // true => this was first fatal msg
385 
386  private:
388  void operator=(const LogMessageData&);
389 };
390 
391 // A mutex that allows only one thread to log at a time, to keep things from
392 // getting jumbled. Some other very uncommon logging operations (like
393 // changing the destination file for log messages of a given severity) also
394 // lock this mutex. Please be sure that anybody who might possibly need to
395 // lock it does so.
397 
398 // Number of messages sent at each severity. Under log_mutex.
399 int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0};
400 
401 // Globally disable log writing (if disk is full)
402 static bool stop_writing = false;
403 
404 const char*const LogSeverityNames[NUM_SEVERITIES] = {
405  "INFO", "WARNING", "ERROR", "FATAL"
406 };
407 
408 // Has the user called SetExitOnDFatal(true)?
409 static bool exit_on_dfatal = true;
410 
412  return LogSeverityNames[severity];
413 }
414 
415 static bool SendEmailInternal(const char*dest, const char *subject,
416  const char*body, bool use_logging);
417 
418 base::Logger::~Logger() {
419 }
420 
421 #ifdef GLOG_CUSTOM_PREFIX_SUPPORT
422 namespace {
423  // Optional user-configured callback to print custom prefixes.
424  CustomPrefixCallback custom_prefix_callback = NULL;
425  // User-provided data to pass to the callback:
426  void* custom_prefix_callback_data = NULL;
427 }
428 #endif
429 
430 namespace {
431 
432 // Encapsulates all file-system related state
433 class LogFileObject : public base::Logger {
434  public:
435  LogFileObject(LogSeverity severity, const char* base_filename);
436  ~LogFileObject();
437 
438  virtual void Write(bool force_flush, // Should we force a flush here?
439  time_t timestamp, // Timestamp for this entry
440  const char* message,
441  size_t message_len);
442 
443  // Configuration options
444  void SetBasename(const char* basename);
445  void SetExtension(const char* ext);
446  void SetSymlinkBasename(const char* symlink_basename);
447 
448  // Normal flushing routine
449  virtual void Flush();
450 
451  // It is the actual file length for the system loggers,
452  // i.e., INFO, ERROR, etc.
453  virtual uint32 LogSize() {
454  MutexLock l(&lock_);
455  return file_length_;
456  }
457 
458  // Internal flush routine. Exposed so that FlushLogFilesUnsafe()
459  // can avoid grabbing a lock. Usually Flush() calls it after
460  // acquiring lock_.
461  void FlushUnlocked();
462 
463  private:
464  static const uint32 kRolloverAttemptFrequency = 0x20;
465 
466  Mutex lock_;
467  bool base_filename_selected_;
468  string base_filename_;
469  string symlink_basename_;
470  string filename_extension_; // option users can specify (eg to add port#)
471  FILE* file_;
472  LogSeverity severity_;
473  uint32 bytes_since_flush_;
474  uint32 dropped_mem_length_;
475  uint32 file_length_;
476  unsigned int rollover_attempt_;
477  int64 next_flush_time_; // cycle count at which to flush log
478  WallTime start_time_;
479 
480  // Actually create a logfile using the value of base_filename_ and the
481  // optional argument time_pid_string
482  // REQUIRES: lock_ is held
483  bool CreateLogfile(const string& time_pid_string);
484 };
485 
486 // Encapsulate all log cleaner related states
487 class LogCleaner {
488  public:
489  LogCleaner();
490 
491  // Setting overdue_days to 0 days will delete all logs.
492  void Enable(unsigned int overdue_days);
493  void Disable();
494 
495  // update next_cleanup_time_
496  void UpdateCleanUpTime();
497 
498  void Run(bool base_filename_selected,
499  const string& base_filename,
500  const string& filename_extension);
501 
502  bool enabled() const { return enabled_; }
503 
504  private:
505  vector<string> GetOverdueLogNames(string log_directory, unsigned int days,
506  const string& base_filename,
507  const string& filename_extension) const;
508 
509  bool IsLogFromCurrentProject(const string& filepath,
510  const string& base_filename,
511  const string& filename_extension) const;
512 
513  bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const;
514 
515  bool enabled_;
516  unsigned int overdue_days_;
517  int64 next_cleanup_time_; // cycle count at which to clean overdue log
518 };
519 
520 LogCleaner log_cleaner;
521 
522 } // namespace
523 
525  public:
526  friend class LogMessage;
527  friend void ReprintFatalMessage();
528  friend base::Logger* base::GetLogger(LogSeverity);
529  friend void base::SetLogger(LogSeverity, base::Logger*);
530 
531  // These methods are just forwarded to by their global versions.
533  const char* base_filename);
534  static void SetLogSymlink(LogSeverity severity,
535  const char* symlink_basename);
536  static void AddLogSink(LogSink *destination);
537  static void RemoveLogSink(LogSink *destination);
538  static void SetLogFilenameExtension(const char* filename_extension);
539  static void SetStderrLogging(LogSeverity min_severity);
540  static void SetEmailLogging(LogSeverity min_severity, const char* addresses);
541  static void LogToStderr();
542  // Flush all log files that are at least at the given severity level
543  static void FlushLogFiles(int min_severity);
544  static void FlushLogFilesUnsafe(int min_severity);
545 
546  // we set the maximum size of our packet to be 1400, the logic being
547  // to prevent fragmentation.
548  // Really this number is arbitrary.
549  static const int kNetworkBytes = 1400;
550 
551  static const string& hostname();
552  static const bool& terminal_supports_color() {
554  }
555 
556  static void DeleteLogDestinations();
557 
558  private:
559  LogDestination(LogSeverity severity, const char* base_filename);
560  ~LogDestination();
561 
562  // Take a log message of a particular severity and log it to stderr
563  // iff it's of a high enough severity to deserve it.
564  static void MaybeLogToStderr(LogSeverity severity, const char* message,
565  size_t message_len, size_t prefix_len);
566 
567  // Take a log message of a particular severity and log it to email
568  // iff it's of a high enough severity to deserve it.
569  static void MaybeLogToEmail(LogSeverity severity, const char* message,
570  size_t len);
571  // Take a log message of a particular severity and log it to a file
572  // iff the base filename is not "" (which means "don't log to me")
574  time_t timestamp,
575  const char* message, size_t len);
576  // Take a log message of a particular severity and log it to the file
577  // for that severity and also for all files with severity less than
578  // this severity.
580  time_t timestamp,
581  const char* message, size_t len);
582 
583  // Send logging info to all registered sinks.
584  static void LogToSinks(LogSeverity severity, const char* full_filename,
585  const char* base_filename, int line,
586  const LogMessageTime& logmsgtime, const char* message,
587  size_t message_len);
588 
589  // Wait for all registered sinks via WaitTillSent
590  // including the optional one in "data".
592 
594 
595  LogFileObject fileobject_;
596  base::Logger* logger_; // Either &fileobject_, or wrapper around it
597 
600  static string addresses_;
601  static string hostname_;
603 
604  // arbitrary global logging destinations.
605  static vector<LogSink*>* sinks_;
606 
607  // Protects the vector sinks_,
608  // but not the LogSink objects its elements reference.
610 
611  // Disallow
614 };
615 
616 // Errors do not get logged to email by default.
618 
621 
622 vector<LogSink*>* LogDestination::sinks_ = NULL;
625 
626 /* static */
627 const string& LogDestination::hostname() {
628  if (hostname_.empty()) {
630  if (hostname_.empty()) {
631  hostname_ = "(unknown)";
632  }
633  }
634  return hostname_;
635 }
636 
638  const char* base_filename)
639  : fileobject_(severity, base_filename),
640  logger_(&fileobject_) {
641 }
642 
644  if (logger_ && logger_ != &fileobject_) {
645  // Delete user-specified logger set via SetLogger().
646  delete logger_;
647  }
648 }
649 
650 inline void LogDestination::FlushLogFilesUnsafe(int min_severity) {
651  // assume we have the log_mutex or we simply don't care
652  // about it
653  for (int i = min_severity; i < NUM_SEVERITIES; i++) {
655  if (log != NULL) {
656  // Flush the base fileobject_ logger directly instead of going
657  // through any wrappers to reduce chance of deadlock.
658  log->fileobject_.FlushUnlocked();
659  }
660  }
661 }
662 
663 inline void LogDestination::FlushLogFiles(int min_severity) {
664  // Prevent any subtle race conditions by wrapping a mutex lock around
665  // all this stuff.
666  MutexLock l(&log_mutex);
667  for (int i = min_severity; i < NUM_SEVERITIES; i++) {
669  if (log != NULL) {
670  log->logger_->Flush();
671  }
672  }
673 }
674 
676  const char* base_filename) {
677  assert(severity >= 0 && severity < NUM_SEVERITIES);
678  // Prevent any subtle race conditions by wrapping a mutex lock around
679  // all this stuff.
680  MutexLock l(&log_mutex);
681  log_destination(severity)->fileobject_.SetBasename(base_filename);
682 }
683 
685  const char* symlink_basename) {
686  CHECK_GE(severity, 0);
688  MutexLock l(&log_mutex);
689  log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename);
690 }
691 
692 inline void LogDestination::AddLogSink(LogSink *destination) {
693  // Prevent any subtle race conditions by wrapping a mutex lock around
694  // all this stuff.
696  if (!sinks_) sinks_ = new vector<LogSink*>;
697  sinks_->push_back(destination);
698 }
699 
700 inline void LogDestination::RemoveLogSink(LogSink *destination) {
701  // Prevent any subtle race conditions by wrapping a mutex lock around
702  // all this stuff.
704  // This doesn't keep the sinks in order, but who cares?
705  if (sinks_) {
706  sinks_->erase(std::remove(sinks_->begin(), sinks_->end(), destination), sinks_->end());
707  }
708 }
709 
710 inline void LogDestination::SetLogFilenameExtension(const char* ext) {
711  // Prevent any subtle race conditions by wrapping a mutex lock around
712  // all this stuff.
713  MutexLock l(&log_mutex);
714  for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) {
715  log_destination(severity)->fileobject_.SetExtension(ext);
716  }
717 }
718 
720  assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
721  // Prevent any subtle race conditions by wrapping a mutex lock around
722  // all this stuff.
723  MutexLock l(&log_mutex);
724  FLAGS_stderrthreshold = min_severity;
725 }
726 
728  // *Don't* put this stuff in a mutex lock, since SetStderrLogging &
729  // SetLogDestination already do the locking!
730  SetStderrLogging(0); // thus everything is "also" logged to stderr
731  for ( int i = 0; i < NUM_SEVERITIES; ++i ) {
732  SetLogDestination(i, ""); // "" turns off logging to a logfile
733  }
734 }
735 
737  const char* addresses) {
738  assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
739  // Prevent any subtle race conditions by wrapping a mutex lock around
740  // all this stuff.
741  MutexLock l(&log_mutex);
743  LogDestination::addresses_ = addresses;
744 }
745 
747  const char* message, size_t len) {
748  bool is_stdout = (output == stdout);
750  ((!is_stdout && FLAGS_colorlogtostderr) ||
751  (is_stdout && FLAGS_colorlogtostdout)))
753  : COLOR_DEFAULT;
754 
755  // Avoid using cerr from this module since we may get called during
756  // exit code, and cerr may be partially or fully destroyed by then.
757  if (COLOR_DEFAULT == color) {
758  fwrite(message, len, 1, output);
759  return;
760  }
761 #ifdef GLOG_OS_WINDOWS
762  const HANDLE output_handle =
763  GetStdHandle(is_stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
764 
765  // Gets the current text color.
766  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
767  GetConsoleScreenBufferInfo(output_handle, &buffer_info);
768  const WORD old_color_attrs = buffer_info.wAttributes;
769 
770  // We need to flush the stream buffers into the console before each
771  // SetConsoleTextAttribute call lest it affect the text that is already
772  // printed but has not yet reached the console.
773  fflush(output);
774  SetConsoleTextAttribute(output_handle,
775  GetColorAttribute(color) | FOREGROUND_INTENSITY);
776  fwrite(message, len, 1, output);
777  fflush(output);
778  // Restores the text color.
779  SetConsoleTextAttribute(output_handle, old_color_attrs);
780 #else
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.
784 #endif // GLOG_OS_WINDOWS
785 }
786 
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  }
796 }
797 
799  size_t len) {
801 }
802 
803 static void WriteToStderr(const char* message, size_t len) {
804  // Avoid using cerr from this module since we may get called during
805  // exit code, and cerr may be partially or fully destroyed by then.
806  fwrite(message, len, 1, stderr);
807 }
808 
810  const char* message, size_t message_len, size_t prefix_len) {
811  if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) {
812  ColoredWriteToStderr(severity, message, message_len);
813 #ifdef GLOG_OS_WINDOWS
814  (void) prefix_len;
815  // On Windows, also output to the debugger
816  ::OutputDebugStringA(message);
817 #elif defined(__ANDROID__)
818  // On Android, also output to logcat
819  const int android_log_levels[NUM_SEVERITIES] = {
820  ANDROID_LOG_INFO,
821  ANDROID_LOG_WARN,
822  ANDROID_LOG_ERROR,
823  ANDROID_LOG_FATAL,
824  };
825  __android_log_write(android_log_levels[severity],
827  message + prefix_len);
828 #else
829  (void) prefix_len;
830 #endif
831  }
832 }
833 
834 
836  const char* message, size_t len) {
838  severity >= FLAGS_logemaillevel) {
839  string to(FLAGS_alsologtoemail);
840  if (!addresses_.empty()) {
841  if (!to.empty()) {
842  to += ",";
843  }
844  to += addresses_;
845  }
846  const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " +
848  string body(hostname());
849  body += "\n\n";
850  body.append(message, len);
851 
852  // should NOT use SendEmail(). The caller of this function holds the
853  // log_mutex and SendEmail() calls LOG/VLOG which will block trying to
854  // acquire the log_mutex object. Use SendEmailInternal() and set
855  // use_logging to false.
856  SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false);
857  }
858 }
859 
860 
862  time_t timestamp,
863  const char* message,
864  size_t len) {
865  const bool should_flush = severity > FLAGS_logbuflevel;
866  LogDestination* destination = log_destination(severity);
867  destination->logger_->Write(should_flush, timestamp, message, len);
868 }
869 
871  time_t timestamp,
872  const char* message,
873  size_t len) {
874  if (FLAGS_logtostdout) { // global flag: never log to file
876  } else if (FLAGS_logtostderr) { // global flag: never log to file
878  } else {
879  for (int i = severity; i >= 0; --i) {
881  }
882  }
883 }
884 
886  const char* full_filename,
887  const char* base_filename, int line,
888  const LogMessageTime& logmsgtime,
889  const char* message,
890  size_t message_len) {
892  if (sinks_) {
893  for (size_t i = sinks_->size(); i-- > 0; ) {
894  (*sinks_)[i]->send(severity, full_filename, base_filename,
895  line, logmsgtime, message, message_len);
896  }
897  }
898 }
899 
902  if (sinks_) {
903  for (size_t i = sinks_->size(); i-- > 0; ) {
904  (*sinks_)[i]->WaitTillSent();
905  }
906  }
907  const bool send_to_sink =
908  (data->send_method_ == &LogMessage::SendToSink) ||
909  (data->send_method_ == &LogMessage::SendToSinkAndLog);
910  if (send_to_sink && data->sink_ != NULL) {
911  data->sink_->WaitTillSent();
912  }
913 }
914 
916 
918  assert(severity >=0 && severity < NUM_SEVERITIES);
919  if (!log_destinations_[severity]) {
921  }
922  return log_destinations_[severity];
923 }
924 
926  for (int severity = 0; severity < NUM_SEVERITIES; ++severity) {
927  delete log_destinations_[severity];
929  }
931  delete sinks_;
932  sinks_ = NULL;
933 }
934 
935 namespace {
936 
937 std::string g_application_fingerprint;
938 
939 } // namespace
940 
941 void SetApplicationFingerprint(const std::string& fingerprint) {
942  g_application_fingerprint = fingerprint;
943 }
944 
945 namespace {
946 
947 // Directory delimiter; Windows supports both forward slashes and backslashes
948 #ifdef GLOG_OS_WINDOWS
949 const char possible_dir_delim[] = {'\\', '/'};
950 #else
951 const char possible_dir_delim[] = {'/'};
952 #endif
953 
954 string PrettyDuration(int secs) {
955  std::stringstream result;
956  int mins = secs / 60;
957  int hours = mins / 60;
958  mins = mins % 60;
959  secs = secs % 60;
960  result.fill('0');
961  result << hours << ':' << setw(2) << mins << ':' << setw(2) << secs;
962  return result.str();
963 }
964 
965 
966 LogFileObject::LogFileObject(LogSeverity severity,
967  const char* base_filename)
968  : base_filename_selected_(base_filename != NULL),
969  base_filename_((base_filename != NULL) ? base_filename : ""),
971  filename_extension_(),
972  file_(NULL),
973  severity_(severity),
974  bytes_since_flush_(0),
975  dropped_mem_length_(0),
976  file_length_(0),
977  rollover_attempt_(kRolloverAttemptFrequency-1),
978  next_flush_time_(0),
979  start_time_(WallTime_Now()) {
980  assert(severity >= 0);
981  assert(severity < NUM_SEVERITIES);
982 }
983 
984 LogFileObject::~LogFileObject() {
985  MutexLock l(&lock_);
986  if (file_ != NULL) {
987  fclose(file_);
988  file_ = NULL;
989  }
990 }
991 
992 void LogFileObject::SetBasename(const char* basename) {
993  MutexLock l(&lock_);
994  base_filename_selected_ = true;
995  if (base_filename_ != basename) {
996  // Get rid of old log file since we are changing names
997  if (file_ != NULL) {
998  fclose(file_);
999  file_ = NULL;
1000  rollover_attempt_ = kRolloverAttemptFrequency-1;
1001  }
1002  base_filename_ = basename;
1003  }
1004 }
1005 
1006 void LogFileObject::SetExtension(const char* ext) {
1007  MutexLock l(&lock_);
1008  if (filename_extension_ != ext) {
1009  // Get rid of old log file since we are changing names
1010  if (file_ != NULL) {
1011  fclose(file_);
1012  file_ = NULL;
1013  rollover_attempt_ = kRolloverAttemptFrequency-1;
1014  }
1015  filename_extension_ = ext;
1016  }
1017 }
1018 
1019 void LogFileObject::SetSymlinkBasename(const char* symlink_basename) {
1020  MutexLock l(&lock_);
1021  symlink_basename_ = symlink_basename;
1022 }
1023 
1024 void LogFileObject::Flush() {
1025  MutexLock l(&lock_);
1026  FlushUnlocked();
1027 }
1028 
1029 void LogFileObject::FlushUnlocked(){
1030  if (file_ != NULL) {
1031  fflush(file_);
1032  bytes_since_flush_ = 0;
1033  }
1034  // Figure out when we are due for another flush.
1035  const int64 next = (FLAGS_logbufsecs
1036  * static_cast<int64>(1000000)); // in usec
1037  next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
1038 }
1039 
1040 bool LogFileObject::CreateLogfile(const string& time_pid_string) {
1041  string string_filename = base_filename_;
1042  if (FLAGS_timestamp_in_logfile_name) {
1043  string_filename += time_pid_string;
1044  }
1045  string_filename += filename_extension_;
1046  const char* filename = string_filename.c_str();
1047  //only write to files, create if non-existant.
1048  int flags = O_WRONLY | O_CREAT;
1049  if (FLAGS_timestamp_in_logfile_name) {
1050  //demand that the file is unique for our timestamp (fail if it exists).
1051  flags = flags | O_EXCL;
1052  }
1053  int fd = open(filename, flags, FLAGS_logfile_mode);
1054  if (fd == -1) return false;
1055 #ifdef HAVE_FCNTL
1056  // Mark the file close-on-exec. We don't really care if this fails
1057  fcntl(fd, F_SETFD, FD_CLOEXEC);
1058 
1059  // Mark the file as exclusive write access to avoid two clients logging to the
1060  // same file. This applies particularly when !FLAGS_timestamp_in_logfile_name
1061  // (otherwise open would fail because the O_EXCL flag on similar filename).
1062  // locks are released on unlock or close() automatically, only after log is
1063  // released.
1064  // This will work after a fork as it is not inherited (not stored in the fd).
1065  // Lock will not be lost because the file is opened with exclusive lock (write)
1066  // and we will never read from it inside the process.
1067  // TODO windows implementation of this (as flock is not available on mingw).
1068  static struct flock w_lock;
1069 
1070  w_lock.l_type = F_WRLCK;
1071  w_lock.l_start = 0;
1072  w_lock.l_whence = SEEK_SET;
1073  w_lock.l_len = 0;
1074 
1075  int wlock_ret = fcntl(fd, F_SETLK, &w_lock);
1076  if (wlock_ret == -1) {
1077  close(fd); //as we are failing already, do not check errors here
1078  return false;
1079  }
1080 #endif
1081 
1082  //fdopen in append mode so if the file exists it will fseek to the end
1083  file_ = fdopen(fd, "a"); // Make a FILE*.
1084  if (file_ == NULL) { // Man, we're screwed!
1085  close(fd);
1086  if (FLAGS_timestamp_in_logfile_name) {
1087  unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it.
1088  }
1089  return false;
1090  }
1091 #ifdef GLOG_OS_WINDOWS
1092  // https://github.com/golang/go/issues/27638 - make sure we seek to the end to append
1093  // empirically replicated with wine over mingw build
1094  if (!FLAGS_timestamp_in_logfile_name) {
1095  if (fseek(file_, 0, SEEK_END) != 0) {
1096  return false;
1097  }
1098  }
1099 #endif
1100  // We try to create a symlink called <program_name>.<severity>,
1101  // which is easier to use. (Every time we create a new logfile,
1102  // we destroy the old symlink and create a new one, so it always
1103  // points to the latest logfile.) If it fails, we're sad but it's
1104  // no error.
1105  if (!symlink_basename_.empty()) {
1106  // take directory from filename
1107  const char* slash = strrchr(filename, PATH_SEPARATOR);
1108  const string linkname =
1109  symlink_basename_ + '.' + LogSeverityNames[severity_];
1110  string linkpath;
1111  if ( slash ) linkpath = string(filename, static_cast<size_t>(slash-filename+1)); // get dirname
1112  linkpath += linkname;
1113  unlink(linkpath.c_str()); // delete old one if it exists
1114 
1115 #if defined(GLOG_OS_WINDOWS)
1116  // TODO(hamaji): Create lnk file on Windows?
1117 #elif defined(HAVE_UNISTD_H)
1118  // We must have unistd.h.
1119  // Make the symlink be relative (in the same dir) so that if the
1120  // entire log directory gets relocated the link is still valid.
1121  const char *linkdest = slash ? (slash + 1) : filename;
1122  if (symlink(linkdest, linkpath.c_str()) != 0) {
1123  // silently ignore failures
1124  }
1125 
1126  // Make an additional link to the log file in a place specified by
1127  // FLAGS_log_link, if indicated
1128  if (!FLAGS_log_link.empty()) {
1129  linkpath = FLAGS_log_link + "/" + linkname;
1130  unlink(linkpath.c_str()); // delete old one if it exists
1131  if (symlink(filename, linkpath.c_str()) != 0) {
1132  // silently ignore failures
1133  }
1134  }
1135 #endif
1136  }
1137 
1138  return true; // Everything worked
1139 }
1140 
1141 void LogFileObject::Write(bool force_flush,
1142  time_t timestamp,
1143  const char* message,
1144  size_t message_len) {
1145  MutexLock l(&lock_);
1146 
1147  // We don't log if the base_name_ is "" (which means "don't write")
1148  if (base_filename_selected_ && base_filename_.empty()) {
1149  return;
1150  }
1151 
1152  if (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) {
1153  if (file_ != NULL) fclose(file_);
1154  file_ = NULL;
1155  file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0;
1156  rollover_attempt_ = kRolloverAttemptFrequency - 1;
1157  }
1158 
1159  // If there's no destination file, make one before outputting
1160  if (file_ == NULL) {
1161  // Try to rollover the log file every 32 log messages. The only time
1162  // this could matter would be when we have trouble creating the log
1163  // file. If that happens, we'll lose lots of log messages, of course!
1164  if (++rollover_attempt_ != kRolloverAttemptFrequency) return;
1165  rollover_attempt_ = 0;
1166 
1167  struct ::tm tm_time;
1168  if (FLAGS_log_utc_time) {
1169  gmtime_r(&timestamp, &tm_time);
1170  } else {
1171  localtime_r(&timestamp, &tm_time);
1172  }
1173 
1174  // The logfile's filename will have the date/time & pid in it
1175  ostringstream time_pid_stream;
1176  time_pid_stream.fill('0');
1177  time_pid_stream << 1900+tm_time.tm_year
1178  << setw(2) << 1+tm_time.tm_mon
1179  << setw(2) << tm_time.tm_mday
1180  << '-'
1181  << setw(2) << tm_time.tm_hour
1182  << setw(2) << tm_time.tm_min
1183  << setw(2) << tm_time.tm_sec
1184  << '.'
1185  << GetMainThreadPid();
1186  const string& time_pid_string = time_pid_stream.str();
1187 
1188  if (base_filename_selected_) {
1189  if (!CreateLogfile(time_pid_string)) {
1190  perror("Could not create log file");
1191  fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n",
1192  time_pid_string.c_str());
1193  return;
1194  }
1195  } else {
1196  // If no base filename for logs of this severity has been set, use a
1197  // default base filename of
1198  // "<program name>.<hostname>.<user name>.log.<severity level>.". So
1199  // logfiles will have names like
1200  // webserver.examplehost.root.log.INFO.19990817-150000.4354, where
1201  // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00),
1202  // and 4354 is the pid of the logging process. The date & time reflect
1203  // when the file was created for output.
1204  //
1205  // Where does the file get put? Successively try the directories
1206  // "/tmp", and "."
1207  string stripped_filename(
1209  string hostname;
1210  GetHostName(&hostname);
1211 
1212  string uidname = MyUserName();
1213  // We should not call CHECK() here because this function can be
1214  // called after holding on to log_mutex. We don't want to
1215  // attempt to hold on to the same mutex, and get into a
1216  // deadlock. Simply use a name like invalid-user.
1217  if (uidname.empty()) uidname = "invalid-user";
1218 
1219  stripped_filename = stripped_filename+'.'+hostname+'.'
1220  +uidname+".log."
1221  +LogSeverityNames[severity_]+'.';
1222  // We're going to (potentially) try to put logs in several different dirs
1223  const vector<string> & log_dirs = GetLoggingDirectories();
1224 
1225  // Go through the list of dirs, and try to create the log file in each
1226  // until we succeed or run out of options
1227  bool success = false;
1228  for (vector<string>::const_iterator dir = log_dirs.begin();
1229  dir != log_dirs.end();
1230  ++dir) {
1231  base_filename_ = *dir + "/" + stripped_filename;
1232  if ( CreateLogfile(time_pid_string) ) {
1233  success = true;
1234  break;
1235  }
1236  }
1237  // If we never succeeded, we have to give up
1238  if ( success == false ) {
1239  perror("Could not create logging file");
1240  fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!",
1241  time_pid_string.c_str());
1242  return;
1243  }
1244  }
1245 
1246  // Write a header message into the log file
1247  ostringstream file_header_stream;
1248  file_header_stream.fill('0');
1249  file_header_stream << "Log file created at: "
1250  << 1900+tm_time.tm_year << '/'
1251  << setw(2) << 1+tm_time.tm_mon << '/'
1252  << setw(2) << tm_time.tm_mday
1253  << ' '
1254  << setw(2) << tm_time.tm_hour << ':'
1255  << setw(2) << tm_time.tm_min << ':'
1256  << setw(2) << tm_time.tm_sec << (FLAGS_log_utc_time ? " UTC\n" : "\n")
1257  << "Running on machine: "
1258  << LogDestination::hostname() << '\n';
1259 
1260  if(!g_application_fingerprint.empty()) {
1261  file_header_stream << "Application fingerprint: " << g_application_fingerprint << '\n';
1262  }
1263  const char* const date_time_format = FLAGS_log_year_in_prefix
1264  ? "yyyymmdd hh:mm:ss.uuuuuu"
1265  : "mmdd hh:mm:ss.uuuuuu";
1266  file_header_stream << "Running duration (h:mm:ss): "
1267  << PrettyDuration(static_cast<int>(WallTime_Now() - start_time_)) << '\n'
1268  << "Log line format: [IWEF]" << date_time_format << " "
1269  << "threadid file:line] msg" << '\n';
1270  const string& file_header_string = file_header_stream.str();
1271 
1272  const size_t header_len = file_header_string.size();
1273  fwrite(file_header_string.data(), 1, header_len, file_);
1274  file_length_ += header_len;
1275  bytes_since_flush_ += header_len;
1276  }
1277 
1278  // Write to LOG file
1279  if ( !stop_writing ) {
1280  // fwrite() doesn't return an error when the disk is full, for
1281  // messages that are less than 4096 bytes. When the disk is full,
1282  // it returns the message length for messages that are less than
1283  // 4096 bytes. fwrite() returns 4096 for message lengths that are
1284  // greater than 4096, thereby indicating an error.
1285  errno = 0;
1286  fwrite(message, 1, message_len, file_);
1287  if ( FLAGS_stop_logging_if_full_disk &&
1288  errno == ENOSPC ) { // disk full, stop writing to disk
1289  stop_writing = true; // until the disk is
1290  return;
1291  } else {
1292  file_length_ += message_len;
1293  bytes_since_flush_ += message_len;
1294  }
1295  } else {
1296  if (CycleClock_Now() >= next_flush_time_) {
1297  stop_writing = false; // check to see if disk has free space.
1298  }
1299  return; // no need to flush
1300  }
1301 
1302  // See important msgs *now*. Also, flush logs at least every 10^6 chars,
1303  // or every "FLAGS_logbufsecs" seconds.
1304  if ( force_flush ||
1305  (bytes_since_flush_ >= 1000000) ||
1306  (CycleClock_Now() >= next_flush_time_) ) {
1307  FlushUnlocked();
1308 #ifdef GLOG_OS_LINUX
1309  // Only consider files >= 3MiB
1310  if (FLAGS_drop_log_memory && file_length_ >= (3U << 20U)) {
1311  // Don't evict the most recent 1-2MiB so as not to impact a tailer
1312  // of the log file and to avoid page rounding issue on linux < 4.7
1313  uint32 total_drop_length =
1314  (file_length_ & ~((1U << 20U) - 1U)) - (1U << 20U);
1315  uint32 this_drop_length = total_drop_length - dropped_mem_length_;
1316  if (this_drop_length >= (2U << 20U)) {
1317  // Only advise when >= 2MiB to drop
1318 # if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
1319  // 'posix_fadvise' introduced in API 21:
1320  // * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732
1321 # else
1322  posix_fadvise(fileno(file_), dropped_mem_length_, this_drop_length,
1323  POSIX_FADV_DONTNEED);
1324 # endif
1325  dropped_mem_length_ = total_drop_length;
1326  }
1327  }
1328 #endif
1329 
1330  // Remove old logs
1331  if (log_cleaner.enabled()) {
1332  log_cleaner.Run(base_filename_selected_,
1333  base_filename_,
1334  filename_extension_);
1335  }
1336  }
1337 }
1338 
1339 LogCleaner::LogCleaner() : enabled_(false), overdue_days_(7), next_cleanup_time_(0) {}
1340 
1341 void LogCleaner::Enable(unsigned int overdue_days) {
1342  enabled_ = true;
1343  overdue_days_ = overdue_days;
1344 }
1345 
1346 void LogCleaner::Disable() {
1347  enabled_ = false;
1348 }
1349 
1350 void LogCleaner::UpdateCleanUpTime() {
1351  const int64 next = (FLAGS_logcleansecs
1352  * 1000000); // in usec
1353  next_cleanup_time_ = CycleClock_Now() + UsecToCycles(next);
1354 }
1355 
1356 void LogCleaner::Run(bool base_filename_selected,
1357  const string& base_filename,
1358  const string& filename_extension) {
1359  assert(enabled_);
1360  assert(!base_filename_selected || !base_filename.empty());
1361 
1362  // avoid scanning logs too frequently
1363  if (CycleClock_Now() < next_cleanup_time_) {
1364  return;
1365  }
1366  UpdateCleanUpTime();
1367 
1368  vector<string> dirs;
1369 
1370  if (!base_filename_selected) {
1371  dirs = GetLoggingDirectories();
1372  } else {
1373  size_t pos = base_filename.find_last_of(possible_dir_delim, string::npos,
1374  sizeof(possible_dir_delim));
1375  if (pos != string::npos) {
1376  string dir = base_filename.substr(0, pos + 1);
1377  dirs.push_back(dir);
1378  } else {
1379  dirs.push_back(".");
1380  }
1381  }
1382 
1383  for (size_t i = 0; i < dirs.size(); i++) {
1384  vector<string> logs = GetOverdueLogNames(dirs[i],
1385  overdue_days_,
1386  base_filename,
1387  filename_extension);
1388  for (size_t j = 0; j < logs.size(); j++) {
1389  static_cast<void>(unlink(logs[j].c_str()));
1390  }
1391  }
1392 }
1393 
1394 vector<string> LogCleaner::GetOverdueLogNames(
1395  string log_directory, unsigned int days, const string& base_filename,
1396  const string& filename_extension) const {
1397  // The names of overdue logs.
1398  vector<string> overdue_log_names;
1399 
1400  // Try to get all files within log_directory.
1401  DIR *dir;
1402  struct dirent *ent;
1403 
1404  if ((dir = opendir(log_directory.c_str()))) {
1405  while ((ent = readdir(dir))) {
1406  if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
1407  continue;
1408  }
1409 
1410  string filepath = ent->d_name;
1411  const char* const dir_delim_end =
1412  possible_dir_delim + sizeof(possible_dir_delim);
1413 
1414  if (!log_directory.empty() &&
1415  std::find(possible_dir_delim, dir_delim_end,
1416  log_directory[log_directory.size() - 1]) != dir_delim_end) {
1417  filepath = log_directory + filepath;
1418  }
1419 
1420  if (IsLogFromCurrentProject(filepath, base_filename, filename_extension) &&
1421  IsLogLastModifiedOver(filepath, days)) {
1422  overdue_log_names.push_back(filepath);
1423  }
1424  }
1425  closedir(dir);
1426  }
1427 
1428  return overdue_log_names;
1429 }
1430 
1431 bool LogCleaner::IsLogFromCurrentProject(const string& filepath,
1432  const string& base_filename,
1433  const string& filename_extension) const {
1434  // We should remove duplicated delimiters from `base_filename`, e.g.,
1435  // before: "/tmp//<base_filename>.<create_time>.<pid>"
1436  // after: "/tmp/<base_filename>.<create_time>.<pid>"
1437  string cleaned_base_filename;
1438 
1439  const char* const dir_delim_end =
1440  possible_dir_delim + sizeof(possible_dir_delim);
1441 
1442  size_t real_filepath_size = filepath.size();
1443  for (size_t i = 0; i < base_filename.size(); ++i) {
1444  const char& c = base_filename[i];
1445 
1446  if (cleaned_base_filename.empty()) {
1447  cleaned_base_filename += c;
1448  } else if (std::find(possible_dir_delim, dir_delim_end, c) ==
1449  dir_delim_end ||
1450  (!cleaned_base_filename.empty() &&
1451  c != cleaned_base_filename[cleaned_base_filename.size() - 1])) {
1452  cleaned_base_filename += c;
1453  }
1454  }
1455 
1456  // Return early if the filename doesn't start with `cleaned_base_filename`.
1457  if (filepath.find(cleaned_base_filename) != 0) {
1458  return false;
1459  }
1460 
1461  // Check if in the string `filename_extension` is right next to
1462  // `cleaned_base_filename` in `filepath` if the user
1463  // has set a custom filename extension.
1464  if (!filename_extension.empty()) {
1465  if (cleaned_base_filename.size() >= real_filepath_size) {
1466  return false;
1467  }
1468  // for origin version, `filename_extension` is middle of the `filepath`.
1469  string ext = filepath.substr(cleaned_base_filename.size(), filename_extension.size());
1470  if (ext == filename_extension) {
1471  cleaned_base_filename += filename_extension;
1472  }
1473  else {
1474  // for new version, `filename_extension` is right of the `filepath`.
1475  if (filename_extension.size() >= real_filepath_size) {
1476  return false;
1477  }
1478  real_filepath_size = filepath.size() - filename_extension.size();
1479  if (filepath.substr(real_filepath_size) != filename_extension) {
1480  return false;
1481  }
1482  }
1483  }
1484 
1485  // The characters after `cleaned_base_filename` should match the format:
1486  // YYYYMMDD-HHMMSS.pid
1487  for (size_t i = cleaned_base_filename.size(); i < real_filepath_size; i++) {
1488  const char& c = filepath[i];
1489 
1490  if (i <= cleaned_base_filename.size() + 7) { // 0 ~ 7 : YYYYMMDD
1491  if (c < '0' || c > '9') { return false; }
1492 
1493  } else if (i == cleaned_base_filename.size() + 8) { // 8: -
1494  if (c != '-') { return false; }
1495 
1496  } else if (i <= cleaned_base_filename.size() + 14) { // 9 ~ 14: HHMMSS
1497  if (c < '0' || c > '9') { return false; }
1498 
1499  } else if (i == cleaned_base_filename.size() + 15) { // 15: .
1500  if (c != '.') { return false; }
1501 
1502  } else if (i >= cleaned_base_filename.size() + 16) { // 16+: pid
1503  if (c < '0' || c > '9') { return false; }
1504  }
1505  }
1506 
1507  return true;
1508 }
1509 
1510 bool LogCleaner::IsLogLastModifiedOver(const string& filepath,
1511  unsigned int days) const {
1512  // Try to get the last modified time of this file.
1513  struct stat file_stat;
1514 
1515  if (stat(filepath.c_str(), &file_stat) == 0) {
1516  const time_t seconds_in_a_day = 60 * 60 * 24;
1517  time_t last_modified_time = file_stat.st_mtime;
1518  time_t current_time = time(NULL);
1519  return difftime(current_time, last_modified_time) > days * seconds_in_a_day;
1520  }
1521 
1522  // If failed to get file stat, don't return true!
1523  return false;
1524 }
1525 
1526 } // namespace
1527 
1528 // Static log data space to avoid alloc failures in a LOG(FATAL)
1529 //
1530 // Since multiple threads may call LOG(FATAL), and we want to preserve
1531 // the data from the first call, we allocate two sets of space. One
1532 // for exclusive use by the first thread, and one for shared use by
1533 // all other threads.
1535 static CrashReason crash_reason;
1536 static bool fatal_msg_exclusive = true;
1539 
1540 #ifdef GLOG_THREAD_LOCAL_STORAGE
1541 // Static thread-local log data space to use, because typically at most one
1542 // LogMessageData object exists (in this case glog makes zero heap memory
1543 // allocations).
1544 static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true;
1545 
1546 #if defined(HAVE_ALIGNED_STORAGE) && __cplusplus >= 201103L
1547 static GLOG_THREAD_LOCAL_STORAGE
1548  std::aligned_storage<sizeof(LogMessage::LogMessageData),
1549  alignof(LogMessage::LogMessageData)>::type thread_msg_data;
1550 #else
1551 static GLOG_THREAD_LOCAL_STORAGE
1552  char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)];
1553 #endif // HAVE_ALIGNED_STORAGE
1554 #endif // defined(GLOG_THREAD_LOCAL_STORAGE)
1555 
1557  : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
1558 }
1559 
1560 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
1561  int64 ctr, void (LogMessage::*send_method)())
1562  : allocated_(NULL) {
1563  Init(file, line, severity, send_method);
1564  data_->stream_.set_ctr(ctr);
1565 }
1566 
1567 LogMessage::LogMessage(const char* file, int line,
1568  const CheckOpString& result)
1569  : allocated_(NULL) {
1570  Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
1571  stream() << "Check failed: " << (*result.str_) << " ";
1572 }
1573 
1574 LogMessage::LogMessage(const char* file, int line)
1575  : allocated_(NULL) {
1576  Init(file, line, GLOG_INFO, &LogMessage::SendToLog);
1577 }
1578 
1579 LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
1580  : allocated_(NULL) {
1581  Init(file, line, severity, &LogMessage::SendToLog);
1582 }
1583 
1584 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
1585  LogSink* sink, bool also_send_to_log)
1586  : allocated_(NULL) {
1587  Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
1588  &LogMessage::SendToSink);
1589  data_->sink_ = sink; // override Init()'s setting to NULL
1590 }
1591 
1592 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
1593  vector<string> *outvec)
1594  : allocated_(NULL) {
1595  Init(file, line, severity, &LogMessage::SaveOrSendToLog);
1596  data_->outvec_ = outvec; // override Init()'s setting to NULL
1597 }
1598 
1599 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
1600  string *message)
1601  : allocated_(NULL) {
1602  Init(file, line, severity, &LogMessage::WriteToStringAndLog);
1603  data_->message_ = message; // override Init()'s setting to NULL
1604 }
1605 
1606 void LogMessage::Init(const char* file,
1607  int line,
1609  void (LogMessage::*send_method)()) {
1610  allocated_ = NULL;
1611  if (severity != GLOG_FATAL || !exit_on_dfatal) {
1612 #ifdef GLOG_THREAD_LOCAL_STORAGE
1613  // No need for locking, because this is thread local.
1614  if (thread_data_available) {
1615  thread_data_available = false;
1616 #ifdef HAVE_ALIGNED_STORAGE
1617  data_ = new (&thread_msg_data) LogMessageData;
1618 #else
1619  const uintptr_t kAlign = sizeof(void*) - 1;
1620 
1621  char* align_ptr =
1622  reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign);
1623  data_ = new (align_ptr) LogMessageData;
1624  assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0);
1625 #endif
1626  } else {
1627  allocated_ = new LogMessageData();
1628  data_ = allocated_;
1629  }
1630 #else // !defined(GLOG_THREAD_LOCAL_STORAGE)
1631  allocated_ = new LogMessageData();
1632  data_ = allocated_;
1633 #endif // defined(GLOG_THREAD_LOCAL_STORAGE)
1634  data_->first_fatal_ = false;
1635  } else {
1637  if (fatal_msg_exclusive) {
1638  fatal_msg_exclusive = false;
1640  data_->first_fatal_ = true;
1641  } else {
1643  data_->first_fatal_ = false;
1644  }
1645  }
1646 
1647  data_->preserved_errno_ = errno;
1648  data_->severity_ = severity;
1649  data_->line_ = line;
1650  data_->send_method_ = send_method;
1651  data_->sink_ = NULL;
1652  data_->outvec_ = NULL;
1653  WallTime now = WallTime_Now();
1654  time_t timestamp_now = static_cast<time_t>(now);
1655  logmsgtime_ = LogMessageTime(timestamp_now, now);
1656 
1657  data_->num_chars_to_log_ = 0;
1658  data_->num_chars_to_syslog_ = 0;
1659  data_->basename_ = const_basename(file);
1660  data_->fullname_ = file;
1661  data_->has_been_flushed_ = false;
1662 
1663  // If specified, prepend a prefix to each line. For example:
1664  // I20201018 160715 f5d4fbb0 logging.cc:1153]
1665  // (log level, GMT year, month, date, time, thread_id, file basename, line)
1666  // We exclude the thread_id for the default thread.
1667  if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
1668  std::ios saved_fmt(NULL);
1669  saved_fmt.copyfmt(stream());
1670  stream().fill('0');
1671  #ifdef GLOG_CUSTOM_PREFIX_SUPPORT
1672  if (custom_prefix_callback == NULL) {
1673  #endif
1674  stream() << LogSeverityNames[severity][0];
1675  if (FLAGS_log_year_in_prefix) {
1676  stream() << setw(4) << 1900 + logmsgtime_.year();
1677  }
1678  stream() << setw(2) << 1 + logmsgtime_.month()
1679  << setw(2) << logmsgtime_.day()
1680  << ' '
1681  << setw(2) << logmsgtime_.hour() << ':'
1682  << setw(2) << logmsgtime_.min() << ':'
1683  << setw(2) << logmsgtime_.sec() << "."
1684  << setw(6) << logmsgtime_.usec()
1685  << ' '
1686  << setfill(' ') << setw(5)
1687  << static_cast<unsigned int>(GetTID()) << setfill('0')
1688  << ' '
1689  << data_->basename_ << ':' << data_->line_ << "] ";
1690  #ifdef GLOG_CUSTOM_PREFIX_SUPPORT
1691  } else {
1692  custom_prefix_callback(
1693  stream(),
1694  LogMessageInfo(LogSeverityNames[severity],
1695  data_->basename_, data_->line_, GetTID(),
1696  logmsgtime_),
1697  custom_prefix_callback_data
1698  );
1699  stream() << " ";
1700  }
1701  #endif
1702  stream().copyfmt(saved_fmt);
1703  }
1704  data_->num_prefix_chars_ = data_->stream_.pcount();
1705 
1706  if (!FLAGS_log_backtrace_at.empty()) {
1707  char fileline[128];
1708  snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line);
1709 #ifdef HAVE_STACKTRACE
1710  if (FLAGS_log_backtrace_at == fileline) {
1711  string stacktrace;
1712  DumpStackTraceToString(&stacktrace);
1713  stream() << " (stacktrace:\n" << stacktrace << ") ";
1714  }
1715 #endif
1716  }
1717 }
1718 
1719 const LogMessageTime& LogMessage::getLogMessageTime() const {
1720  return logmsgtime_;
1721 }
1722 
1723 LogMessage::~LogMessage() {
1724  Flush();
1725 #ifdef GLOG_THREAD_LOCAL_STORAGE
1726  if (data_ == static_cast<void*>(&thread_msg_data)) {
1727  data_->~LogMessageData();
1728  thread_data_available = true;
1729  }
1730  else {
1731  delete allocated_;
1732  }
1733 #else // !defined(GLOG_THREAD_LOCAL_STORAGE)
1734  delete allocated_;
1735 #endif // defined(GLOG_THREAD_LOCAL_STORAGE)
1736 }
1737 
1738 int LogMessage::preserved_errno() const {
1739  return data_->preserved_errno_;
1740 }
1741 
1742 ostream& LogMessage::stream() {
1743  return data_->stream_;
1744 }
1745 
1746 // Flush buffered message, called by the destructor, or any other function
1747 // that needs to synchronize the log.
1748 void LogMessage::Flush() {
1749  if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) {
1750  return;
1751  }
1752 
1753  data_->num_chars_to_log_ = data_->stream_.pcount();
1754  data_->num_chars_to_syslog_ =
1755  data_->num_chars_to_log_ - data_->num_prefix_chars_;
1756 
1757  // Do we need to add a \n to the end of this message?
1758  bool append_newline =
1759  (data_->message_text_[data_->num_chars_to_log_-1] != '\n');
1760  char original_final_char = '\0';
1761 
1762  // If we do need to add a \n, we'll do it by violating the memory of the
1763  // ostrstream buffer. This is quick, and we'll make sure to undo our
1764  // modification before anything else is done with the ostrstream. It
1765  // would be preferable not to do things this way, but it seems to be
1766  // the best way to deal with this.
1767  if (append_newline) {
1768  original_final_char = data_->message_text_[data_->num_chars_to_log_];
1769  data_->message_text_[data_->num_chars_to_log_++] = '\n';
1770  }
1771  data_->message_text_[data_->num_chars_to_log_] = '\0';
1772 
1773  // Prevent any subtle race conditions by wrapping a mutex lock around
1774  // the actual logging action per se.
1775  {
1776  MutexLock l(&log_mutex);
1777  (this->*(data_->send_method_))();
1778  ++num_messages_[static_cast<int>(data_->severity_)];
1779  }
1781 
1782  if (append_newline) {
1783  // Fix the ostrstream back how it was before we screwed with it.
1784  // It's 99.44% certain that we don't need to worry about doing this.
1785  data_->message_text_[data_->num_chars_to_log_-1] = original_final_char;
1786  }
1787 
1788  // If errno was already set before we enter the logging call, we'll
1789  // set it back to that value when we return from the logging call.
1790  // It happens often that we log an error message after a syscall
1791  // failure, which can potentially set the errno to some other
1792  // values. We would like to preserve the original errno.
1793  if (data_->preserved_errno_ != 0) {
1794  errno = data_->preserved_errno_;
1795  }
1796 
1797  // Note that this message is now safely logged. If we're asked to flush
1798  // again, as a result of destruction, say, we'll do nothing on future calls.
1799  data_->has_been_flushed_ = true;
1800 }
1801 
1802 // Copy of first FATAL log message so that we can print it out again
1803 // after all the stack traces. To preserve legacy behavior, we don't
1804 // use fatal_msg_data_exclusive.
1805 static time_t fatal_time;
1806 static char fatal_message[256];
1807 
1809  if (fatal_message[0]) {
1810  const size_t n = strlen(fatal_message);
1811  if (!FLAGS_logtostderr) {
1812  // Also write to stderr (don't color to avoid terminal checks)
1814  }
1816  }
1817 }
1818 
1819 // L >= log_mutex (callers must hold the log_mutex).
1820 void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
1821  static bool already_warned_before_initgoogle = false;
1822 
1824 
1825  RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
1826  data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
1827 
1828  // Messages of a given severity get logged to lower severity logs, too
1829 
1830  if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) {
1831  const char w[] = "WARNING: Logging before InitGoogleLogging() is "
1832  "written to STDERR\n";
1833  WriteToStderr(w, strlen(w));
1834  already_warned_before_initgoogle = true;
1835  }
1836 
1837  // global flag: never log to file if set. Also -- don't log to a
1838  // file if we haven't parsed the command line flags to get the
1839  // program name.
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  }
1848 
1849  // this could be protected by a flag if necessary.
1850  LogDestination::LogToSinks(data_->severity_,
1851  data_->fullname_, data_->basename_,
1852  data_->line_, logmsgtime_,
1853  data_->message_text_ + data_->num_prefix_chars_,
1854  (data_->num_chars_to_log_ -
1855  data_->num_prefix_chars_ - 1) );
1856  } else {
1857  // log this message to all log files of severity <= severity_
1858  LogDestination::LogToAllLogfiles(data_->severity_, logmsgtime_.timestamp(),
1859  data_->message_text_,
1860  data_->num_chars_to_log_);
1861 
1862  LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_,
1863  data_->num_chars_to_log_,
1864  data_->num_prefix_chars_);
1865  LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_,
1866  data_->num_chars_to_log_);
1867  LogDestination::LogToSinks(data_->severity_,
1868  data_->fullname_, data_->basename_,
1869  data_->line_, logmsgtime_,
1870  data_->message_text_ + data_->num_prefix_chars_,
1871  (data_->num_chars_to_log_
1872  - data_->num_prefix_chars_ - 1) );
1873  // NOTE: -1 removes trailing \n
1874  }
1875 
1876  // If we log a FATAL message, flush all the log destinations, then toss
1877  // a signal for others to catch. We leave the logs in a state that
1878  // someone else can use them (as long as they flush afterwards)
1879  if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) {
1880  if (data_->first_fatal_) {
1881  // Store crash information so that it is accessible from within signal
1882  // handlers that may be invoked later.
1883  RecordCrashReason(&crash_reason);
1885 
1886  // Store shortened fatal message for other logs and GWQ status
1887  const size_t copy = min(data_->num_chars_to_log_,
1888  sizeof(fatal_message)-1);
1889  memcpy(fatal_message, data_->message_text_, copy);
1890  fatal_message[copy] = '\0';
1891  fatal_time = logmsgtime_.timestamp();
1892  }
1893 
1894  if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
1895  for (int i = 0; i < NUM_SEVERITIES; ++i) {
1897  LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0);
1898  }
1899  }
1900  }
1901 
1902  // release the lock that our caller (directly or indirectly)
1903  // LogMessage::~LogMessage() grabbed so that signal handlers
1904  // can use the logging facility. Alternately, we could add
1905  // an entire unsafe logging interface to bypass locking
1906  // for signal handlers but this seems simpler.
1907  log_mutex.Unlock();
1909 
1910  const char* message = "*** Check failure stack trace: ***\n";
1911  if (write(STDERR_FILENO, message, strlen(message)) < 0) {
1912  // Ignore errors.
1913  }
1914 #if defined(__ANDROID__)
1915  // ANDROID_LOG_FATAL as this message is of FATAL severity.
1916  __android_log_write(ANDROID_LOG_FATAL,
1918  message);
1919 #endif
1920  Fail();
1921  }
1922 }
1923 
1924 void LogMessage::RecordCrashReason(
1930 #ifdef HAVE_STACKTRACE
1931  // Retrieve the stack trace, omitting the logging frames that got us here.
1932  reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4);
1933 #else
1934  reason->depth = 0;
1935 #endif
1936 }
1937 
1938 GLOG_EXPORT logging_fail_func_t g_logging_fail_func =
1939  reinterpret_cast<logging_fail_func_t>(&abort);
1940 
1941 void InstallFailureFunction(logging_fail_func_t fail_func) {
1942  g_logging_fail_func = fail_func;
1943 }
1944 
1945 void LogMessage::Fail() {
1947 }
1948 
1949 // L >= log_mutex (callers must hold the log_mutex).
1950 void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
1951  if (data_->sink_ != NULL) {
1952  RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
1953  data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
1954  data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
1955  data_->line_, logmsgtime_,
1956  data_->message_text_ + data_->num_prefix_chars_,
1957  (data_->num_chars_to_log_ -
1958  data_->num_prefix_chars_ - 1) );
1959  }
1960 }
1961 
1962 // L >= log_mutex (callers must hold the log_mutex).
1963 void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
1964  SendToSink();
1965  SendToLog();
1966 }
1967 
1968 // L >= log_mutex (callers must hold the log_mutex).
1969 void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
1970  if (data_->outvec_ != NULL) {
1971  RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
1972  data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
1973  // Omit prefix of message and trailing newline when recording in outvec_.
1974  const char *start = data_->message_text_ + data_->num_prefix_chars_;
1975  size_t len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
1976  data_->outvec_->push_back(string(start, len));
1977  } else {
1978  SendToLog();
1979  }
1980 }
1981 
1982 void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
1983  if (data_->message_ != NULL) {
1984  RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
1985  data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
1986  // Omit prefix of message and trailing newline when writing to message_.
1987  const char *start = data_->message_text_ + data_->num_prefix_chars_;
1988  size_t len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
1989  data_->message_->assign(start, len);
1990  }
1991  SendToLog();
1992 }
1993 
1994 // L >= log_mutex (callers must hold the log_mutex).
1995 void LogMessage::SendToSyslogAndLog() {
1996 #ifdef HAVE_SYSLOG_H
1997  // Before any calls to syslog(), make a single call to openlog()
1998  static bool openlog_already_called = false;
1999  if (!openlog_already_called) {
2001  LOG_CONS | LOG_NDELAY | LOG_PID,
2002  LOG_USER);
2003  openlog_already_called = true;
2004  }
2005 
2006  // This array maps Google severity levels to syslog levels
2007  const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
2008  syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s",
2009  int(data_->num_chars_to_syslog_),
2010  data_->message_text_ + data_->num_prefix_chars_);
2011  SendToLog();
2012 #else
2013  LOG(ERROR) << "No syslog support: message=" << data_->message_text_;
2014 #endif
2015 }
2016 
2017 base::Logger* base::GetLogger(LogSeverity severity) {
2018  MutexLock l(&log_mutex);
2020 }
2021 
2022 void base::SetLogger(LogSeverity severity, base::Logger* logger) {
2023  MutexLock l(&log_mutex);
2025 }
2026 
2027 // L < log_mutex. Acquires and releases mutex_.
2028 int64 LogMessage::num_messages(int severity) {
2029  MutexLock l(&log_mutex);
2030  return num_messages_[severity];
2031 }
2032 
2033 // Output the COUNTER value. This is only valid if ostream is a
2034 // LogStream.
2035 ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
2036 #ifdef DISABLE_RTTI
2037  LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
2038 #else
2039  LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os);
2040 #endif
2041  CHECK(log && log == log->self())
2042  << "You must not use COUNTER with non-glog ostream";
2043  os << log->ctr();
2044  return os;
2045 }
2046 
2047 ErrnoLogMessage::ErrnoLogMessage(const char* file, int line,
2048  LogSeverity severity, int64 ctr,
2049  void (LogMessage::*send_method)())
2050  : LogMessage(file, line, severity, ctr, send_method) {}
2051 
2052 ErrnoLogMessage::~ErrnoLogMessage() {
2053  // Don't access errno directly because it may have been altered
2054  // while streaming the message.
2055  stream() << ": " << StrError(preserved_errno()) << " ["
2056  << preserved_errno() << "]";
2057 }
2058 
2059 void FlushLogFiles(LogSeverity min_severity) {
2060  LogDestination::FlushLogFiles(min_severity);
2061 }
2062 
2063 void FlushLogFilesUnsafe(LogSeverity min_severity) {
2065 }
2066 
2067 void SetLogDestination(LogSeverity severity, const char* base_filename) {
2069 }
2070 
2071 void SetLogSymlink(LogSeverity severity, const char* symlink_basename) {
2072  LogDestination::SetLogSymlink(severity, symlink_basename);
2073 }
2074 
2075 LogSink::~LogSink() {
2076 }
2077 
2078 void LogSink::send(LogSeverity severity, const char* full_filename,
2079  const char* base_filename, int line,
2080  const LogMessageTime& time, const char* message,
2081  size_t message_len) {
2082 #if defined(__GNUC__)
2083 #pragma GCC diagnostic push
2084 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2085 #elif defined(_MSC_VER)
2086 #pragma warning(push)
2087 #pragma warning(disable : 4996)
2088 #endif // __GNUC__
2089  send(severity, full_filename, base_filename, line, &time.tm(), message,
2090  message_len);
2091 #if defined(__GNUC__)
2092 #pragma GCC diagnostic pop
2093 #elif defined(_MSC_VER)
2094 #pragma warning(pop)
2095 #endif // __GNUC__
2096 }
2097 
2098 void LogSink::send(LogSeverity severity, const char* full_filename,
2099  const char* base_filename, int line, const std::tm* t,
2100  const char* message, size_t message_len) {
2101  (void)severity;
2102  (void)full_filename;
2103  (void)base_filename;
2104  (void)line;
2105  (void)t;
2106  (void)message;
2107  (void)message_len;
2108 }
2109 
2110 void LogSink::WaitTillSent() {
2111  // noop default
2112 }
2113 
2114 string LogSink::ToString(LogSeverity severity, const char* file, int line,
2115  const LogMessageTime& logmsgtime, const char* message,
2116  size_t message_len) {
2117  ostringstream stream(string(message, message_len));
2118  stream.fill('0');
2119 
2121  << setw(4) << 1900 + logmsgtime.year()
2122  << setw(2) << 1 + logmsgtime.month()
2123  << setw(2) << logmsgtime.day()
2124  << ' '
2125  << setw(2) << logmsgtime.hour() << ':'
2126  << setw(2) << logmsgtime.min() << ':'
2127  << setw(2) << logmsgtime.sec() << '.'
2128  << setw(6) << logmsgtime.usec()
2129  << ' '
2130  << setfill(' ') << setw(5) << GetTID() << setfill('0')
2131  << ' '
2132  << file << ':' << line << "] ";
2133 
2134  stream << string(message, message_len);
2135  return stream.str();
2136 }
2137 
2138 void AddLogSink(LogSink *destination) {
2139  LogDestination::AddLogSink(destination);
2140 }
2141 
2142 void RemoveLogSink(LogSink *destination) {
2143  LogDestination::RemoveLogSink(destination);
2144 }
2145 
2146 void SetLogFilenameExtension(const char* ext) {
2148 }
2149 
2150 void SetStderrLogging(LogSeverity min_severity) {
2151  LogDestination::SetStderrLogging(min_severity);
2152 }
2153 
2154 void SetEmailLogging(LogSeverity min_severity, const char* addresses) {
2155  LogDestination::SetEmailLogging(min_severity, addresses);
2156 }
2157 
2158 void LogToStderr() {
2160 }
2161 
2162 namespace base {
2163 namespace internal {
2164 
2165 bool GetExitOnDFatal();
2167  MutexLock l(&log_mutex);
2168  return exit_on_dfatal;
2169 }
2170 
2171 // Determines whether we exit the program for a LOG(DFATAL) message in
2172 // debug mode. It does this by skipping the call to Fail/FailQuietly.
2173 // This is intended for testing only.
2174 //
2175 // This can have some effects on LOG(FATAL) as well. Failure messages
2176 // are always allocated (rather than sharing a buffer), the crash
2177 // reason is not recorded, the "gwq" status message is not updated,
2178 // and the stack trace is not recorded. The LOG(FATAL) *will* still
2179 // exit the program. Since this function is used only in testing,
2180 // these differences are acceptable.
2181 void SetExitOnDFatal(bool value);
2183  MutexLock l(&log_mutex);
2185 }
2186 
2187 } // namespace internal
2188 } // namespace base
2189 
2190 // Shell-escaping as we need to shell out ot /bin/mail.
2191 static const char kDontNeedShellEscapeChars[] =
2192  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2193  "abcdefghijklmnopqrstuvwxyz"
2194  "0123456789+-_.=/:,@";
2195 
2196 static string ShellEscape(const string& src) {
2197  string result;
2198  if (!src.empty() && // empty string needs quotes
2199  src.find_first_not_of(kDontNeedShellEscapeChars) == string::npos) {
2200  // only contains chars that don't need quotes; it's fine
2201  result.assign(src);
2202  } else if (src.find_first_of('\'') == string::npos) {
2203  // no single quotes; just wrap it in single quotes
2204  result.assign("'");
2205  result.append(src);
2206  result.append("'");
2207  } else {
2208  // needs double quote escaping
2209  result.assign("\"");
2210  for (size_t i = 0; i < src.size(); ++i) {
2211  switch (src[i]) {
2212  case '\\':
2213  case '$':
2214  case '"':
2215  case '`':
2216  result.append("\\");
2217  }
2218  result.append(src, i, 1);
2219  }
2220  result.append("\"");
2221  }
2222  return result;
2223 }
2224 
2225 
2226 // use_logging controls whether the logging functions LOG/VLOG are used
2227 // to log errors. It should be set to false when the caller holds the
2228 // log_mutex.
2229 static bool SendEmailInternal(const char*dest, const char *subject,
2230  const char*body, bool use_logging) {
2231 #ifndef __EMSCRIPTEN__
2232  if (dest && *dest) {
2233  if ( use_logging ) {
2234  VLOG(1) << "Trying to send TITLE:" << subject
2235  << " BODY:" << body << " to " << dest;
2236  } else {
2237  fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n",
2238  subject, body, dest);
2239  }
2240 
2241  string logmailer = FLAGS_logmailer;
2242  if (logmailer.empty()) {
2243  logmailer = "/bin/mail";
2244  }
2245  string cmd =
2246  logmailer + " -s" +
2247  ShellEscape(subject) + " " + ShellEscape(dest);
2248  if (use_logging) {
2249  VLOG(4) << "Mailing command: " << cmd;
2250  }
2251 
2252  FILE* pipe = popen(cmd.c_str(), "w");
2253  if (pipe != NULL) {
2254  // Add the body if we have one
2255  if (body) {
2256  fwrite(body, sizeof(char), strlen(body), pipe);
2257  }
2258  bool ok = pclose(pipe) != -1;
2259  if ( !ok ) {
2260  if ( use_logging ) {
2261  LOG(ERROR) << "Problems sending mail to " << dest << ": "
2262  << StrError(errno);
2263  } else {
2264  fprintf(stderr, "Problems sending mail to %s: %s\n",
2265  dest, StrError(errno).c_str());
2266  }
2267  }
2268  return ok;
2269  } else {
2270  if ( use_logging ) {
2271  LOG(ERROR) << "Unable to send mail to " << dest;
2272  } else {
2273  fprintf(stderr, "Unable to send mail to %s\n", dest);
2274  }
2275  }
2276  }
2277 #endif
2278  return false;
2279 }
2280 
2281 bool SendEmail(const char*dest, const char *subject, const char*body){
2282  return SendEmailInternal(dest, subject, body, true);
2283 }
2284 
2285 static void GetTempDirectories(vector<string>* list) {
2286  list->clear();
2287 #ifdef GLOG_OS_WINDOWS
2288  // On windows we'll try to find a directory in this order:
2289  // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is)
2290  // C:/TMP/
2291  // C:/TEMP/
2292  // C:/WINDOWS/ or C:/WINNT/
2293  // .
2294  char tmp[MAX_PATH];
2295  if (GetTempPathA(MAX_PATH, tmp))
2296  list->push_back(tmp);
2297  list->push_back("C:\\tmp\\");
2298  list->push_back("C:\\temp\\");
2299 #else
2300  // Directories, in order of preference. If we find a dir that
2301  // exists, we stop adding other less-preferred dirs
2302  const char * candidates[] = {
2303  // Non-null only during unittest/regtest
2304  getenv("TEST_TMPDIR"),
2305 
2306  // Explicitly-supplied temp dirs
2307  getenv("TMPDIR"), getenv("TMP"),
2308 
2309  // If all else fails
2310  "/tmp",
2311  };
2312 
2313  for (size_t i = 0; i < ARRAYSIZE(candidates); i++) {
2314  const char *d = candidates[i];
2315  if (!d) continue; // Empty env var
2316 
2317  // Make sure we don't surprise anyone who's expecting a '/'
2318  string dstr = d;
2319  if (dstr[dstr.size() - 1] != '/') {
2320  dstr += "/";
2321  }
2322  list->push_back(dstr);
2323 
2324  struct stat statbuf;
2325  if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) {
2326  // We found a dir that exists - we're done.
2327  return;
2328  }
2329  }
2330 
2331 #endif
2332 }
2333 
2334 static vector<string>* logging_directories_list;
2335 
2336 const vector<string>& GetLoggingDirectories() {
2337  // Not strictly thread-safe but we're called early in InitGoogle().
2338  if (logging_directories_list == NULL) {
2339  logging_directories_list = new vector<string>;
2340 
2341  if ( !FLAGS_log_dir.empty() ) {
2342  // A dir was specified, we should use it
2343  logging_directories_list->push_back(FLAGS_log_dir);
2344  } else {
2346 #ifdef GLOG_OS_WINDOWS
2347  char tmp[MAX_PATH];
2348  if (GetWindowsDirectoryA(tmp, MAX_PATH))
2349  logging_directories_list->push_back(tmp);
2350  logging_directories_list->push_back(".\\");
2351 #else
2352  logging_directories_list->push_back("./");
2353 #endif
2354  }
2355  }
2356  return *logging_directories_list;
2357 }
2358 
2360  fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
2361  "called from test code.\n");
2362  delete logging_directories_list;
2364 }
2365 
2366 void GetExistingTempDirectories(vector<string>* list) {
2367  GetTempDirectories(list);
2368  vector<string>::iterator i_dir = list->begin();
2369  while( i_dir != list->end() ) {
2370  // zero arg to access means test for existence; no constant
2371  // defined on windows
2372  if ( access(i_dir->c_str(), 0) ) {
2373  i_dir = list->erase(i_dir);
2374  } else {
2375  ++i_dir;
2376  }
2377  }
2378 }
2379 
2380 void TruncateLogFile(const char *path, uint64 limit, uint64 keep) {
2381 #ifdef HAVE_UNISTD_H
2382  struct stat statbuf;
2383  const int kCopyBlockSize = 8 << 10;
2384  char copybuf[kCopyBlockSize];
2385  off_t read_offset, write_offset;
2386  // Don't follow symlinks unless they're our own fd symlinks in /proc
2387  int flags = O_RDWR;
2388  // TODO(hamaji): Support other environments.
2389 #ifdef GLOG_OS_LINUX
2390  const char *procfd_prefix = "/proc/self/fd/";
2391  if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW;
2392 #endif
2393 
2394  int fd = open(path, flags);
2395  if (fd == -1) {
2396  if (errno == EFBIG) {
2397  // The log file in question has got too big for us to open. The
2398  // real fix for this would be to compile logging.cc (or probably
2399  // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's
2400  // rather scary.
2401  // Instead just truncate the file to something we can manage
2402  if (truncate(path, 0) == -1) {
2403  PLOG(ERROR) << "Unable to truncate " << path;
2404  } else {
2405  LOG(ERROR) << "Truncated " << path << " due to EFBIG error";
2406  }
2407  } else {
2408  PLOG(ERROR) << "Unable to open " << path;
2409  }
2410  return;
2411  }
2412 
2413  if (fstat(fd, &statbuf) == -1) {
2414  PLOG(ERROR) << "Unable to fstat()";
2415  goto out_close_fd;
2416  }
2417 
2418  // See if the path refers to a regular file bigger than the
2419  // specified limit
2420  if (!S_ISREG(statbuf.st_mode)) goto out_close_fd;
2421  if (statbuf.st_size <= static_cast<off_t>(limit)) goto out_close_fd;
2422  if (statbuf.st_size <= static_cast<off_t>(keep)) goto out_close_fd;
2423 
2424  // This log file is too large - we need to truncate it
2425  LOG(INFO) << "Truncating " << path << " to " << keep << " bytes";
2426 
2427  // Copy the last "keep" bytes of the file to the beginning of the file
2428  read_offset = statbuf.st_size - static_cast<off_t>(keep);
2429  write_offset = 0;
2430  ssize_t bytesin, bytesout;
2431  while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) {
2432  bytesout = pwrite(fd, copybuf, static_cast<size_t>(bytesin), write_offset);
2433  if (bytesout == -1) {
2434  PLOG(ERROR) << "Unable to write to " << path;
2435  break;
2436  } else if (bytesout != bytesin) {
2437  LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout;
2438  }
2439  read_offset += bytesin;
2440  write_offset += bytesout;
2441  }
2442  if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path;
2443 
2444  // Truncate the remainder of the file. If someone else writes to the
2445  // end of the file after our last read() above, we lose their latest
2446  // data. Too bad ...
2447  if (ftruncate(fd, write_offset) == -1) {
2448  PLOG(ERROR) << "Unable to truncate " << path;
2449  }
2450 
2451  out_close_fd:
2452  close(fd);
2453 #else
2454  LOG(ERROR) << "No log truncation support.";
2455 #endif
2456  }
2457 
2459 #ifdef HAVE_UNISTD_H
2460  uint64 limit = MaxLogSize() << 20U;
2461  uint64 keep = 1U << 20U;
2462  TruncateLogFile("/proc/self/fd/1", limit, keep);
2463  TruncateLogFile("/proc/self/fd/2", limit, keep);
2464 #else
2465  LOG(ERROR) << "No log truncation support.";
2466 #endif
2467 }
2468 
2469 
2470 // Helper functions for string comparisons.
2471 #define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
2472  string* Check##func##expected##Impl(const char* s1, const char* s2, \
2473  const char* names) { \
2474  bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
2475  if (equal == expected) return NULL; \
2476  else { \
2477  ostringstream ss; \
2478  if (!s1) s1 = ""; \
2479  if (!s2) s2 = ""; \
2480  ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
2481  return new string(ss.str()); \
2482  } \
2483  }
2484 DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
2485 DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
2486 DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
2487 DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
2488 #undef DEFINE_CHECK_STROP_IMPL
2489 
2490 int posix_strerror_r(int err, char *buf, size_t len) {
2491  // Sanity check input parameters
2492  if (buf == NULL || len <= 0) {
2493  errno = EINVAL;
2494  return -1;
2495  }
2496 
2497  // Reset buf and errno, and try calling whatever version of strerror_r()
2498  // is implemented by glibc
2499  buf[0] = '\000';
2500  int old_errno = errno;
2501  errno = 0;
2502  char *rc = reinterpret_cast<char *>(strerror_r(err, buf, len));
2503 
2504  // Both versions set errno on failure
2505  if (errno) {
2506  // Should already be there, but better safe than sorry
2507  buf[0] = '\000';
2508  return -1;
2509  }
2510  errno = old_errno;
2511 
2512  // POSIX is vague about whether the string will be terminated, although
2513  // is indirectly implies that typically ERANGE will be returned, instead
2514  // of truncating the string. This is different from the GNU implementation.
2515  // We play it safe by always terminating the string explicitly.
2516  buf[len-1] = '\000';
2517 
2518  // If the function succeeded, we can use its exit code to determine the
2519  // semantics implemented by glibc
2520  if (!rc) {
2521  return 0;
2522  } else {
2523  // GNU semantics detected
2524  if (rc == buf) {
2525  return 0;
2526  } else {
2527  buf[0] = '\000';
2528 #if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
2529  if (reinterpret_cast<intptr_t>(rc) < sys_nerr) {
2530  // This means an error on MacOSX or FreeBSD.
2531  return -1;
2532  }
2533 #endif
2534  strncat(buf, rc, len-1);
2535  return 0;
2536  }
2537  }
2538 }
2539 
2540 string StrError(int err) {
2541  char buf[100];
2542  int rc = posix_strerror_r(err, buf, sizeof(buf));
2543  if ((rc < 0) || (buf[0] == '\000')) {
2544  snprintf(buf, sizeof(buf), "Error number %d", err);
2545  }
2546  return buf;
2547 }
2548 
2549 LogMessageFatal::LogMessageFatal(const char* file, int line) :
2550  LogMessage(file, line, GLOG_FATAL) {}
2551 
2552 LogMessageFatal::LogMessageFatal(const char* file, int line,
2553  const CheckOpString& result) :
2554  LogMessage(file, line, result) {}
2555 
2556 LogMessageFatal::~LogMessageFatal() {
2557  Flush();
2558  LogMessage::Fail();
2559 }
2560 
2561 namespace base {
2562 
2563 CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext)
2564  : stream_(new ostringstream) {
2565  *stream_ << exprtext << " (";
2566 }
2567 
2568 CheckOpMessageBuilder::~CheckOpMessageBuilder() {
2569  delete stream_;
2570 }
2571 
2572 ostream* CheckOpMessageBuilder::ForVar2() {
2573  *stream_ << " vs. ";
2574  return stream_;
2575 }
2576 
2577 string* CheckOpMessageBuilder::NewString() {
2578  *stream_ << ")";
2579  return new string(stream_->str());
2580 }
2581 
2582 } // namespace base
2583 
2584 template <>
2585 void MakeCheckOpValueString(std::ostream* os, const char& v) {
2586  if (v >= 32 && v <= 126) {
2587  (*os) << "'" << v << "'";
2588  } else {
2589  (*os) << "char value " << static_cast<short>(v);
2590  }
2591 }
2592 
2593 template <>
2594 void MakeCheckOpValueString(std::ostream* os, const signed char& v) {
2595  if (v >= 32 && v <= 126) {
2596  (*os) << "'" << v << "'";
2597  } else {
2598  (*os) << "signed char value " << static_cast<short>(v);
2599  }
2600 }
2601 
2602 template <>
2603 void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) {
2604  if (v >= 32 && v <= 126) {
2605  (*os) << "'" << v << "'";
2606  } else {
2607  (*os) << "unsigned char value " << static_cast<unsigned short>(v);
2608  }
2609 }
2610 
2611 #if defined(HAVE_CXX11_NULLPTR_T) && __cplusplus >= 201103L
2612 template <>
2613 void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
2614  (*os) << "nullptr";
2615 }
2616 #endif // defined(HAVE_CXX11_NULLPTR_T)
2617 
2618 void InitGoogleLogging(const char* argv0) {
2620 }
2621 
2622 #ifdef GLOG_CUSTOM_PREFIX_SUPPORT
2623 void InitGoogleLogging(const char* argv0,
2624  CustomPrefixCallback prefix_callback,
2625  void* prefix_callback_data) {
2626  custom_prefix_callback = prefix_callback;
2627  custom_prefix_callback_data = prefix_callback_data;
2628  InitGoogleLogging(argv0);
2629 }
2630 #endif
2631 
2635  delete logging_directories_list;
2637 }
2638 
2639 void EnableLogCleaner(unsigned int overdue_days) {
2640  log_cleaner.Enable(overdue_days);
2641 }
2642 
2644  log_cleaner.Disable();
2645 }
2646 
2647 LogMessageTime::LogMessageTime()
2648  : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
2649 
2650 LogMessageTime::LogMessageTime(std::tm t) {
2651  std::time_t timestamp = std::mktime(&t);
2652  init(t, timestamp, 0);
2653 }
2654 
2655 LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
2656  std::tm t;
2657  if (FLAGS_log_utc_time)
2658  gmtime_r(&timestamp, &t);
2659  else
2660  localtime_r(&timestamp, &t);
2661  init(t, timestamp, now);
2662 }
2663 
2664 void LogMessageTime::init(const std::tm& t, std::time_t timestamp,
2665  WallTime now) {
2666  time_struct_ = t;
2667  timestamp_ = timestamp;
2668  usecs_ = static_cast<int32>((now - timestamp) * 1000000);
2669 
2670  CalcGmtOffset();
2671 }
2672 
2673 void LogMessageTime::CalcGmtOffset() {
2674  std::tm gmt_struct;
2675  int isDst = 0;
2676  if ( FLAGS_log_utc_time ) {
2677  localtime_r(&timestamp_, &gmt_struct);
2678  isDst = gmt_struct.tm_isdst;
2679  gmt_struct = time_struct_;
2680  } else {
2681  isDst = time_struct_.tm_isdst;
2682  gmtime_r(&timestamp_, &gmt_struct);
2683  }
2684 
2685  time_t gmt_sec = mktime(&gmt_struct);
2686  const long hour_secs = 3600;
2687  // If the Daylight Saving Time(isDst) is active subtract an hour from the current timestamp.
2688  gmtoffset_ = static_cast<long int>(timestamp_ - gmt_sec + (isDst ? hour_secs : 0) ) ;
2689 }
2690 
2691 _END_GOOGLE_NAMESPACE_
glog_internal_namespace_::CrashReason
Definition: utilities.h:193
LogMessage::LogMessageData::basename_
const char * basename_
Definition: logging.cc:381
LogDestination::SetStderrLogging
static void SetStderrLogging(LogSeverity min_severity)
Definition: logging.cc:719
LogMessage::LogMessageData::outvec_
std::vector< std::string > * outvec_
Definition: logging.cc:375
GetTempDirectories
static void GetTempDirectories(vector< string > *list)
Definition: logging.cc:2285
init
WEPOLL_INTERNAL int init(void)
Definition: wepoll.c:858
INFO
const int INFO
Definition: log_severity.h:59
LogDestination::MaybeLogToLogfile
static void MaybeLogToLogfile(LogSeverity severity, time_t timestamp, const char *message, size_t len)
Definition: logging.cc:861
localtime_r
struct tm * localtime_r(const time_t *timep, struct tm *result)
Definition: port.cc:52
data_
StringPiece data_
Definition: bytestream_unittest.cc:60
COLOR_RED
@ COLOR_RED
Definition: logging.cc:299
BoolFromEnv
static bool BoolFromEnv(const char *varname, bool defval)
Definition: logging.cc:108
gmtime_r
struct tm * gmtime_r(const time_t *timep, struct tm *result)
Definition: port.cc:58
MUTEX_NAMESPACE::MutexLock
Definition: glog/src/base/mutex.h:288
glog_internal_namespace_::PidHasChanged
bool PidHasChanged()
Definition: utilities.cc:250
glog_internal_namespace_::CrashReason::message
const char * message
Definition: utilities.h:198
LogDestination::SetLogDestination
static void SetLogDestination(LogSeverity severity, const char *base_filename)
Definition: logging.cc:675
fatal_time
static time_t fatal_time
Definition: logging.cc:1805
COLOR_YELLOW
@ COLOR_YELLOW
Definition: logging.cc:301
GLOG_DEFINE_string
GLOG_DEFINE_string(alsologtoemail, "", "log messages go to these email addresses " "in addition to logfiles")
LogDestination::MaybeLogToStderr
static void MaybeLogToStderr(LogSeverity severity, const char *message, size_t message_len, size_t prefix_len)
Definition: logging.cc:809
operator<<
ostream & operator<<(ostream &os, const PRIVATE_Counter &)
Definition: logging.cc:2035
LogDestination::kNetworkBytes
static const int kNetworkBytes
Definition: logging.cc:549
Fail
void Fail(const char *msg)
Definition: gtest_assert_by_exception_test.cc:52
stream
GLuint GLuint stream
Definition: glcorearb.h:3946
NULL
NULL
Definition: test_security_zap.cpp:405
LogDestination::LogToStderr
static void LogToStderr()
Definition: logging.cc:727
src
GLenum src
Definition: glcorearb.h:3364
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
posix_strerror_r
int posix_strerror_r(int err, char *buf, size_t len)
Definition: logging.cc:2490
glog_internal_namespace_::ProgramInvocationShortName
const char * ProgramInvocationShortName()
Definition: utilities.cc:189
ERROR
const int ERROR
Definition: log_severity.h:60
glog_internal_namespace_::ShutdownGoogleLoggingUtilities
void ShutdownGoogleLoggingUtilities()
Definition: utilities.cc:378
googleinit.h
LogMessage::LogMessageData::sink_
LogSink * sink_
Definition: logging.cc:374
LogMessage
log_mutex
static Mutex log_mutex
Definition: logging.cc:396
base
Definition: logging.cc:2162
EINVAL
#define EINVAL
Definition: errno.hpp:25
LogMessage::LogMessageData::message_
std::string * message_
Definition: logging.cc:376
LogMessage::LogMessageData::num_chars_to_log_
size_t num_chars_to_log_
Definition: logging.cc:379
LogDestination::hostname_
static string hostname_
Definition: logging.cc:601
ReprintFatalMessage
void ReprintFatalMessage()
Definition: logging.cc:1808
LogDestination::SetLogSymlink
static void SetLogSymlink(LogSeverity severity, const char *symlink_basename)
Definition: logging.cc:684
LogMessage::LogMessageData::severity_
char severity_
Definition: logging.cc:370
LogMessage::LogMessageData::send_method_
void(LogMessage::* send_method_)()
Definition: logging.cc:372
StrError
string StrError(int err)
Definition: logging.cc:2540
LogDestination::LogDestination
LogDestination(LogSeverity severity, const char *base_filename)
Definition: logging.cc:637
readdir
static struct dirent * readdir(DIR *dirp)
Definition: dirent.h:732
MUTEX_NAMESPACE::Mutex::Unlock
void Unlock()
glog_internal_namespace_::WallTime_Now
WallTime WallTime_Now()
Definition: utilities.cc:240
LogDestination::SetLogger
friend void base::SetLogger(LogSeverity, base::Logger *)
ColoredWriteToStderr
static void ColoredWriteToStderr(LogSeverity severity, const char *message, size_t len)
Definition: logging.cc:798
TerminalSupportsColor
static bool TerminalSupportsColor()
Definition: logging.cc:269
ARRAYSIZE
#define ARRAYSIZE(a)
Definition: utilities.h:128
LogDestination::LogToAllLogfiles
static void LogToAllLogfiles(LogSeverity severity, time_t timestamp, const char *message, size_t len)
Definition: logging.cc:870
dirent::d_name
char d_name[PATH_MAX+1]
Definition: dirent.h:278
TestOnly_ClearLoggingDirectoriesList
void TestOnly_ClearLoggingDirectoriesList()
Definition: logging.cc:2359
GLOG_INFO
const int GLOG_INFO
Definition: log_severity.h:53
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
MakeCheckOpValueString
void MakeCheckOpValueString(std::ostream *os, const char &v)
Definition: logging.cc:2585
color
GLuint color
Definition: glcorearb.h:3267
LogDestination::terminal_supports_color_
static bool terminal_supports_color_
Definition: logging.cc:602
pread
static ssize_t pread(int fd, void *buf, size_t count, off_t offset)
Definition: logging.cc:215
LogDestination::SetLogFilenameExtension
static void SetLogFilenameExtension(const char *filename_extension)
Definition: logging.cc:710
FlushLogFilesUnsafe
void FlushLogFilesUnsafe(LogSeverity min_severity)
Definition: logging.cc:2063
LogSeverity
int LogSeverity
Definition: log_severity.h:51
google::protobuf::python::cmessage::Init
static int Init(CMessage *self, PyObject *args, PyObject *kwargs)
Definition: python/google/protobuf/pyext/message.cc:1286
LogDestination::SetEmailLogging
static void SetEmailLogging(LogSeverity min_severity, const char *addresses)
Definition: logging.cc:736
crash_reason
static CrashReason crash_reason
Definition: logging.cc:1535
glog_internal_namespace_::CrashReason::stack
void * stack[32]
Definition: utilities.h:202
glog_internal_namespace_
Definition: logging_custom_prefix_unittest.cc:1003
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
LogDestination::log_destinations_
static LogDestination * log_destinations_[NUM_SEVERITIES]
Definition: logging.cc:598
RemoveLogSink
void RemoveLogSink(LogSink *destination)
Definition: logging.cc:2142
errno
int errno
FlushLogFiles
void FlushLogFiles(LogSeverity min_severity)
Definition: logging.cc:2059
sys_nerr
#define sys_nerr
Definition: errno.hpp:50
LogMessage::LogMessageData::fullname_
const char * fullname_
Definition: logging.cc:382
GetStackTrace
_START_GOOGLE_NAMESPACE_ GLOG_EXPORT int GetStackTrace(void **result, int max_depth, int skip_count)
Definition: stacktrace_generic-inl.h:41
conformance_python.stdout
stdout
Definition: conformance_python.py:50
severity
GLenum GLuint GLenum severity
Definition: glcorearb.h:2695
LogMessage::LogMessageData::num_chars_to_syslog_
size_t num_chars_to_syslog_
Definition: logging.cc:380
EnableLogCleaner
void EnableLogCleaner(unsigned int overdue_days)
Definition: logging.cc:2639
LogMessage::LogMessageData::message_text_
char message_text_[LogMessage::kMaxLogMessageLen+1]
Definition: logging.cc:368
send
void send(fd_t fd_, const char(&data_)[N])
Definition: test_security_curve.cpp:209
GLOG_EXPORT
#define GLOG_EXPORT
Definition: glog/src/googletest.h:76
MUTEX_NAMESPACE::Mutex
Definition: glog/src/base/mutex.h:159
glog_internal_namespace_::CrashReason::filename
const char * filename
Definition: utilities.h:196
glog_internal_namespace_::GetTID
pid_t GetTID()
Definition: utilities.cc:259
fatal_msg_data_shared
static LogMessage::LogMessageData fatal_msg_data_shared
Definition: logging.cc:1538
closedir
static int closedir(DIR *dirp)
Definition: dirent.h:843
flags
GLbitfield flags
Definition: glcorearb.h:3585
SendEmailInternal
static bool SendEmailInternal(const char *dest, const char *subject, const char *body, bool use_logging)
Definition: logging.cc:2229
MaxLogSize
static uint32 MaxLogSize()
Definition: logging.cc:353
S_ISREG
#define S_ISREG(mode)
Definition: dirent.h:193
ok
ROSCPP_DECL bool ok()
MUTEX_NAMESPACE::ReaderMutexLock
Definition: glog/src/base/mutex.h:300
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:4174
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
LogDestination::MaybeLogToEmail
static void MaybeLogToEmail(LogSeverity severity, const char *message, size_t len)
Definition: logging.cc:835
access
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:4266
GetAnsiColorCode
static const char * GetAnsiColorCode(GLogColor color)
Definition: logging.cc:340
LogDestination::hostname
static const string & hostname()
Definition: logging.cc:627
snprintf
int snprintf(char *str, size_t size, const char *format,...)
Definition: port.cc:64
glog_internal_namespace_::SetCrashReason
void SetCrashReason(const CrashReason *r)
Definition: utilities.cc:358
MUTEX_NAMESPACE::Mutex::AssertHeld
void AssertHeld()
Definition: glog/src/base/mutex.h:185
stop_writing
static bool stop_writing
Definition: logging.cc:402
dirent.h
glog_internal_namespace_::CrashReason::line_number
int line_number
Definition: utilities.h:197
GLOG_DEFINE_int32
GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " "actually get logged anywhere")
DEFINE_CHECK_STROP_IMPL
#define DEFINE_CHECK_STROP_IMPL(name, func, expected)
Definition: logging.cc:2471
SetEmailLogging
void SetEmailLogging(LogSeverity min_severity, const char *addresses)
Definition: logging.cc:2154
DefaultLogDir
static const char * DefaultLogDir()
Definition: logging.cc:173
COLOR_GREEN
@ COLOR_GREEN
Definition: logging.cc:300
path
GLsizei const GLchar ** path
Definition: glcorearb.h:3658
CHECK_LT
#define CHECK_LT(a, b)
Definition: check.h:70
offset
GLintptr offset
Definition: glcorearb.h:2944
fatal_message
static char fatal_message[256]
Definition: logging.cc:1806
LogDestination::fileobject_
LogFileObject fileobject_
Definition: logging.cc:595
LogDestination::sinks_
static vector< LogSink * > * sinks_
Definition: logging.cc:605
GLOG_DEFINE_bool
GLOG_DEFINE_bool(timestamp_in_logfile_name, BoolFromEnv("GOOGLE_TIMESTAMP_IN_LOGFILE_NAME", true), "put a timestamp at the end of the log file name")
start
GLuint start
Definition: glcorearb.h:2858
GLogColor
GLogColor
Definition: logging.cc:297
LogDestination::operator=
LogDestination & operator=(const LogDestination &)
exit_on_dfatal
static bool exit_on_dfatal
Definition: logging.cc:409
LogDestination
Definition: logging.cc:524
glog_internal_namespace_::CrashReason::depth
int depth
Definition: utilities.h:203
LogDestination::GetLogger
friend base::Logger * base::GetLogger(LogSeverity)
dirent
Definition: dirent.h:261
glog_internal_namespace_::CycleClock_Now
int64 CycleClock_Now()
Definition: utilities.cc:229
ColoredWriteToStdout
static void ColoredWriteToStdout(LogSeverity severity, const char *message, size_t len)
Definition: logging.cc:787
SetLogSymlink
void SetLogSymlink(LogSeverity severity, const char *symlink_basename)
Definition: logging.cc:2071
LogSeverityNames
const char *const LogSeverityNames[NUM_SEVERITIES]
Definition: logging.cc:404
LogDestination::email_logging_severity_
static LogSeverity email_logging_severity_
Definition: logging.cc:599
SendEmail
bool SendEmail(const char *dest, const char *subject, const char *body)
Definition: logging.cc:2281
GetExistingTempDirectories
void GetExistingTempDirectories(vector< string > *list)
Definition: logging.cc:2366
err
static UPB_NORETURN void err(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5856
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
LogDestination::~LogDestination
~LogDestination()
Definition: logging.cc:643
CHECK
#define CHECK(x)
Definition: php/ext/google/protobuf/upb.c:8393
FLAGS_logtostderr
static int FLAGS_logtostderr
Definition: sdk/include/aditof/log.h:67
fatal_msg_exclusive
static bool fatal_msg_exclusive
Definition: logging.cc:1536
d
d
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:4175
glog_internal_namespace_::InitGoogleLoggingUtilities
void InitGoogleLoggingUtilities(const char *argv0)
Definition: utilities.cc:364
S_ISDIR
#define S_ISDIR(mode)
Definition: dirent.h:190
WriteToStderr
static void WriteToStderr(const char *message, size_t len)
Definition: logging.cc:803
commandlineflags.h
utilities.h
GLOG_WARNING
const int GLOG_WARNING
Definition: log_severity.h:53
void
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
n
GLdouble n
Definition: glcorearb.h:4153
AddLogSink
void AddLogSink(LogSink *destination)
Definition: logging.cc:2138
i
int i
Definition: gmock-matchers_test.cc:764
DisableLogCleaner
void DisableLogCleaner()
Definition: logging.cc:2643
LogMessage::LogMessageData::preserved_errno_
int preserved_errno_
Definition: logging.cc:366
LogDestination::LogToSinks
static void LogToSinks(LogSeverity severity, const char *full_filename, const char *base_filename, int line, const LogMessageTime &logmsgtime, const char *message, size_t message_len)
Definition: logging.cc:885
type
GLenum type
Definition: glcorearb.h:2695
base::internal::GetExitOnDFatal
bool GetExitOnDFatal()
Definition: logging.cc:2166
LogDestination::WaitForSinks
static void WaitForSinks(LogMessage::LogMessageData *data)
Definition: logging.cc:900
LOG
#define LOG(x)
Definition: sdk/include/aditof/log.h:72
testing::internal::posix::Write
int Write(int fd, const void *buf, unsigned int count)
Definition: gtest-port.h:2129
base::internal::SetExitOnDFatal
void SetExitOnDFatal(bool value)
Definition: logging.cc:2182
TruncateLogFile
void TruncateLogFile(const char *path, uint64 limit, uint64 keep)
Definition: logging.cc:2380
LogDestination::log_destination
static LogDestination * log_destination(LogSeverity severity)
Definition: logging.cc:917
_START_GOOGLE_NAMESPACE_
Definition: signalhandler.cc:51
len
int len
Definition: php/ext/google/protobuf/map.c:206
LogMessage::LogMessageData::first_fatal_
bool first_fatal_
Definition: logging.cc:384
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(mu)
Definition: logging.cc:106
logging_directories_list
static vector< string > * logging_directories_list
Definition: logging.cc:2334
v
const GLdouble * v
Definition: glcorearb.h:3106
InstallFailureFunction
void InstallFailureFunction(logging_fail_func_t fail_func)
Definition: logging.cc:1941
DIR
Definition: dirent.h:282
LogDestination::addresses_
static string addresses_
Definition: logging.cc:600
LogDestination::AddLogSink
static void AddLogSink(LogSink *destination)
Definition: logging.cc:692
googletest-break-on-failure-unittest.Run
def Run(command)
Definition: googletest-break-on-failure-unittest.py:76
glog_internal_namespace_::DumpStackTraceToString
void DumpStackTraceToString(std::string *stacktrace)
GetHostName
static void GetHostName(string *hostname)
Definition: logging.cc:246
IsGoogleLoggingInitialized
bool IsGoogleLoggingInitialized()
Definition: utilities.cc:69
benchmarks.python.py_benchmark.dest
dest
Definition: py_benchmark.py:13
LogMessage::LogMessageData::stream_
LogStream stream_
Definition: logging.cc:369
LogMessage::LogMessageData::line_
int line_
Definition: logging.cc:371
g_logging_fail_func
GLOG_EXPORT logging_fail_func_t g_logging_fail_func
Definition: logging.cc:1938
FLAGS_alsologtostderr
static int FLAGS_alsologtostderr
Definition: sdk/include/aditof/log.h:66
SetStderrLogging
void SetStderrLogging(LogSeverity min_severity)
Definition: logging.cc:2150
fatal_msg_lock
static Mutex fatal_msg_lock
Definition: logging.cc:1534
SeverityToColor
static GLogColor SeverityToColor(LogSeverity severity)
Definition: logging.cc:304
VLOG
#define VLOG(x)
Definition: protobuf/third_party/benchmark/src/log.h:69
stacktrace.h
HANDLE
void * HANDLE
Definition: wepoll.c:70
LogDestination::DeleteLogDestinations
static void DeleteLogDestinations()
Definition: logging.cc:925
glog_internal_namespace_::GetMainThreadPid
int32 GetMainThreadPid()
Definition: utilities.cc:246
GLOG_FATAL
const int GLOG_FATAL
Definition: log_severity.h:53
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
LogMessage::LogMessageData::LogMessageData
LogMessageData()
Definition: logging.cc:1556
SetLogDestination
void SetLogDestination(LogSeverity severity, const char *base_filename)
Definition: logging.cc:2067
LogDestination::sink_mutex_
static Mutex sink_mutex_
Definition: logging.cc:609
LogToStderr
void LogToStderr()
Definition: logging.cc:2158
DEFINE_int32
DEFINE_int32(stderrthreshold, GOOGLE_NAMESPACE::GLOG_ERROR, "log messages at or above this level are copied to stderr in " "addition to logfiles. This flag obsoletes --alsologtostderr.")
true
#define true
Definition: cJSON.c:65
LogMessage::LogMessageData::has_been_flushed_
bool has_been_flushed_
Definition: logging.cc:383
opendir
static DIR * opendir(const char *dirname)
Definition: dirent.h:676
internal
Definition: any.pb.h:40
GLOG_ERROR
const int GLOG_ERROR
Definition: log_severity.h:53
COLOR_DEFAULT
@ COLOR_DEFAULT
Definition: logging.cc:298
SetApplicationFingerprint
void SetApplicationFingerprint(const std::string &fingerprint)
Definition: logging.cc:941
LogDestination::FlushLogFiles
static void FlushLogFiles(int min_severity)
Definition: logging.cc:663
ShutdownGoogleLogging
void ShutdownGoogleLogging()
Definition: logging.cc:2632
next
static size_t next(const upb_table *t, size_t i)
Definition: php/ext/google/protobuf/upb.c:4889
LogDestination::logger_
base::Logger * logger_
Definition: logging.cc:596
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
glog_internal_namespace_::const_basename
const char * const_basename(const char *filepath)
Definition: utilities.cc:304
fatal_msg_data_exclusive
static LogMessage::LogMessageData fatal_msg_data_exclusive
Definition: logging.cc:1537
glog_internal_namespace_::UsecToCycles
int64 UsecToCycles(int64 usec)
Definition: utilities.cc:236
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
w
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:3126
LogDestination::terminal_supports_color
static const bool & terminal_supports_color()
Definition: logging.cc:552
PATH_SEPARATOR
#define PATH_SEPARATOR
Definition: logging.cc:208
count
GLint GLsizei count
Definition: glcorearb.h:2830
kDontNeedShellEscapeChars
static const char kDontNeedShellEscapeChars[]
Definition: logging.cc:2191
false
#define false
Definition: cJSON.c:70
ShellEscape
static string ShellEscape(const string &src)
Definition: logging.cc:2196
SetLogFilenameExtension
void SetLogFilenameExtension(const char *ext)
Definition: logging.cc:2146
InitGoogleLogging
void InitGoogleLogging(const char *argv0)
Definition: logging.cc:2618
LogDestination::FlushLogFilesUnsafe
static void FlushLogFilesUnsafe(int min_severity)
Definition: logging.cc:650
LogMessage::LogMessageData::num_prefix_chars_
size_t num_prefix_chars_
Definition: logging.cc:378
CHECK_GE
#define CHECK_GE(a, b)
Definition: check.h:67
GetLoggingDirectories
const vector< string > & GetLoggingDirectories()
Definition: logging.cc:2336
file_
FileDescriptorProto * file_
Definition: annotation_test_util.cc:68
GetLogSeverityName
const char * GetLogSeverityName(LogSeverity severity)
Definition: logging.cc:411
LogMessage::LogMessageData::operator=
void operator=(const LogMessageData &)
LogMessage::LogMessageData
Definition: logging.cc:363
pwrite
static ssize_t pwrite(int fd, void *buf, size_t count, off_t offset)
Definition: logging.cc:231
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
GLOG_DEFINE_uint32
GLOG_DEFINE_uint32(max_log_size, 1800, "approx. maximum log file size (in MB). A value of 0 will " "be silently overridden to 1.")
LogDestination::ReprintFatalMessage
friend void ReprintFatalMessage()
Definition: logging.cc:1808
NUM_SEVERITIES
const int NUM_SEVERITIES
Definition: log_severity.h:54
ColoredWriteToStderrOrStdout
static void ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity, const char *message, size_t len)
Definition: logging.cc:746
TruncateStdoutStderr
void TruncateStdoutStderr()
Definition: logging.cc:2458
LogDestination::RemoveLogSink
static void RemoveLogSink(LogSink *destination)
Definition: logging.cc:700
glog_internal_namespace_::MyUserName
const string & MyUserName()
Definition: utilities.cc:314


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:55