mirror of https://github.com/PurpleI2P/i2pd.git
I2P: End-to-End encrypted and anonymous Internet
https://i2pd.website/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.0 KiB
133 lines
3.0 KiB
#include <boost/date_time/posix_time/posix_time.hpp> |
|
#include "Log.h" |
|
|
|
Log * g_Log = nullptr; |
|
|
|
static const char * g_LogLevelStr[eNumLogLevels] = |
|
{ |
|
"error", // eLogError |
|
"warn", // eLogWarning |
|
"info", // eLogInfo |
|
"debug" // eLogDebug |
|
}; |
|
#ifndef _WIN32 |
|
/** 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; |
|
} |
|
} |
|
#endif |
|
|
|
void LogMsg::Process() |
|
{ |
|
#ifndef _WIN32 |
|
if (log && log->SyslogEnabled()) { |
|
// only log to syslog |
|
syslog(ToSyslogLevel(level), "%s", s.str().c_str()); |
|
return; |
|
} |
|
#endif |
|
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(); |
|
} |
|
|
|
const std::string& Log::GetTimestamp () |
|
{ |
|
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6) && !defined(__clang__) |
|
auto ts = std::chrono::monotonic_clock::now (); |
|
#else |
|
auto ts = std::chrono::steady_clock::now (); |
|
#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; |
|
} |
|
|
|
void Log::Flush () |
|
{ |
|
if (m_LogStream) |
|
m_LogStream->flush(); |
|
} |
|
|
|
void Log::SetLogFile (const std::string& fullFilePath, bool truncate) |
|
{ |
|
m_FullFilePath = fullFilePath; |
|
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); |
|
LogPrint(eLogInfo, "Log: will send messages to ", fullFilePath); |
|
} |
|
} |
|
|
|
void Log::ReopenLogFile () |
|
{ |
|
if (m_FullFilePath.length () > 0) |
|
{ |
|
SetLogFile (m_FullFilePath, false); // don't truncate |
|
LogPrint(eLogInfo, "Log: file ", m_FullFilePath, " reopen"); |
|
} |
|
} |
|
|
|
|
|
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; |
|
} |
|
LogPrint(eLogInfo, "Log: min msg level set to ", level); |
|
} |
|
|
|
void Log::SetLogStream (std::shared_ptr<std::ostream> logStream) |
|
{ |
|
m_LogStream = logStream; |
|
} |
|
|
|
void Log::StartSyslog(const std::string & ident, const int facility) |
|
{ |
|
#ifndef _WIN32 |
|
m_Ident = ident; |
|
openlog(m_Ident.c_str(), LOG_PID, facility); |
|
#endif |
|
} |
|
|
|
void Log::StopSyslog() |
|
{ |
|
#ifndef _WIN32 |
|
closelog(); |
|
m_Ident.clear(); |
|
#endif |
|
} |
|
|
|
bool Log::SyslogEnabled() |
|
{ |
|
return m_Ident.size() > 0; |
|
}
|
|
|