Home | History | Annotate | Download | only in brillo
      1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "brillo/syslog_logging.h"
      6 
      7 #include <syslog.h>
      8 #include <unistd.h>
      9 
     10 #include <string>
     11 
     12 // syslog.h and base/logging.h both try to #define LOG_INFO and LOG_WARNING.
     13 // We need to #undef at least these two before including base/logging.h.  The
     14 // others are included to be consistent.
     15 namespace {
     16 const int kSyslogDebug    = LOG_DEBUG;
     17 const int kSyslogInfo     = LOG_INFO;
     18 const int kSyslogWarning  = LOG_WARNING;
     19 const int kSyslogError    = LOG_ERR;
     20 const int kSyslogCritical = LOG_CRIT;
     21 
     22 #undef LOG_INFO
     23 #undef LOG_WARNING
     24 #undef LOG_ERR
     25 #undef LOG_CRIT
     26 }  // namespace
     27 
     28 #include <base/logging.h>
     29 
     30 static std::string s_ident;
     31 static std::string s_accumulated;
     32 static bool s_accumulate;
     33 static bool s_log_to_syslog;
     34 static bool s_log_to_stderr;
     35 static bool s_log_header;
     36 
     37 static bool HandleMessage(int severity,
     38                           const char* /* file */,
     39                           int /* line */,
     40                           size_t message_start,
     41                           const std::string& message) {
     42   switch (severity) {
     43     case logging::LOG_INFO:
     44       severity = kSyslogInfo;
     45       break;
     46 
     47     case logging::LOG_WARNING:
     48       severity = kSyslogWarning;
     49       break;
     50 
     51     case logging::LOG_ERROR:
     52       severity = kSyslogError;
     53       break;
     54 
     55     case logging::LOG_FATAL:
     56       severity = kSyslogCritical;
     57       break;
     58 
     59     default:
     60       severity = kSyslogDebug;
     61       break;
     62   }
     63 
     64   const char* str;
     65   if (s_log_header) {
     66     str = message.c_str();
     67   } else {
     68     str = message.c_str() + message_start;
     69   }
     70 
     71   if (s_log_to_syslog)
     72     syslog(severity, "%s", str);
     73   if (s_accumulate)
     74     s_accumulated.append(str);
     75   return !s_log_to_stderr && severity != kSyslogCritical;
     76 }
     77 
     78 namespace brillo {
     79 void SetLogFlags(int log_flags) {
     80   s_log_to_syslog = (log_flags & kLogToSyslog) != 0;
     81   s_log_to_stderr = (log_flags & kLogToStderr) != 0;
     82   if ((log_flags & kLogToStderrIfTty) && isatty(0))
     83     s_log_to_stderr = true;
     84   s_log_header = (log_flags & kLogHeader) != 0;
     85 }
     86 int GetLogFlags() {
     87   int flags = 0;
     88   flags |= (s_log_to_syslog) ? kLogToSyslog : 0;
     89   flags |= (s_log_to_stderr) ? kLogToStderr : 0;
     90   flags |= (s_log_header) ? kLogHeader : 0;
     91   return flags;
     92 }
     93 void InitLog(int init_flags) {
     94   logging::LoggingSettings settings;
     95   settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
     96   logging::InitLogging(settings);
     97 
     98   const bool kOptionPID = false;
     99   const bool kOptionTID = false;
    100   const bool kOptionTimestamp = false;
    101   const bool kOptionTickcount = false;
    102   logging::SetLogItems(
    103       kOptionPID, kOptionTID, kOptionTimestamp, kOptionTickcount);
    104   logging::SetLogMessageHandler(HandleMessage);
    105   SetLogFlags(init_flags);
    106 }
    107 void OpenLog(const char* ident, bool log_pid) {
    108   s_ident = ident;
    109   openlog(s_ident.c_str(), log_pid ? LOG_PID : 0, LOG_USER);
    110 }
    111 void LogToString(bool enabled) {
    112   s_accumulate = enabled;
    113 }
    114 std::string GetLog() {
    115   return s_accumulated;
    116 }
    117 void ClearLog() {
    118   s_accumulated.clear();
    119 }
    120 bool FindLog(const char* string) {
    121   return s_accumulated.find(string) != std::string::npos;
    122 }
    123 }  // namespace brillo
    124