i2pd/Log.cpp

134 lines
3.0 KiB
C++
Raw Normal View History

2014-08-17 09:35:09 +04:00
#include <boost/date_time/posix_time/posix_time.hpp>
#include "Log.h"
2013-12-10 17:00:13 +04:00
2014-07-02 21:48:45 +04:00
Log * g_Log = nullptr;
2014-10-28 23:36:17 +03:00
static const char * g_LogLevelStr[eNumLogLevels] =
{
"error", // eLogError
"warn", // eLogWarning
"info", // eLogInfo
"debug" // eLogDebug
};
2016-03-26 16:49:45 +03:00
#ifndef _WIN32
2016-03-26 16:40:19 +03:00
/** convert LogLevel enum to syslog priority level */
static int ToSyslogLevel(LogLevel lvl)
{
switch (lvl) {
case eLogError:
return LOG_ERR;
case eLogWarning:
return LOG_WARNING;
case eLogInfo:
return LOG_INFO;
case eLogDebug:
return LOG_DEBUG;
default:
// WTF? invalid log level?
return LOG_CRIT;
}
}
2016-03-26 16:49:45 +03:00
#endif
2016-03-26 16:40:19 +03:00
void LogMsg::Process()
{
2016-03-26 16:49:45 +03:00
#ifndef _WIN32
2016-03-26 16:40:19 +03:00
if (log && log->SyslogEnabled()) {
// only log to syslog
syslog(ToSyslogLevel(level), "%s", s.str().c_str());
return;
}
2016-03-26 16:49:45 +03:00
#endif
2016-02-04 20:36:58 +03:00
auto stream = log ? log->GetLogStream () : nullptr;
auto& output = stream ? *stream : std::cout;
if (log)
output << log->GetTimestamp ();
else
output << boost::posix_time::second_clock::local_time().time_of_day ();
output << "/" << g_LogLevelStr[level] << " - ";
output << s.str();
2014-04-23 20:49:02 +04:00
}
const std::string& Log::GetTimestamp ()
{
2015-11-20 18:02:54 +03:00
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6) && !defined(__clang__)
2015-05-07 02:18:00 +03:00
auto ts = std::chrono::monotonic_clock::now ();
#else
auto ts = std::chrono::steady_clock::now ();
2015-05-07 02:18:00 +03:00
#endif
if (ts > m_LastTimestampUpdate + std::chrono::milliseconds (500)) // 0.5 second
{
m_LastTimestampUpdate = ts;
m_Timestamp = boost::posix_time::to_simple_string (boost::posix_time::second_clock::local_time().time_of_day ());
}
return m_Timestamp;
}
2014-04-23 20:49:02 +04:00
void Log::Flush ()
{
if (m_LogStream)
m_LogStream->flush();
2014-04-23 20:49:02 +04:00
}
2016-02-29 19:02:55 +03:00
void Log::SetLogFile (const std::string& fullFilePath, bool truncate)
2014-04-24 19:10:46 +04:00
{
2016-02-04 21:53:38 +03:00
m_FullFilePath = fullFilePath;
2016-02-29 19:02:55 +03:00
auto mode = std::ofstream::out | std::ofstream::binary;
mode |= truncate ? std::ofstream::trunc : std::ofstream::app;
auto logFile = std::make_shared<std::ofstream> (fullFilePath, mode);
if (logFile->is_open ())
{
SetLogStream (logFile);
2015-12-18 17:08:35 +03:00
LogPrint(eLogInfo, "Log: will send messages to ", fullFilePath);
}
}
2016-02-04 21:53:38 +03:00
void Log::ReopenLogFile ()
{
if (m_FullFilePath.length () > 0)
{
2016-02-29 19:02:55 +03:00
SetLogFile (m_FullFilePath, false); // don't truncate
2016-02-04 21:53:38 +03:00
LogPrint(eLogInfo, "Log: file ", m_FullFilePath, " reopen");
}
}
2015-12-28 03:00:00 +03:00
void Log::SetLogLevel (const std::string& level)
{
if (level == "error") { m_MinLevel = eLogError; }
else if (level == "warn") { m_MinLevel = eLogWarning; }
else if (level == "info") { m_MinLevel = eLogInfo; }
else if (level == "debug") { m_MinLevel = eLogDebug; }
else {
LogPrint(eLogError, "Log: Unknown loglevel: ", level);
return;
}
2016-02-04 20:36:58 +03:00
LogPrint(eLogInfo, "Log: min msg level set to ", level);
2015-12-28 03:00:00 +03:00
}
2016-02-04 20:36:58 +03:00
void Log::SetLogStream (std::shared_ptr<std::ostream> logStream)
{
m_LogStream = logStream;
2014-04-24 19:10:46 +04:00
}
2016-03-26 16:40:19 +03:00
void Log::StartSyslog(const std::string & ident, const int facility)
{
2016-03-26 16:49:45 +03:00
#ifndef _WIN32
2016-03-26 16:40:19 +03:00
m_Ident = ident;
openlog(m_Ident.c_str(), LOG_PID, facility);
2016-03-26 16:49:45 +03:00
#endif
2016-03-26 16:40:19 +03:00
}
void Log::StopSyslog()
{
2016-03-26 16:49:45 +03:00
#ifndef _WIN32
2016-03-26 16:40:19 +03:00
closelog();
m_Ident.clear();
2016-03-26 16:49:45 +03:00
#endif
2016-03-26 16:40:19 +03:00
}
bool Log::SyslogEnabled()
{
return m_Ident.size() > 0;
}