diff options
Diffstat (limited to 'lib/common/Logging.cpp')
-rw-r--r-- | lib/common/Logging.cpp | 233 |
1 files changed, 188 insertions, 45 deletions
diff --git a/lib/common/Logging.cpp b/lib/common/Logging.cpp index 2b81b52b..1f872d93 100644 --- a/lib/common/Logging.cpp +++ b/lib/common/Logging.cpp @@ -15,12 +15,15 @@ #ifdef HAVE_SYSLOG_H #include <syslog.h> #endif +#ifdef HAVE_UNISTD_H + #include <unistd.h> +#endif -#include "Logging.h" - +#include <cstring> #include <iomanip> #include "BoxTime.h" +#include "Logging.h" bool Logging::sLogToSyslog = false; bool Logging::sLogToConsole = false; @@ -32,6 +35,7 @@ Console* Logging::spConsole = NULL; Syslog* Logging::spSyslog = NULL; Log::Level Logging::sGlobalLevel = Log::EVERYTHING; Logging Logging::sGlobalLogging; //automatic initialisation +std::string Logging::sProgramName; Logging::Logging() { @@ -148,12 +152,54 @@ void Logging::Log(Log::Level level, const std::string& rFile, } } +void Logging::LogToSyslog(Log::Level level, const std::string& rFile, + int line, const std::string& rMessage) +{ + if (!sLogToSyslog) + { + return; + } + + if (level > sGlobalLevel) + { + return; + } + + std::string newMessage; + + if (sContextSet) + { + newMessage += "[" + sContext + "] "; + } + + newMessage += rMessage; + + spSyslog->Log(level, rFile, line, newMessage); +} + void Logging::SetContext(std::string context) { sContext = context; sContextSet = true; } +Log::Level Logging::GetNamedLevel(const std::string& rName) +{ + if (rName == "nothing") { return Log::NOTHING; } + else if (rName == "fatal") { return Log::FATAL; } + else if (rName == "error") { return Log::ERROR; } + else if (rName == "warning") { return Log::WARNING; } + else if (rName == "notice") { return Log::NOTICE; } + else if (rName == "info") { return Log::INFO; } + else if (rName == "trace") { return Log::TRACE; } + else if (rName == "everything") { return Log::EVERYTHING; } + else + { + BOX_ERROR("Unknown verbosity level: " << rName); + return Log::INVALID; + } +} + void Logging::ClearContext() { sContextSet = false; @@ -161,6 +207,8 @@ void Logging::ClearContext() void Logging::SetProgramName(const std::string& rProgramName) { + sProgramName = rProgramName; + for (std::vector<Logger*>::iterator i = sLoggers.begin(); i != sLoggers.end(); i++) { @@ -168,12 +216,23 @@ void Logging::SetProgramName(const std::string& rProgramName) } } +void Logging::SetFacility(int facility) +{ + spSyslog->SetFacility(facility); +} + Logger::Logger() : mCurrentLevel(Log::EVERYTHING) { Logging::Add(this); } +Logger::Logger(Log::Level Level) +: mCurrentLevel(Level) +{ + Logging::Add(this); +} + Logger::~Logger() { Logging::Remove(this); @@ -182,12 +241,17 @@ Logger::~Logger() bool Console::sShowTime = false; bool Console::sShowTimeMicros = false; bool Console::sShowTag = false; +bool Console::sShowPID = false; std::string Console::sTag; -void Console::SetTag(const std::string& rTag) +void Console::SetProgramName(const std::string& rProgramName) +{ + sTag = rProgramName; +} + +void Console::SetShowTag(bool enabled) { - sTag = rTag; - sShowTag = true; + sShowTag = enabled; } void Console::SetShowTime(bool enabled) @@ -200,6 +264,11 @@ void Console::SetShowTimeMicros(bool enabled) sShowTimeMicros = enabled; } +void Console::SetShowPID(bool enabled) +{ + sShowPID = enabled; +} + bool Console::Log(Log::Level level, const std::string& rFile, int line, std::string& rMessage) { @@ -215,69 +284,64 @@ bool Console::Log(Log::Level level, const std::string& rFile, target = stderr; } - std::string msg; + std::ostringstream buf; if (sShowTime) { - box_time_t time_now = GetCurrentBoxTime(); - time_t seconds = BoxTimeToSeconds(time_now); - int micros = BoxTimeToMicroSeconds(time_now) % MICRO_SEC_IN_SEC; - - struct tm tm_now, *tm_ptr = &tm_now; + buf << FormatTime(GetCurrentBoxTime(), false, sShowTimeMicros); + buf << " "; + } - #ifdef WIN32 - if ((tm_ptr = localtime(&seconds)) != NULL) - #else - if (localtime_r(&seconds, &tm_now) != NULL) - #endif + if (sShowTag) + { + if (sShowPID) { - std::ostringstream buf; - - buf << std::setfill('0') << - std::setw(2) << tm_ptr->tm_hour << ":" << - std::setw(2) << tm_ptr->tm_min << ":" << - std::setw(2) << tm_ptr->tm_sec; - - if (sShowTimeMicros) - { - buf << "." << std::setw(6) << micros; - } - - buf << " "; - msg += buf.str(); + buf << "[" << sTag << " " << getpid() << "] "; } else { - msg += strerror(errno); - msg += " "; + buf << "[" << sTag << "] "; } } - - if (sShowTag) + else if (sShowPID) { - msg += "[" + sTag + "] "; + buf << "[" << getpid() << "] "; } if (level <= Log::FATAL) { - msg += "FATAL: "; + buf << "FATAL: "; } else if (level <= Log::ERROR) { - msg += "ERROR: "; + buf << "ERROR: "; } else if (level <= Log::WARNING) { - msg += "WARNING: "; + buf << "WARNING: "; } else if (level <= Log::NOTICE) { - msg += "NOTICE: "; + buf << "NOTICE: "; } - - msg += rMessage; + else if (level <= Log::INFO) + { + buf << "INFO: "; + } + else if (level <= Log::TRACE) + { + buf << "TRACE: "; + } + + buf << rMessage; - fprintf(target, "%s\n", msg.c_str()); + #ifdef WIN32 + std::string output = buf.str(); + ConvertUtf8ToConsole(output.c_str(), output); + fprintf(target, "%s\n", output.c_str()); + #else + fprintf(target, "%s\n", buf.str().c_str()); + #endif return true; } @@ -295,6 +359,7 @@ bool Syslog::Log(Log::Level level, const std::string& rFile, switch(level) { case Log::NOTHING: /* fall through */ + case Log::INVALID: /* fall through */ case Log::FATAL: syslogLevel = LOG_CRIT; break; case Log::ERROR: syslogLevel = LOG_ERR; break; case Log::WARNING: syslogLevel = LOG_WARNING; break; @@ -330,9 +395,9 @@ bool Syslog::Log(Log::Level level, const std::string& rFile, return true; } -Syslog::Syslog() +Syslog::Syslog() : mFacility(LOG_LOCAL6) { - ::openlog("Box Backup", LOG_PID, LOG_LOCAL6); + ::openlog("Box Backup", LOG_PID, mFacility); } Syslog::~Syslog() @@ -344,5 +409,83 @@ void Syslog::SetProgramName(const std::string& rProgramName) { mName = rProgramName; ::closelog(); - ::openlog(mName.c_str(), LOG_PID, LOG_LOCAL6); + ::openlog(mName.c_str(), LOG_PID, mFacility); +} + +void Syslog::SetFacility(int facility) +{ + mFacility = facility; + ::closelog(); + ::openlog(mName.c_str(), LOG_PID, mFacility); +} + +int Syslog::GetNamedFacility(const std::string& rFacility) +{ + #define CASE_RETURN(x) if (rFacility == #x) { return LOG_ ## x; } + CASE_RETURN(LOCAL0) + CASE_RETURN(LOCAL1) + CASE_RETURN(LOCAL2) + CASE_RETURN(LOCAL3) + CASE_RETURN(LOCAL4) + CASE_RETURN(LOCAL5) + CASE_RETURN(LOCAL6) + CASE_RETURN(DAEMON) + #undef CASE_RETURN + + BOX_ERROR("Unknown log facility '" << rFacility << "', " + "using default LOCAL6"); + return LOG_LOCAL6; +} + +bool FileLogger::Log(Log::Level Level, const std::string& rFile, + int line, std::string& rMessage) +{ + if (Level > GetLevel()) + { + return true; + } + + /* avoid infinite loop if this throws an exception */ + Logging::Remove(this); + + std::ostringstream buf; + buf << FormatTime(GetCurrentBoxTime(), true, false); + buf << " "; + + if (Level <= Log::FATAL) + { + buf << "[FATAL] "; + } + else if (Level <= Log::ERROR) + { + buf << "[ERROR] "; + } + else if (Level <= Log::WARNING) + { + buf << "[WARNING] "; + } + else if (Level <= Log::NOTICE) + { + buf << "[NOTICE] "; + } + else if (Level <= Log::INFO) + { + buf << "[INFO] "; + } + else if (Level <= Log::TRACE) + { + buf << "[TRACE] "; + } + + buf << rMessage << "\n"; + std::string output = buf.str(); + + #ifdef WIN32 + ConvertUtf8ToConsole(output.c_str(), output); + #endif + + mLogFile.Write(output.c_str(), output.length()); + + Logging::Add(this); + return true; } |