/thirdparty/breakpad/third_party/glog/src/logging.cc
C++ | 1808 lines | 1341 code | 202 blank | 265 comment | 176 complexity | cf7b2eac37b87263cb124fcaed0d9042 MD5 | raw 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 <assert.h> 35#include <iomanip> 36#include <string> 37#ifdef HAVE_UNISTD_H 38# include <unistd.h> // For _exit. 39#endif 40#include <climits> 41#include <sys/types.h> 42#include <sys/stat.h> 43#ifdef HAVE_SYS_UTSNAME_H 44# include <sys/utsname.h> // For uname. 45#endif 46#include <fcntl.h> 47#include <cstdio> 48#include <iostream> 49#include <stdarg.h> 50#include <stdlib.h> 51#ifdef HAVE_PWD_H 52# include <pwd.h> 53#endif 54#ifdef HAVE_SYSLOG_H 55# include <syslog.h> 56#endif 57#include <vector> 58#include <errno.h> // for errno 59#include <sstream> 60#include "base/commandlineflags.h" // to get the program name 61#include "glog/logging.h" 62#include "glog/raw_logging.h" 63#include "base/googleinit.h" 64 65#ifdef HAVE_STACKTRACE 66# include "stacktrace.h" 67#endif 68 69using std::string; 70using std::vector; 71using std::ostrstream; 72using std::setw; 73using std::setfill; 74using std::hex; 75using std::dec; 76using std::min; 77using std::ostream; 78using std::ostringstream; 79using std::strstream; 80 81// There is no thread annotation support. 82#define EXCLUSIVE_LOCKS_REQUIRED(mu) 83 84static bool BoolFromEnv(const char *varname, bool defval) { 85 const char* const valstr = getenv(varname); 86 if (!valstr) { 87 return defval; 88 } 89 return memchr("tTyY1\0", valstr[0], 6) != NULL; 90} 91 92GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), 93 "log messages go to stderr instead of logfiles"); 94GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), 95 "log messages go to stderr in addition to logfiles"); 96#ifdef OS_LINUX 97GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " 98 "Logs can grow very quickly and they are rarely read before they " 99 "need to be evicted from memory. Instead, drop them from memory " 100 "as soon as they are flushed to disk."); 101_START_GOOGLE_NAMESPACE_ 102namespace logging { 103static const int64 kPageSize = getpagesize(); 104} 105_END_GOOGLE_NAMESPACE_ 106#endif 107 108// By default, errors (including fatal errors) get logged to stderr as 109// well as the file. 110// 111// The default is ERROR instead of FATAL so that users can see problems 112// when they run a program without having to look in another file. 113DEFINE_int32(stderrthreshold, 114 GOOGLE_NAMESPACE::ERROR, 115 "log messages at or above this level are copied to stderr in " 116 "addition to logfiles. This flag obsoletes --alsologtostderr."); 117 118GLOG_DEFINE_string(alsologtoemail, "", 119 "log messages go to these email addresses " 120 "in addition to logfiles"); 121GLOG_DEFINE_bool(log_prefix, true, 122 "Prepend the log prefix to the start of each log line"); 123GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " 124 "actually get logged anywhere"); 125GLOG_DEFINE_int32(logbuflevel, 0, 126 "Buffer log messages logged at this level or lower" 127 " (-1 means don't buffer; 0 means buffer INFO only;" 128 " ...)"); 129GLOG_DEFINE_int32(logbufsecs, 30, 130 "Buffer log messages for at most this many seconds"); 131GLOG_DEFINE_int32(logemaillevel, 999, 132 "Email log messages logged at this level or higher" 133 " (0 means email all; 3 means email FATAL only;" 134 " ...)"); 135GLOG_DEFINE_string(logmailer, "/bin/mail", 136 "Mailer used to send logging email"); 137 138// Compute the default value for --log_dir 139static const char* DefaultLogDir() { 140 const char* env; 141 env = getenv("GOOGLE_LOG_DIR"); 142 if (env != NULL && env[0] != '\0') { 143 return env; 144 } 145 env = getenv("TEST_TMPDIR"); 146 if (env != NULL && env[0] != '\0') { 147 return env; 148 } 149 return ""; 150} 151 152GLOG_DEFINE_string(log_dir, DefaultLogDir(), 153 "If specified, logfiles are written into this directory instead " 154 "of the default logging directory."); 155GLOG_DEFINE_string(log_link, "", "Put additional links to the log " 156 "files in this directory"); 157 158GLOG_DEFINE_int32(max_log_size, 1800, 159 "approx. maximum log file size (in MB). A value of 0 will " 160 "be silently overridden to 1."); 161 162GLOG_DEFINE_bool(stop_logging_if_full_disk, false, 163 "Stop attempting to log to disk if the disk is full."); 164 165GLOG_DEFINE_string(log_backtrace_at, "", 166 "Emit a backtrace when logging at file:linenum."); 167 168// TODO(hamaji): consider windows 169#define PATH_SEPARATOR '/' 170 171static void GetHostName(string* hostname) { 172#if defined(HAVE_SYS_UTSNAME_H) 173 struct utsname buf; 174 if (0 != uname(&buf)) { 175 // ensure null termination on failure 176 *buf.nodename = '\0'; 177 } 178 *hostname = buf.nodename; 179#elif defined(OS_WINDOWS) 180 char buf[MAX_COMPUTERNAME_LENGTH + 1]; 181 DWORD len = MAX_COMPUTERNAME_LENGTH + 1; 182 if (GetComputerNameA(buf, &len)) { 183 *hostname = buf; 184 } else { 185 hostname->clear(); 186 } 187#else 188# warning There is no way to retrieve the host name. 189 *hostname = "(unknown)"; 190#endif 191} 192 193_START_GOOGLE_NAMESPACE_ 194 195// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 196static int32 MaxLogSize() { 197 return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); 198} 199 200// A mutex that allows only one thread to log at a time, to keep things from 201// getting jumbled. Some other very uncommon logging operations (like 202// changing the destination file for log messages of a given severity) also 203// lock this mutex. Please be sure that anybody who might possibly need to 204// lock it does so. 205static Mutex log_mutex; 206 207// Number of messages sent at each severity. Under log_mutex. 208int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; 209 210// Globally disable log writing (if disk is full) 211static bool stop_writing = false; 212 213const char*const LogSeverityNames[NUM_SEVERITIES] = { 214 "INFO", "WARNING", "ERROR", "FATAL" 215}; 216 217// Has the user called SetExitOnDFatal(true)? 218static bool exit_on_dfatal = true; 219 220const char* GetLogSeverityName(LogSeverity severity) { 221 return LogSeverityNames[severity]; 222} 223 224static bool SendEmailInternal(const char*dest, const char *subject, 225 const char*body, bool use_logging); 226 227base::Logger::~Logger() { 228} 229 230namespace { 231 232// Encapsulates all file-system related state 233class LogFileObject : public base::Logger { 234 public: 235 LogFileObject(LogSeverity severity, const char* base_filename); 236 ~LogFileObject(); 237 238 virtual void Write(bool force_flush, // Should we force a flush here? 239 time_t timestamp, // Timestamp for this entry 240 const char* message, 241 int message_len); 242 243 // Configuration options 244 void SetBasename(const char* basename); 245 void SetExtension(const char* ext); 246 void SetSymlinkBasename(const char* symlink_basename); 247 248 // Normal flushing routine 249 virtual void Flush(); 250 251 // It is the actual file length for the system loggers, 252 // i.e., INFO, ERROR, etc. 253 virtual uint32 LogSize() { 254 MutexLock l(&lock_); 255 return file_length_; 256 } 257 258 // Internal flush routine. Exposed so that FlushLogFilesUnsafe() 259 // can avoid grabbing a lock. Usually Flush() calls it after 260 // acquiring lock_. 261 void FlushUnlocked(); 262 263 private: 264 static const uint32 kRolloverAttemptFrequency = 0x20; 265 266 Mutex lock_; 267 bool base_filename_selected_; 268 string base_filename_; 269 string symlink_basename_; 270 string filename_extension_; // option users can specify (eg to add port#) 271 FILE* file_; 272 LogSeverity severity_; 273 uint32 bytes_since_flush_; 274 uint32 file_length_; 275 unsigned int rollover_attempt_; 276 int64 next_flush_time_; // cycle count at which to flush log 277 278 // Actually create a logfile using the value of base_filename_ and the 279 // supplied argument time_pid_string 280 // REQUIRES: lock_ is held 281 bool CreateLogfile(const char* time_pid_string); 282}; 283 284} // namespace 285 286class LogDestination { 287 public: 288 friend class LogMessage; 289 friend void ReprintFatalMessage(); 290 friend base::Logger* base::GetLogger(LogSeverity); 291 friend void base::SetLogger(LogSeverity, base::Logger*); 292 293 // These methods are just forwarded to by their global versions. 294 static void SetLogDestination(LogSeverity severity, 295 const char* base_filename); 296 static void SetLogSymlink(LogSeverity severity, 297 const char* symlink_basename); 298 static void AddLogSink(LogSink *destination); 299 static void RemoveLogSink(LogSink *destination); 300 static void SetLogFilenameExtension(const char* filename_extension); 301 static void SetStderrLogging(LogSeverity min_severity); 302 static void SetEmailLogging(LogSeverity min_severity, const char* addresses); 303 static void LogToStderr(); 304 // Flush all log files that are at least at the given severity level 305 static void FlushLogFiles(int min_severity); 306 static void FlushLogFilesUnsafe(int min_severity); 307 308 // we set the maximum size of our packet to be 1400, the logic being 309 // to prevent fragmentation. 310 // Really this number is arbitrary. 311 static const int kNetworkBytes = 1400; 312 313 static const string& hostname(); 314 315 static void DeleteLogDestinations(); 316 317 private: 318 LogDestination(LogSeverity severity, const char* base_filename); 319 ~LogDestination() { } 320 321 // Take a log message of a particular severity and log it to stderr 322 // iff it's of a high enough severity to deserve it. 323 static void MaybeLogToStderr(LogSeverity severity, const char* message, 324 size_t len); 325 326 // Take a log message of a particular severity and log it to email 327 // iff it's of a high enough severity to deserve it. 328 static void MaybeLogToEmail(LogSeverity severity, const char* message, 329 size_t len); 330 // Take a log message of a particular severity and log it to a file 331 // iff the base filename is not "" (which means "don't log to me") 332 static void MaybeLogToLogfile(LogSeverity severity, 333 time_t timestamp, 334 const char* message, size_t len); 335 // Take a log message of a particular severity and log it to the file 336 // for that severity and also for all files with severity less than 337 // this severity. 338 static void LogToAllLogfiles(LogSeverity severity, 339 time_t timestamp, 340 const char* message, size_t len); 341 342 // Send logging info to all registered sinks. 343 static void LogToSinks(LogSeverity severity, 344 const char *full_filename, 345 const char *base_filename, 346 int line, 347 const struct ::tm* tm_time, 348 const char* message, 349 size_t message_len); 350 351 // Wait for all registered sinks via WaitTillSent 352 // including the optional one in "data". 353 static void WaitForSinks(LogMessage::LogMessageData* data); 354 355 static LogDestination* log_destination(LogSeverity severity); 356 357 LogFileObject fileobject_; 358 base::Logger* logger_; // Either &fileobject_, or wrapper around it 359 360 static LogDestination* log_destinations_[NUM_SEVERITIES]; 361 static LogSeverity email_logging_severity_; 362 static string addresses_; 363 static string hostname_; 364 365 // arbitrary global logging destinations. 366 static vector<LogSink*>* sinks_; 367 368 // Protects the vector sinks_, 369 // but not the LogSink objects its elements reference. 370 static Mutex sink_mutex_; 371 372 // Disallow 373 LogDestination(const LogDestination&); 374 LogDestination& operator=(const LogDestination&); 375}; 376 377// Errors do not get logged to email by default. 378LogSeverity LogDestination::email_logging_severity_ = 99999; 379 380string LogDestination::addresses_; 381string LogDestination::hostname_; 382 383vector<LogSink*>* LogDestination::sinks_ = NULL; 384Mutex LogDestination::sink_mutex_; 385 386/* static */ 387const string& LogDestination::hostname() { 388 if (hostname_.empty()) { 389 GetHostName(&hostname_); 390 if (hostname_.empty()) { 391 hostname_ = "(unknown)"; 392 } 393 } 394 return hostname_; 395} 396 397LogDestination::LogDestination(LogSeverity severity, 398 const char* base_filename) 399 : fileobject_(severity, base_filename), 400 logger_(&fileobject_) { 401} 402 403inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { 404 // assume we have the log_mutex or we simply don't care 405 // about it 406 for (int i = min_severity; i < NUM_SEVERITIES; i++) { 407 LogDestination* log = log_destination(i); 408 if (log != NULL) { 409 // Flush the base fileobject_ logger directly instead of going 410 // through any wrappers to reduce chance of deadlock. 411 log->fileobject_.FlushUnlocked(); 412 } 413 } 414} 415 416inline void LogDestination::FlushLogFiles(int min_severity) { 417 // Prevent any subtle race conditions by wrapping a mutex lock around 418 // all this stuff. 419 MutexLock l(&log_mutex); 420 for (int i = min_severity; i < NUM_SEVERITIES; i++) { 421 LogDestination* log = log_destination(i); 422 if (log != NULL) { 423 log->logger_->Flush(); 424 } 425 } 426} 427 428inline void LogDestination::SetLogDestination(LogSeverity severity, 429 const char* base_filename) { 430 assert(severity >= 0 && severity < NUM_SEVERITIES); 431 // Prevent any subtle race conditions by wrapping a mutex lock around 432 // all this stuff. 433 MutexLock l(&log_mutex); 434 log_destination(severity)->fileobject_.SetBasename(base_filename); 435} 436 437inline void LogDestination::SetLogSymlink(LogSeverity severity, 438 const char* symlink_basename) { 439 CHECK_GE(severity, 0); 440 CHECK_LT(severity, NUM_SEVERITIES); 441 MutexLock l(&log_mutex); 442 log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename); 443} 444 445inline void LogDestination::AddLogSink(LogSink *destination) { 446 // Prevent any subtle race conditions by wrapping a mutex lock around 447 // all this stuff. 448 MutexLock l(&sink_mutex_); 449 if (!sinks_) sinks_ = new vector<LogSink*>; 450 sinks_->push_back(destination); 451} 452 453inline void LogDestination::RemoveLogSink(LogSink *destination) { 454 // Prevent any subtle race conditions by wrapping a mutex lock around 455 // all this stuff. 456 MutexLock l(&sink_mutex_); 457 // This doesn't keep the sinks in order, but who cares? 458 if (sinks_) { 459 for (int i = sinks_->size() - 1; i >= 0; i--) { 460 if ((*sinks_)[i] == destination) { 461 (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; 462 sinks_->pop_back(); 463 break; 464 } 465 } 466 } 467} 468 469inline void LogDestination::SetLogFilenameExtension(const char* ext) { 470 // Prevent any subtle race conditions by wrapping a mutex lock around 471 // all this stuff. 472 MutexLock l(&log_mutex); 473 for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) { 474 log_destination(severity)->fileobject_.SetExtension(ext); 475 } 476} 477 478inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { 479 assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); 480 // Prevent any subtle race conditions by wrapping a mutex lock around 481 // all this stuff. 482 MutexLock l(&log_mutex); 483 FLAGS_stderrthreshold = min_severity; 484} 485 486inline void LogDestination::LogToStderr() { 487 // *Don't* put this stuff in a mutex lock, since SetStderrLogging & 488 // SetLogDestination already do the locking! 489 SetStderrLogging(0); // thus everything is "also" logged to stderr 490 for ( int i = 0; i < NUM_SEVERITIES; ++i ) { 491 SetLogDestination(i, ""); // "" turns off logging to a logfile 492 } 493} 494 495inline void LogDestination::SetEmailLogging(LogSeverity min_severity, 496 const char* addresses) { 497 assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); 498 // Prevent any subtle race conditions by wrapping a mutex lock around 499 // all this stuff. 500 MutexLock l(&log_mutex); 501 LogDestination::email_logging_severity_ = min_severity; 502 LogDestination::addresses_ = addresses; 503} 504 505static void WriteToStderr(const char* message, size_t len) { 506 // Avoid using cerr from this module since we may get called during 507 // exit code, and cerr may be partially or fully destroyed by then. 508 fwrite(message, len, 1, stderr); 509} 510 511inline void LogDestination::MaybeLogToStderr(LogSeverity severity, 512 const char* message, size_t len) { 513 if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { 514 WriteToStderr(message, len); 515#ifdef OS_WINDOWS 516 // On Windows, also output to the debugger 517 ::OutputDebugStringA(string(message,len).c_str()); 518#endif 519 } 520} 521 522 523inline void LogDestination::MaybeLogToEmail(LogSeverity severity, 524 const char* message, size_t len) { 525 if (severity >= email_logging_severity_ || 526 severity >= FLAGS_logemaillevel) { 527 string to(FLAGS_alsologtoemail); 528 if (!addresses_.empty()) { 529 if (!to.empty()) { 530 to += ","; 531 } 532 to += addresses_; 533 } 534 const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " + 535 glog_internal_namespace_::ProgramInvocationShortName()); 536 string body(hostname()); 537 body += "\n\n"; 538 body.append(message, len); 539 540 // should NOT use SendEmail(). The caller of this function holds the 541 // log_mutex and SendEmail() calls LOG/VLOG which will block trying to 542 // acquire the log_mutex object. Use SendEmailInternal() and set 543 // use_logging to false. 544 SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false); 545 } 546} 547 548 549inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, 550 time_t timestamp, 551 const char* message, 552 size_t len) { 553 const bool should_flush = severity > FLAGS_logbuflevel; 554 LogDestination* destination = log_destination(severity); 555 destination->logger_->Write(should_flush, timestamp, message, len); 556} 557 558inline void LogDestination::LogToAllLogfiles(LogSeverity severity, 559 time_t timestamp, 560 const char* message, 561 size_t len) { 562 563 if ( FLAGS_logtostderr ) // global flag: never log to file 564 WriteToStderr(message, len); 565 else 566 for (int i = severity; i >= 0; --i) 567 LogDestination::MaybeLogToLogfile(i, timestamp, message, len); 568 569} 570 571inline void LogDestination::LogToSinks(LogSeverity severity, 572 const char *full_filename, 573 const char *base_filename, 574 int line, 575 const struct ::tm* tm_time, 576 const char* message, 577 size_t message_len) { 578 ReaderMutexLock l(&sink_mutex_); 579 if (sinks_) { 580 for (int i = sinks_->size() - 1; i >= 0; i--) { 581 (*sinks_)[i]->send(severity, full_filename, base_filename, 582 line, tm_time, message, message_len); 583 } 584 } 585} 586 587inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { 588 ReaderMutexLock l(&sink_mutex_); 589 if (sinks_) { 590 for (int i = sinks_->size() - 1; i >= 0; i--) { 591 (*sinks_)[i]->WaitTillSent(); 592 } 593 } 594 const bool send_to_sink = 595 (data->send_method_ == &LogMessage::SendToSink) || 596 (data->send_method_ == &LogMessage::SendToSinkAndLog); 597 if (send_to_sink && data->sink_ != NULL) { 598 data->sink_->WaitTillSent(); 599 } 600} 601 602LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; 603 604inline LogDestination* LogDestination::log_destination(LogSeverity severity) { 605 assert(severity >=0 && severity < NUM_SEVERITIES); 606 if (!log_destinations_[severity]) { 607 log_destinations_[severity] = new LogDestination(severity, NULL); 608 } 609 return log_destinations_[severity]; 610} 611 612void LogDestination::DeleteLogDestinations() { 613 for (int severity = 0; severity < NUM_SEVERITIES; ++severity) { 614 delete log_destinations_[severity]; 615 log_destinations_[severity] = NULL; 616 } 617} 618 619namespace { 620 621LogFileObject::LogFileObject(LogSeverity severity, 622 const char* base_filename) 623 : base_filename_selected_(base_filename != NULL), 624 base_filename_((base_filename != NULL) ? base_filename : ""), 625 symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), 626 filename_extension_(), 627 file_(NULL), 628 severity_(severity), 629 bytes_since_flush_(0), 630 file_length_(0), 631 rollover_attempt_(kRolloverAttemptFrequency-1), 632 next_flush_time_(0) { 633 assert(severity >= 0); 634 assert(severity < NUM_SEVERITIES); 635} 636 637LogFileObject::~LogFileObject() { 638 MutexLock l(&lock_); 639 if (file_ != NULL) { 640 fclose(file_); 641 file_ = NULL; 642 } 643} 644 645void LogFileObject::SetBasename(const char* basename) { 646 MutexLock l(&lock_); 647 base_filename_selected_ = true; 648 if (base_filename_ != basename) { 649 // Get rid of old log file since we are changing names 650 if (file_ != NULL) { 651 fclose(file_); 652 file_ = NULL; 653 rollover_attempt_ = kRolloverAttemptFrequency-1; 654 } 655 base_filename_ = basename; 656 } 657} 658 659void LogFileObject::SetExtension(const char* ext) { 660 MutexLock l(&lock_); 661 if (filename_extension_ != ext) { 662 // Get rid of old log file since we are changing names 663 if (file_ != NULL) { 664 fclose(file_); 665 file_ = NULL; 666 rollover_attempt_ = kRolloverAttemptFrequency-1; 667 } 668 filename_extension_ = ext; 669 } 670} 671 672void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { 673 MutexLock l(&lock_); 674 symlink_basename_ = symlink_basename; 675} 676 677void LogFileObject::Flush() { 678 MutexLock l(&lock_); 679 FlushUnlocked(); 680} 681 682void LogFileObject::FlushUnlocked(){ 683 if (file_ != NULL) { 684 fflush(file_); 685 bytes_since_flush_ = 0; 686 } 687 // Figure out when we are due for another flush. 688 const int64 next = (FLAGS_logbufsecs 689 * static_cast<int64>(1000000)); // in usec 690 next_flush_time_ = CycleClock_Now() + UsecToCycles(next); 691} 692 693bool LogFileObject::CreateLogfile(const char* time_pid_string) { 694 string string_filename = base_filename_+filename_extension_+ 695 time_pid_string; 696 const char* filename = string_filename.c_str(); 697 int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664); 698 if (fd == -1) return false; 699#ifdef HAVE_FCNTL 700 // Mark the file close-on-exec. We don't really care if this fails 701 fcntl(fd, F_SETFD, FD_CLOEXEC); 702#endif 703 704 file_ = fdopen(fd, "a"); // Make a FILE*. 705 if (file_ == NULL) { // Man, we're screwed! 706 close(fd); 707 unlink(filename); // Erase the half-baked evidence: an unusable log file 708 return false; 709 } 710 711 // We try to create a symlink called <program_name>.<severity>, 712 // which is easier to use. (Every time we create a new logfile, 713 // we destroy the old symlink and create a new one, so it always 714 // points to the latest logfile.) If it fails, we're sad but it's 715 // no error. 716 if (!symlink_basename_.empty()) { 717 // take directory from filename 718 const char* slash = strrchr(filename, PATH_SEPARATOR); 719 const string linkname = 720 symlink_basename_ + '.' + LogSeverityNames[severity_]; 721 string linkpath; 722 if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname 723 linkpath += linkname; 724 unlink(linkpath.c_str()); // delete old one if it exists 725 726 // We must have unistd.h. 727#ifdef HAVE_UNISTD_H 728 // Make the symlink be relative (in the same dir) so that if the 729 // entire log directory gets relocated the link is still valid. 730 const char *linkdest = slash ? (slash + 1) : filename; 731 if (symlink(linkdest, linkpath.c_str()) != 0) { 732 // silently ignore failures 733 } 734 735 // Make an additional link to the log file in a place specified by 736 // FLAGS_log_link, if indicated 737 if (!FLAGS_log_link.empty()) { 738 linkpath = FLAGS_log_link + "/" + linkname; 739 unlink(linkpath.c_str()); // delete old one if it exists 740 if (symlink(filename, linkpath.c_str()) != 0) { 741 // silently ignore failures 742 } 743 } 744#endif 745 } 746 747 return true; // Everything worked 748} 749 750void LogFileObject::Write(bool force_flush, 751 time_t timestamp, 752 const char* message, 753 int message_len) { 754 MutexLock l(&lock_); 755 756 // We don't log if the base_name_ is "" (which means "don't write") 757 if (base_filename_selected_ && base_filename_.empty()) { 758 return; 759 } 760 761 if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() || 762 PidHasChanged()) { 763 if (file_ != NULL) fclose(file_); 764 file_ = NULL; 765 file_length_ = bytes_since_flush_ = 0; 766 rollover_attempt_ = kRolloverAttemptFrequency-1; 767 } 768 769 // If there's no destination file, make one before outputting 770 if (file_ == NULL) { 771 // Try to rollover the log file every 32 log messages. The only time 772 // this could matter would be when we have trouble creating the log 773 // file. If that happens, we'll lose lots of log messages, of course! 774 if (++rollover_attempt_ != kRolloverAttemptFrequency) return; 775 rollover_attempt_ = 0; 776 777 struct ::tm tm_time; 778 localtime_r(×tamp, &tm_time); 779 780 // The logfile's filename will have the date/time & pid in it 781 char time_pid_string[256]; // More than enough chars for time, pid, \0 782 ostrstream time_pid_stream(time_pid_string, sizeof(time_pid_string)); 783 time_pid_stream.fill('0'); 784 time_pid_stream << 1900+tm_time.tm_year 785 << setw(2) << 1+tm_time.tm_mon 786 << setw(2) << tm_time.tm_mday 787 << '-' 788 << setw(2) << tm_time.tm_hour 789 << setw(2) << tm_time.tm_min 790 << setw(2) << tm_time.tm_sec 791 << '.' 792 << GetMainThreadPid() 793 << '\0'; 794 795 if (base_filename_selected_) { 796 if (!CreateLogfile(time_pid_string)) { 797 perror("Could not create log file"); 798 fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", time_pid_string); 799 return; 800 } 801 } else { 802 // If no base filename for logs of this severity has been set, use a 803 // default base filename of 804 // "<program name>.<hostname>.<user name>.log.<severity level>.". So 805 // logfiles will have names like 806 // webserver.examplehost.root.log.INFO.19990817-150000.4354, where 807 // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00), 808 // and 4354 is the pid of the logging process. The date & time reflect 809 // when the file was created for output. 810 // 811 // Where does the file get put? Successively try the directories 812 // "/tmp", and "." 813 string stripped_filename( 814 glog_internal_namespace_::ProgramInvocationShortName()); 815 string hostname; 816 GetHostName(&hostname); 817 818 string uidname = MyUserName(); 819 // We should not call CHECK() here because this function can be 820 // called after holding on to log_mutex. We don't want to 821 // attempt to hold on to the same mutex, and get into a 822 // deadlock. Simply use a name like invalid-user. 823 if (uidname.empty()) uidname = "invalid-user"; 824 825 stripped_filename = stripped_filename+'.'+hostname+'.' 826 +uidname+".log." 827 +LogSeverityNames[severity_]+'.'; 828 // We're going to (potentially) try to put logs in several different dirs 829 const vector<string> & log_dirs = GetLoggingDirectories(); 830 831 // Go through the list of dirs, and try to create the log file in each 832 // until we succeed or run out of options 833 bool success = false; 834 for (vector<string>::const_iterator dir = log_dirs.begin(); 835 dir != log_dirs.end(); 836 ++dir) { 837 base_filename_ = *dir + "/" + stripped_filename; 838 if ( CreateLogfile(time_pid_string) ) { 839 success = true; 840 break; 841 } 842 } 843 // If we never succeeded, we have to give up 844 if ( success == false ) { 845 perror("Could not create logging file"); 846 fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", time_pid_string); 847 return; 848 } 849 } 850 851 // Write a header message into the log file 852 char file_header_string[512]; // Enough chars for time and binary info 853 ostrstream file_header_stream(file_header_string, 854 sizeof(file_header_string)); 855 file_header_stream.fill('0'); 856 file_header_stream << "Log file created at: " 857 << 1900+tm_time.tm_year << '/' 858 << setw(2) << 1+tm_time.tm_mon << '/' 859 << setw(2) << tm_time.tm_mday 860 << ' ' 861 << setw(2) << tm_time.tm_hour << ':' 862 << setw(2) << tm_time.tm_min << ':' 863 << setw(2) << tm_time.tm_sec << '\n' 864 << "Running on machine: " 865 << LogDestination::hostname() << '\n' 866 << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu " 867 << "threadid file:line] msg" << '\n' 868 << '\0'; 869 int header_len = strlen(file_header_string); 870 fwrite(file_header_string, 1, header_len, file_); 871 file_length_ += header_len; 872 bytes_since_flush_ += header_len; 873 } 874 875 // Write to LOG file 876 if ( !stop_writing ) { 877 // fwrite() doesn't return an error when the disk is full, for 878 // messages that are less than 4096 bytes. When the disk is full, 879 // it returns the message length for messages that are less than 880 // 4096 bytes. fwrite() returns 4096 for message lengths that are 881 // greater than 4096, thereby indicating an error. 882 errno = 0; 883 fwrite(message, 1, message_len, file_); 884 if ( FLAGS_stop_logging_if_full_disk && 885 errno == ENOSPC ) { // disk full, stop writing to disk 886 stop_writing = true; // until the disk is 887 return; 888 } else { 889 file_length_ += message_len; 890 bytes_since_flush_ += message_len; 891 } 892 } else { 893 if ( CycleClock_Now() >= next_flush_time_ ) 894 stop_writing = false; // check to see if disk has free space. 895 return; // no need to flush 896 } 897 898 // See important msgs *now*. Also, flush logs at least every 10^6 chars, 899 // or every "FLAGS_logbufsecs" seconds. 900 if ( force_flush || 901 (bytes_since_flush_ >= 1000000) || 902 (CycleClock_Now() >= next_flush_time_) ) { 903 FlushUnlocked(); 904#ifdef OS_LINUX 905 if (FLAGS_drop_log_memory) { 906 if (file_length_ >= logging::kPageSize) { 907 // don't evict the most recent page 908 uint32 len = file_length_ & ~(logging::kPageSize - 1); 909 posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED); 910 } 911 } 912#endif 913 } 914} 915 916} // namespace 917 918// An arbitrary limit on the length of a single log message. This 919// is so that streaming can be done more efficiently. 920const size_t LogMessage::kMaxLogMessageLen = 30000; 921 922// Static log data space to avoid alloc failures in a LOG(FATAL) 923// 924// Since multiple threads may call LOG(FATAL), and we want to preserve 925// the data from the first call, we allocate two sets of space. One 926// for exclusive use by the first thread, and one for shared use by 927// all other threads. 928static Mutex fatal_msg_lock; 929static CrashReason crash_reason; 930static bool fatal_msg_exclusive = true; 931static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1]; 932static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1]; 933static LogMessage::LogStream fatal_msg_stream_exclusive( 934 fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0); 935static LogMessage::LogStream fatal_msg_stream_shared( 936 fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0); 937LogMessage::LogMessageData LogMessage::fatal_msg_data_exclusive_; 938LogMessage::LogMessageData LogMessage::fatal_msg_data_shared_; 939 940LogMessage::LogMessageData::~LogMessageData() { 941 delete[] buf_; 942 delete stream_alloc_; 943} 944 945LogMessage::LogMessage(const char* file, int line, LogSeverity severity, 946 int ctr, void (LogMessage::*send_method)()) { 947 Init(file, line, severity, send_method); 948 data_->stream_->set_ctr(ctr); 949} 950 951LogMessage::LogMessage(const char* file, int line, 952 const CheckOpString& result) { 953 Init(file, line, FATAL, &LogMessage::SendToLog); 954 stream() << "Check failed: " << (*result.str_) << " "; 955} 956 957LogMessage::LogMessage(const char* file, int line) { 958 Init(file, line, INFO, &LogMessage::SendToLog); 959} 960 961LogMessage::LogMessage(const char* file, int line, LogSeverity severity) { 962 Init(file, line, severity, &LogMessage::SendToLog); 963} 964 965LogMessage::LogMessage(const char* file, int line, LogSeverity severity, 966 LogSink* sink, bool also_send_to_log) { 967 Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : 968 &LogMessage::SendToSink); 969 data_->sink_ = sink; // override Init()'s setting to NULL 970} 971 972LogMessage::LogMessage(const char* file, int line, LogSeverity severity, 973 vector<string> *outvec) { 974 Init(file, line, severity, &LogMessage::SaveOrSendToLog); 975 data_->outvec_ = outvec; // override Init()'s setting to NULL 976} 977 978LogMessage::LogMessage(const char* file, int line, LogSeverity severity, 979 string *message) { 980 Init(file, line, severity, &LogMessage::WriteToStringAndLog); 981 data_->message_ = message; // override Init()'s setting to NULL 982} 983 984void LogMessage::Init(const char* file, 985 int line, 986 LogSeverity severity, 987 void (LogMessage::*send_method)()) { 988 allocated_ = NULL; 989 if (severity != FATAL || !exit_on_dfatal) { 990 allocated_ = new LogMessageData(); 991 data_ = allocated_; 992 data_->buf_ = new char[kMaxLogMessageLen+1]; 993 data_->message_text_ = data_->buf_; 994 data_->stream_alloc_ = 995 new LogStream(data_->message_text_, kMaxLogMessageLen, 0); 996 data_->stream_ = data_->stream_alloc_; 997 data_->first_fatal_ = false; 998 } else { 999 MutexLock l(&fatal_msg_lock); 1000 if (fatal_msg_exclusive) { 1001 fatal_msg_exclusive = false; 1002 data_ = &fatal_msg_data_exclusive_; 1003 data_->message_text_ = fatal_msg_buf_exclusive; 1004 data_->stream_ = &fatal_msg_stream_exclusive; 1005 data_->first_fatal_ = true; 1006 } else { 1007 data_ = &fatal_msg_data_shared_; 1008 data_->message_text_ = fatal_msg_buf_shared; 1009 data_->stream_ = &fatal_msg_stream_shared; 1010 data_->first_fatal_ = false; 1011 } 1012 data_->stream_alloc_ = NULL; 1013 } 1014 1015 stream().fill('0'); 1016 data_->preserved_errno_ = errno; 1017 data_->severity_ = severity; 1018 data_->line_ = line; 1019 data_->send_method_ = send_method; 1020 data_->sink_ = NULL; 1021 data_->outvec_ = NULL; 1022 WallTime now = WallTime_Now(); 1023 data_->timestamp_ = static_cast<time_t>(now); 1024 localtime_r(&data_->timestamp_, &data_->tm_time_); 1025 int usecs = static_cast<int>((now - data_->timestamp_) * 1000000); 1026 RawLog__SetLastTime(data_->tm_time_, usecs); 1027 1028 data_->num_chars_to_log_ = 0; 1029 data_->num_chars_to_syslog_ = 0; 1030 data_->basename_ = const_basename(file); 1031 data_->fullname_ = file; 1032 data_->has_been_flushed_ = false; 1033 1034 // If specified, prepend a prefix to each line. For example: 1035 // I1018 160715 f5d4fbb0 logging.cc:1153] 1036 // (log level, GMT month, date, time, thread_id, file basename, line) 1037 // We exclude the thread_id for the default thread. 1038 if (FLAGS_log_prefix && (line != kNoLogPrefix)) { 1039 stream() << LogSeverityNames[severity][0] 1040 << setw(2) << 1+data_->tm_time_.tm_mon 1041 << setw(2) << data_->tm_time_.tm_mday 1042 << ' ' 1043 << setw(2) << data_->tm_time_.tm_hour << ':' 1044 << setw(2) << data_->tm_time_.tm_min << ':' 1045 << setw(2) << data_->tm_time_.tm_sec << "." 1046 << setw(6) << usecs 1047 << ' ' 1048 << setfill(' ') << setw(5) 1049 << static_cast<unsigned int>(GetTID()) << setfill('0') 1050 << ' ' 1051 << data_->basename_ << ':' << data_->line_ << "] "; 1052 } 1053 data_->num_prefix_chars_ = data_->stream_->pcount(); 1054 1055 if (!FLAGS_log_backtrace_at.empty()) { 1056 char fileline[128]; 1057 snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); 1058#ifdef HAVE_STACKTRACE 1059 if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) { 1060 string stacktrace; 1061 DumpStackTraceToString(&stacktrace); 1062 stream() << " (stacktrace:\n" << stacktrace << ") "; 1063 } 1064#endif 1065 } 1066} 1067 1068LogMessage::~LogMessage() { 1069 Flush(); 1070 delete allocated_; 1071} 1072 1073// Flush buffered message, called by the destructor, or any other function 1074// that needs to synchronize the log. 1075void LogMessage::Flush() { 1076 if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) 1077 return; 1078 1079 data_->num_chars_to_log_ = data_->stream_->pcount(); 1080 data_->num_chars_to_syslog_ = 1081 data_->num_chars_to_log_ - data_->num_prefix_chars_; 1082 1083 // Do we need to add a \n to the end of this message? 1084 bool append_newline = 1085 (data_->message_text_[data_->num_chars_to_log_-1] != '\n'); 1086 char original_final_char = '\0'; 1087 1088 // If we do need to add a \n, we'll do it by violating the memory of the 1089 // ostrstream buffer. This is quick, and we'll make sure to undo our 1090 // modification before anything else is done with the ostrstream. It 1091 // would be preferable not to do things this way, but it seems to be 1092 // the best way to deal with this. 1093 if (append_newline) { 1094 original_final_char = data_->message_text_[data_->num_chars_to_log_]; 1095 data_->message_text_[data_->num_chars_to_log_++] = '\n'; 1096 } 1097 1098 // Prevent any subtle race conditions by wrapping a mutex lock around 1099 // the actual logging action per se. 1100 { 1101 MutexLock l(&log_mutex); 1102 (this->*(data_->send_method_))(); 1103 ++num_messages_[static_cast<int>(data_->severity_)]; 1104 } 1105 LogDestination::WaitForSinks(data_); 1106 1107 if (append_newline) { 1108 // Fix the ostrstream back how it was before we screwed with it. 1109 // It's 99.44% certain that we don't need to worry about doing this. 1110 data_->message_text_[data_->num_chars_to_log_-1] = original_final_char; 1111 } 1112 1113 // If errno was already set before we enter the logging call, we'll 1114 // set it back to that value when we return from the logging call. 1115 // It happens often that we log an error message after a syscall 1116 // failure, which can potentially set the errno to some other 1117 // values. We would like to preserve the original errno. 1118 if (data_->preserved_errno_ != 0) { 1119 errno = data_->preserved_errno_; 1120 } 1121 1122 // Note that this message is now safely logged. If we're asked to flush 1123 // again, as a result of destruction, say, we'll do nothing on future calls. 1124 data_->has_been_flushed_ = true; 1125} 1126 1127// Copy of first FATAL log message so that we can print it out again 1128// after all the stack traces. To preserve legacy behavior, we don't 1129// use fatal_msg_buf_exclusive. 1130static time_t fatal_time; 1131static char fatal_message[256]; 1132 1133void ReprintFatalMessage() { 1134 if (fatal_message[0]) { 1135 const int n = strlen(fatal_message); 1136 if (!FLAGS_logtostderr) { 1137 // Also write to stderr 1138 WriteToStderr(fatal_message, n); 1139 } 1140 LogDestination::LogToAllLogfiles(ERROR, fatal_time, fatal_message, n); 1141 } 1142} 1143 1144// L >= log_mutex (callers must hold the log_mutex). 1145void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { 1146 static bool already_warned_before_initgoogle = false; 1147 1148 log_mutex.AssertHeld(); 1149 1150 RAW_DCHECK(data_->num_chars_to_log_ > 0 && 1151 data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); 1152 1153 // Messages of a given severity get logged to lower severity logs, too 1154 1155 if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) { 1156 const char w[] = "WARNING: Logging before InitGoogleLogging() is " 1157 "written to STDERR\n"; 1158 WriteToStderr(w, strlen(w)); 1159 already_warned_before_initgoogle = true; 1160 } 1161 1162 // global flag: never log to file if set. Also -- don't log to a 1163 // file if we haven't parsed the command line flags to get the 1164 // program name. 1165 if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { 1166 WriteToStderr(data_->message_text_, data_->num_chars_to_log_); 1167 1168 // this could be protected by a flag if necessary. 1169 LogDestination::LogToSinks(data_->severity_, 1170 data_->fullname_, data_->basename_, 1171 data_->line_, &data_->tm_time_, 1172 data_->message_text_ + data_->num_prefix_chars_, 1173 (data_->num_chars_to_log_ - 1174 data_->num_prefix_chars_ - 1)); 1175 } else { 1176 1177 // log this message to all log files of severity <= severity_ 1178 LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_, 1179 data_->message_text_, 1180 data_->num_chars_to_log_); 1181 1182 LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, 1183 data_->num_chars_to_log_); 1184 LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, 1185 data_->num_chars_to_log_); 1186 LogDestination::LogToSinks(data_->severity_, 1187 data_->fullname_, data_->basename_, 1188 data_->line_, &data_->tm_time_, 1189 data_->message_text_ + data_->num_prefix_chars_, 1190 (data_->num_chars_to_log_ 1191 - data_->num_prefix_chars_ - 1)); 1192 // NOTE: -1 removes trailing \n 1193 } 1194 1195 // If we log a FATAL message, flush all the log destinations, then toss 1196 // a signal for others to catch. We leave the logs in a state that 1197 // someone else can use them (as long as they flush afterwards) 1198 if (data_->severity_ == FATAL && exit_on_dfatal) { 1199 if (data_->first_fatal_) { 1200 // Store crash information so that it is accessible from within signal 1201 // handlers that may be invoked later. 1202 RecordCrashReason(&crash_reason); 1203 SetCrashReason(&crash_reason); 1204 1205 // Store shortened fatal message for other logs and GWQ status 1206 const int copy = min<int>(data_->num_chars_to_log_, 1207 sizeof(fatal_message)-1); 1208 memcpy(fatal_message, data_->message_text_, copy); 1209 fatal_message[copy] = '\0'; 1210 fatal_time = data_->timestamp_; 1211 } 1212 1213 if (!FLAGS_logtostderr) { 1214 for (int i = 0; i < NUM_SEVERITIES; ++i) { 1215 if ( LogDestination::log_destinations_[i] ) 1216 LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); 1217 } 1218 } 1219 1220 // release the lock that our caller (directly or indirectly) 1221 // LogMessage::~LogMessage() grabbed so that signal handlers 1222 // can use the logging facility. Alternately, we could add 1223 // an entire unsafe logging interface to bypass locking 1224 // for signal handlers but this seems simpler. 1225 log_mutex.Unlock(); 1226 LogDestination::WaitForSinks(data_); 1227 1228 const char* message = "*** Check failure stack trace: ***\n"; 1229 if (write(STDERR_FILENO, message, strlen(message)) < 0) { 1230 // Ignore errors. 1231 } 1232 Fail(); 1233 } 1234} 1235 1236void LogMessage::RecordCrashReason( 1237 glog_internal_namespace_::CrashReason* reason) { 1238 reason->filename = fatal_msg_data_exclusive_.fullname_; 1239 reason->line_number = fatal_msg_data_exclusive_.line_; 1240 reason->message = fatal_msg_buf_exclusive + 1241 fatal_msg_data_exclusive_.num_prefix_chars_; 1242#ifdef HAVE_STACKTRACE 1243 // Retrieve the stack trace, omitting the logging frames that got us here. 1244 reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); 1245#else 1246 reason->depth = 0; 1247#endif 1248} 1249 1250static void logging_fail() { 1251#if defined(_DEBUG) && defined(_MSC_VER) 1252 // When debugging on windows, avoid the obnoxious dialog and make 1253 // it possible to continue past a LOG(FATAL) in the debugger 1254 _asm int 3 1255#else 1256 abort(); 1257#endif 1258} 1259 1260#ifdef HAVE___ATTRIBUTE__ 1261GOOGLE_GLOG_DLL_DECL 1262void (*g_logging_fail_func)() __attribute__((noreturn)) = &logging_fail; 1263#else 1264GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)() = &logging_fail; 1265#endif 1266 1267void InstallFailureFunction(void (*fail_func)()) { 1268 g_logging_fail_func = fail_func; 1269} 1270 1271void LogMessage::Fail() { 1272 g_logging_fail_func(); 1273} 1274 1275// L >= log_mutex (callers must hold the log_mutex). 1276void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { 1277 if (data_->sink_ != NULL) { 1278 RAW_DCHECK(data_->num_chars_to_log_ > 0 && 1279 data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); 1280 data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, 1281 data_->line_, &data_->tm_time_, 1282 data_->message_text_ + data_->num_prefix_chars_, 1283 (data_->num_chars_to_log_ - 1284 data_->num_prefix_chars_ - 1)); 1285 } 1286} 1287 1288// L >= log_mutex (callers must hold the log_mutex). 1289void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { 1290 SendToSink(); 1291 SendToLog(); 1292} 1293 1294// L >= log_mutex (callers must hold the log_mutex). 1295void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { 1296 if (data_->outvec_ != NULL) { 1297 RAW_DCHECK(data_->num_chars_to_log_ > 0 && 1298 data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); 1299 // Omit prefix of message and trailing newline when recording in outvec_. 1300 const char *start = data_->message_text_ + data_->num_prefix_chars_; 1301 int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; 1302 data_->outvec_->push_back(string(start, len)); 1303 } else { 1304 SendToLog(); 1305 } 1306} 1307 1308void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { 1309 if (data_->message_ != NULL) { 1310 RAW_DCHECK(data_->num_chars_to_log_ > 0 && 1311 data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); 1312 // Omit prefix of message and trailing newline when writing to message_. 1313 const char *start = data_->message_text_ + data_->num_prefix_chars_; 1314 int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; 1315 data_->message_->assign(start, len); 1316 } 1317 SendToLog(); 1318} 1319 1320// L >= log_mutex (callers must hold the log_mutex). 1321void LogMessage::SendToSyslogAndLog() { 1322#ifdef HAVE_SYSLOG_H 1323 // Before any calls to syslog(), make a single call to openlog() 1324 static bool openlog_already_called = false; 1325 if (!openlog_already_called) { 1326 openlog(glog_internal_namespace_::ProgramInvocationShortName(), 1327 LOG_CONS | LOG_NDELAY | LOG_PID, 1328 LOG_USER); 1329 openlog_already_called = true; 1330 } 1331 1332 // This array maps Google severity levels to syslog levels 1333 const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; 1334 syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s", 1335 int(data_->num_chars_to_syslog_), 1336 data_->message_text_ + data_->num_prefix_chars_); 1337 SendToLog(); 1338#else 1339 LOG(ERROR) << "No syslog support: message=" << data_->message_text_; 1340#endif 1341} 1342 1343base::Logger* base::GetLogger(LogSeverity severity) { 1344 MutexLock l(&log_mutex); 1345 return LogDestination::log_destination(severity)->logger_; 1346} 1347 1348void base::SetLogger(LogSeverity severity, base::Logger* logger) { 1349 MutexLock l(&log_mutex); 1350 LogDestination::log_destination(severity)->logger_ = logger; 1351} 1352 1353// L < log_mutex. Acquires and releases mutex_. 1354int64 LogMessage::num_messages(int severity) { 1355 MutexLock l(&log_mutex); 1356 return num_messages_[severity]; 1357} 1358 1359// Output the COUNTER value. This is only valid if ostream is a 1360// LogStream. 1361ostream& operator<<(ostream &os, const PRIVATE_Counter&) { 1362 LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os); 1363 CHECK(log == log->self()); 1364 os << log->ctr(); 1365 return os; 1366} 1367 1368ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, 1369 LogSeverity severity, int ctr, 1370 void (LogMessage::*send_method)()) 1371 : LogMessage(file, line, severity, ctr, send_method) { 1372} 1373 1374ErrnoLogMessage::~ErrnoLogMessage() { 1375 // Don't access errno directly because it may have been altered 1376 // while streaming the message. 1377 char buf[100]; 1378 posix_strerror_r(preserved_errno(), buf, sizeof(buf)); 1379 stream() << ": " << buf << " [" << preserved_errno() << "]"; 1380} 1381 1382void FlushLogFiles(LogSeverity min_severity) { 1383 LogDestination::FlushLogFiles(min_severity); 1384} 1385 1386void FlushLogFilesUnsafe(LogSeverity min_severity) { 1387 LogDestination::FlushLogFilesUnsafe(min_severity); 1388} 1389 1390void SetLogDestination(LogSeverity severity, const char* base_filename) { 1391 LogDestination::SetLogDestination(severity, base_filename); 1392} 1393 1394void SetLogSymlink(LogSeverity severity, const char* symlink_basename) { 1395 LogDestination::SetLogSymlink(severity, symlink_basename); 1396} 1397 1398LogSink::~LogSink() { 1399} 1400 1401void LogSink::WaitTillSent() { 1402 // noop default 1403} 1404 1405string LogSink::ToString(LogSeverity severity, const char* file, int line, 1406 const struct ::tm* tm_time, 1407 const char* message, size_t message_len) { 1408 ostringstream stream(string(message, message_len)); 1409 stream.fill('0'); 1410 1411 // FIXME(jrvb): Updating this to use the correct value for usecs 1412 // requires changing the signature for both this method and 1413 // LogSink::send(). This change needs to be done in a separate CL 1414 // so subclasses of LogSink can be updated at the same time. 1415 int usecs = 0; 1416 1417 stream << LogSeverityNames[severity][0] 1418 << setw(2) << 1+tm_time->tm_mon 1419 << setw(2) << tm_time->tm_mday 1420 << ' ' 1421 << setw(2) << tm_time->tm_hour << ':' 1422 << setw(2) << tm_time->tm_min << ':' 1423 << setw(2) << tm_time->tm_sec << '.' 1424 << setw(6) << usecs 1425 << ' ' 1426 << setfill(' ') << setw(5) << GetTID() << setfill('0') 1427 << ' ' 1428 << file << ':' << line << "] "; 1429 1430 stream << string(message, message_len); 1431 return stream.str(); 1432} 1433 1434void AddLogSink(LogSink *destination) { 1435 LogDestination::AddLogSink(destination); 1436} 1437 1438void RemoveLogSink(LogSink *destination) { 1439 LogDestination::RemoveLogSink(destination); 1440} 1441 1442void SetLogFilenameExtension(const char* ext) { 1443 LogDestination::SetLogFilenameExtension(ext); 1444} 1445 1446void SetStderrLogging(LogSeverity min_severity) { 1447 LogDestination::SetStderrLogging(min_severity); 1448} 1449 1450void SetEmailLogging(LogSeverity min_severity, const char* addresses) { 1451 LogDestination::SetEmailLogging(min_severity, addresses); 1452} 1453 1454void LogToStderr() { 1455 LogDestination::LogToStderr(); 1456} 1457 1458namespace base { 1459namespace internal { 1460 1461bool GetExitOnDFatal() { 1462 MutexLock l(&log_mutex); 1463 return exit_on_dfatal; 1464} 1465 1466// Determines whether we exit the program for a LOG(DFATAL) message in 1467// debug mode. It does this by skipping the call to Fail/FailQuietly. 1468// This is intended for testing only. 1469// 1470// This can have some effects on LOG(FATAL) as well. Failure messages 1471// are always allocated (rather than sharing a buffer), the crash 1472// reason is not recorded, the "gwq" status message is not updated, 1473// and the stack trace is not recorded. The LOG(FATAL) *will* still 1474// exit the program. Since this function is used only in testing, 1475// these differences are acceptable. 1476void SetExitOnDFatal(bool value) { 1477 MutexLock l(&log_mutex); 1478 exit_on_dfatal = value; 1479} 1480 1481} // namespace internal 1482} // namespace base 1483 1484// use_logging controls whether the logging functions LOG/VLOG are used 1485// to log errors. It should be set to false when the caller holds the 1486// log_mutex. 1487static bool SendEmailInternal(const char*dest, const char *subject, 1488 const char*body, bool use_logging) { 1489 if (dest && *dest) { 1490 if ( use_logging ) { 1491 VLOG(1) << "Trying to send TITLE:" << subject 1492 << " BODY:" << body << " to " << dest; 1493 } else { 1494 fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n", 1495 subject, body, dest); 1496 } 1497 1498 string cmd = 1499 FLAGS_logmailer + " -s\"" + subject + "\" " + dest; 1500 FILE* pipe = popen(cmd.c_str(), "w"); 1501 if (pipe != NULL) { 1502 // Add the body if we have one 1503 if (body) 1504 fwrite(body, sizeof(char), strlen(body), pipe); 1505 bool ok = pclose(pipe) != -1; 1506 if ( !ok ) { 1507 if ( use_logging ) { 1508 char buf[100]; 1509 posix_strerror_r(errno, buf, sizeof(buf)); 1510 LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf; 1511 } else { 1512 char buf[100]; 1513 posix_strerror_r(errno, buf, sizeof(buf)); 1514 fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf); 1515 } 1516 } 1517 return ok; 1518 } else { 1519 if ( use_logging ) { 1520 LOG(ERROR) << "Unable to send mail to " << dest; 1521 } else { 1522 fprintf(stderr, "Unable to send mail to %s\n", dest); 1523 } 1524 } 1525 } 1526 return false; 1527} 1528 1529bool SendEmail(const char*dest, const char *subject, const char*body){ 1530 return SendEmailInternal(dest, subject, body, true); 1531} 1532 1533static void GetTempDirectories(vector<string>* list) { 1534 list->clear(); 1535#ifdef OS_WINDOWS 1536 // On windows we'll try to find a directory in this order: 1537 // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is) 1538 // C:/TMP/ 1539 // C:/TEMP/ 1540 // C:/WINDOWS/ or C:/WINNT/ 1541 // . 1542 char tmp[MAX_PATH]; 1543 if (GetTempPathA(MAX_PATH, tmp)) 1544 list->push_back(tmp); 1545 list->push_back("C:\\tmp\\"); 1546 list->push_back("C:\\temp\\"); 1547#else 1548 // Directories, in order of preference. If we find a dir that 1549 // exists, we stop adding other less-preferred dirs 1550 const char * candidates[] = { 1551 // Non-null only during unittest/regtest 1552 getenv("TEST_TMPDIR"), 1553 1554 // Explicitly-supplied temp dirs 1555 getenv("TMPDIR"), getenv("TMP"), 1556 1557 // If all else fails 1558 "/tmp", 1559 }; 1560 1561 for (int i = 0; i < ARRAYSIZE(candidates); i++) { 1562 const char *d = candidates[i]; 1563 if (!d) continue; // Empty env var 1564 1565 // Make sure we don't surprise anyone who's expecting a '/' 1566 string dstr = d; 1567 if (dstr[dstr.size() - 1] != '/') { 1568 dstr += "/"; 1569 } 1570 list->push_back(dstr); 1571 1572 struct stat statbuf; 1573 if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) { 1574 // We found a dir that exists - we're done. 1575 return; 1576 } 1577 } 1578 1579#endif 1580} 1581 1582static vector<string>* logging_directories_list; 1583 1584const vector<string>& GetLoggingDirectories() { 1585 // Not strictly thread-safe but we're called early in InitGoogle(). 1586 if (logging_directories_list == NULL) { 1587 logging_directories_list = new vector<string>; 1588 1589 if ( !FLAGS_log_dir.empty() ) { 1590 // A dir was specified, we should use it 1591 logging_directories_list->push_back(FLAGS_log_dir.c_str()); 1592 } else { 1593 GetTempDirectories(logging_directories_list); 1594#ifdef OS_WINDOWS 1595 char tmp[MAX_PATH]; 1596 if (GetWindowsDirectoryA(tmp, MAX_PATH)) 1597 logging_directories_list->push_back(tmp); 1598 logging_directories_list->push_back(".\\"); 1599#else 1600 logging_directories_list->push_back("./"); 1601#endif 1602 } 1603 } 1604 return *logging_directories_list; 1605} 1606 1607void TestOnly_ClearLoggingDirectoriesList() { 1608 fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " 1609 "called from test code.\n"); 1610 delete logging_directories_list; 1611 logging_directories_list = NULL; 1612} 1613 1614void GetExistingTempDirectories(vector<string>* list) { 1615 GetTempDirectories(list); 1616 vector<string>::iterator i_dir = list->begin(); 1617 while( i_dir != list->end() ) { 1618 // zero arg to access means test for existence; no constant 1619 // defined on windows 1620 if ( access(i_dir->c_str(), 0) ) { 1621 i_dir = list->erase(i_dir); 1622 } else { 1623 ++i_dir; 1624 } 1625 } 1626} 1627 1628void TruncateLogFile(const char *path, int64 limit, int64 keep) { 1629#ifdef HAVE_UNISTD_H 1630 struct stat statbuf; 1631 const int kCopyBlockSize = 8 << 10; 1632 char copybuf[kCopyBlockSize]; 1633 int64 read_offset, write_offset; 1634 // Don't follow symlinks unless they're our own fd symlinks in /proc 1635 int flags = O_RDWR; 1636 const char *procfd_prefix = "/proc/self/fd/"; 1637 if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; 1638 1639 int fd = open(path, flags); 1640 if (fd == -1) { 1641 if (errno == EFBIG) { 1642 // The log file in question has got too big for us to open. The 1643 // real fix for this would be to compile logging.cc (or probably 1644 // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's 1645 // rather scary. 1646 // Instead just truncate the file to something we can manage 1647 if (truncate(path, 0) == -1) { 1648 PLOG(ERROR) << "Unable to truncate " << path; 1649 } else { 1650 LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; 1651 } 1652 } else { 1653 PLOG(ERROR) << "Unable to open " << path; 1654 } 1655 return; 1656 } 1657 1658 if (fstat(fd, &statbuf) == -1) { 1659 PLOG(ERROR) << "Unable to fstat()"; 1660 goto out_close_fd; 1661 } 1662 1663 // See if the path refers to a regular file bigger than the 1664 // specified limit 1665 if (!S_ISREG(statbuf.st_mode)) goto out_close_fd; 1666 if (statbuf.st_size <= limit) goto out_close_fd; 1667 if (statbuf.st_size <= keep) goto out_close_fd; 1668 1669 // This log file is too large - we need to truncate it 1670 LOG(INFO) << "Truncating " << path << " to " << keep << " bytes"; 1671 1672 // Copy the last "keep" bytes of the file to the beginning of the file 1673 read_offset = statbuf.st_size - keep; 1674 write_offset = 0; 1675 int bytesin, bytesout; 1676 while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { 1677 bytesout = pwrite(fd, copybuf, bytesin, write_offset); 1678 if (bytesout == -1) { 1679 PLOG(ERROR) << "Unable to write to " << path; 1680 break; 1681 } else if (bytesout != bytesin) { 1682 LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout; 1683 } 1684 read_offset += bytesin; 1685 write_offset += bytesout; 1686 } 1687 if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path; 1688 1689 // Truncate the remainder of the file. If someone else writes to the 1690 // end of the file after our last read() above, we lose their latest 1691 // data. Too bad ... 1692 if (ftruncate(fd, write_offset) == -1) { 1693 PLOG(ERROR) << "Unable to truncate " << path; 1694 } 1695 1696 out_close_fd: 1697 close(fd); 1698#else 1699 LOG(ERROR) << "No log truncation support."; 1700#endif 1701} 1702 1703void TruncateStdoutStderr() { 1704#ifdef HAVE_UNISTD_H 1705 int64 limit = MaxLogSize() << 20; 1706 int64 keep = 1 << 20; 1707 TruncateLogFile("/proc/self/fd/1", limit, keep); 1708 TruncateLogFile("/proc/self/fd/2", limit, keep); 1709#else 1710 LOG(ERROR) << "No log truncation support."; 1711#endif 1712} 1713 1714 1715// Helper functions for string comparisons. 1716#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ 1717 string* Check##func##expected##Impl(const char* s1, const char* s2, \ 1718 const char* names) { \ 1719 bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ 1720 if (equal == expected) return NULL; \ 1721 else { \ 1722 strstream ss; \ 1723 if (!s1) s1 = ""; \ 1724 if (!s2) s2 = ""; \ 1725 ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ 1726 return new string(ss.str(), ss.pcount()); \ 1727 } \ 1728 } 1729DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) 1730DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) 1731DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) 1732DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) 1733#undef DEFINE_CHECK_STROP_IMPL 1734 1735int posix_strerror_r(int err, char *buf, size_t len) { 1736 // Sanity check input parameters 1737 if (buf == NULL || len <= 0) { 1738 errno = EINVAL; 1739 return -1; 1740 } 1741 1742 // Reset buf and errno, and try calling whatever version of strerror_r() 1743 // is implemented by glibc 1744 buf[0] = '\000'; 1745 int old_errno = errno; 1746 errno = 0; 1747 char *rc = reinterpret_cast<char *>(strerror_r(err, buf, len)); 1748 1749 // Both versions set errno on failure 1750 if (errno) { 1751 // Should already be there, but better safe than sorry 1752 buf[0] = '\000'; 1753 return -1; 1754 } 1755 errno = old_errno; 1756 1757 // POSIX is vague about whether the string will be terminated, although 1758 // is indirectly implies that typically ERANGE will be returned, instead 1759 // of truncating the string. This is different from the GNU implementation. 1760 // We play it safe by always terminating the string explicitly. 1761 buf[len-1] = '\000'; 1762 1763 // If the function succeeded, we can use its exit code to determine the 1764 // semantics implemented by glibc 1765 if (!rc) { 1766 return 0; 1767 } else { 1768 // GNU semantics detected 1769 if (rc == buf) { 1770 return 0; 1771 } else { 1772 buf[0] = '\000'; 1773#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) 1774 if (reinterpret_cast<intptr_t>(rc) < sys_nerr) { 1775 // This means an error on MacOSX or FreeBSD. 1776 return -1; 1777 } 1778#endif 1779 strncat(buf, rc, len-1); 1780 return 0; 1781 } 1782 } 1783} 1784 1785LogMessageFatal::LogMessageFatal(const char* file, int line) : 1786 LogMessage(file, line, FATAL) {} 1787 1788LogMessageFatal::LogMessageFatal(const char* file, int line, 1789 const CheckOpString& result) : 1790 LogMessage(file, line, result) {} 1791 1792LogMessageFatal::~LogMessageFatal() { 1793 Flush(); 1794 LogMessage::Fail(); 1795} 1796 1797void InitGoogleLogging(const char* argv0) { 1798 glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); 1799} 1800 1801void ShutdownGoogleLogging() { 1802 glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); 1803 LogDestination::DeleteLogDestinations(); 1804 delete logging_directories_list; 1805 logging_directories_list = NULL; 1806} 1807 1808_END_GOOGLE_NAMESPACE_