summaryrefslogtreecommitdiff
path: root/lib/common/Logging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common/Logging.cpp')
-rw-r--r--lib/common/Logging.cpp233
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;
}