// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "brillo/syslog_logging.h"
#include <syslog.h>
#include <unistd.h>
#include <string>
// syslog.h and base/logging.h both try to #define LOG_INFO and LOG_WARNING.
// We need to #undef at least these two before including base/logging.h. The
// others are included to be consistent.
namespace {
const int kSyslogDebug = LOG_DEBUG;
const int kSyslogInfo = LOG_INFO;
const int kSyslogWarning = LOG_WARNING;
const int kSyslogError = LOG_ERR;
const int kSyslogCritical = LOG_CRIT;
#undef LOG_INFO
#undef LOG_WARNING
#undef LOG_ERR
#undef LOG_CRIT
} // namespace
#include <base/logging.h>
static std::string s_ident;
static std::string s_accumulated;
static bool s_accumulate;
static bool s_log_to_syslog;
static bool s_log_to_stderr;
static bool s_log_header;
static bool HandleMessage(int severity,
const char* /* file */,
int /* line */,
size_t message_start,
const std::string& message) {
switch (severity) {
case logging::LOG_INFO:
severity = kSyslogInfo;
break;
case logging::LOG_WARNING:
severity = kSyslogWarning;
break;
case logging::LOG_ERROR:
severity = kSyslogError;
break;
case logging::LOG_FATAL:
severity = kSyslogCritical;
break;
default:
severity = kSyslogDebug;
break;
}
const char* str;
if (s_log_header) {
str = message.c_str();
} else {
str = message.c_str() + message_start;
}
if (s_log_to_syslog)
syslog(severity, "%s", str);
if (s_accumulate)
s_accumulated.append(str);
return !s_log_to_stderr && severity != kSyslogCritical;
}
namespace brillo {
void SetLogFlags(int log_flags) {
s_log_to_syslog = (log_flags & kLogToSyslog) != 0;
s_log_to_stderr = (log_flags & kLogToStderr) != 0;
if ((log_flags & kLogToStderrIfTty) && isatty(0))
s_log_to_stderr = true;
s_log_header = (log_flags & kLogHeader) != 0;
}
int GetLogFlags() {
int flags = 0;
flags |= (s_log_to_syslog) ? kLogToSyslog : 0;
flags |= (s_log_to_stderr) ? kLogToStderr : 0;
flags |= (s_log_header) ? kLogHeader : 0;
return flags;
}
void InitLog(int init_flags) {
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
logging::InitLogging(settings);
const bool kOptionPID = false;
const bool kOptionTID = false;
const bool kOptionTimestamp = false;
const bool kOptionTickcount = false;
logging::SetLogItems(
kOptionPID, kOptionTID, kOptionTimestamp, kOptionTickcount);
logging::SetLogMessageHandler(HandleMessage);
SetLogFlags(init_flags);
}
void OpenLog(const char* ident, bool log_pid) {
s_ident = ident;
openlog(s_ident.c_str(), log_pid ? LOG_PID : 0, LOG_USER);
}
void LogToString(bool enabled) {
s_accumulate = enabled;
}
std::string GetLog() {
return s_accumulated;
}
void ClearLog() {
s_accumulated.clear();
}
bool FindLog(const char* string) {
return s_accumulated.find(string) != std::string::npos;
}
} // namespace brillo