Browse Source

write to log through the separate thread

pull/718/head
orignal 8 years ago
parent
commit
d91691c344
  1. 3
      Daemon.cpp
  2. 96
      Log.cpp
  3. 20
      Log.h
  4. 3
      api.cpp

3
Daemon.cpp

@ -113,7 +113,7 @@ namespace i2p @@ -113,7 +113,7 @@ namespace i2p
} else {
// use stdout -- default
}
i2p::log::Logger().Ready();
i2p::log::Logger().Start();
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
LogPrint(eLogDebug, "FS: main config file: ", config);
@ -351,6 +351,7 @@ namespace i2p @@ -351,6 +351,7 @@ namespace i2p
}
#endif
i2p::crypto::TerminateCrypto ();
i2p::log::Logger().Stop();
return true;
}

96
Log.cpp

@ -58,13 +58,29 @@ namespace log { @@ -58,13 +58,29 @@ namespace log {
Log::Log():
m_Destination(eLogStdout), m_MinLevel(eLogInfo),
m_LogStream (nullptr), m_Logfile(""), m_IsReady(false), m_HasColors(true)
m_LogStream (nullptr), m_Logfile(""), m_HasColors(true),
m_IsRunning (false), m_Thread (nullptr)
{
}
Log::~Log ()
{
switch (m_Destination) {
delete m_Thread;
}
void Log::Start ()
{
if (!m_IsRunning)
{
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Log::Run, this));
}
}
void Log::Stop ()
{
switch (m_Destination)
{
#ifndef _WIN32
case eLogSyslog :
closelog();
@ -78,7 +94,14 @@ namespace log { @@ -78,7 +94,14 @@ namespace log {
/* do nothing */
break;
}
Process();
m_IsRunning = false;
m_Queue.WakeUp ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
void Log::SetLogLevel (const std::string& level) {
@ -106,45 +129,52 @@ namespace log { @@ -106,45 +129,52 @@ namespace log {
* Unfortunately, with current startup process with late fork() this
* will give us nothing but pain. Maybe later. See in NetDb as example.
*/
void Log::Process() {
std::unique_lock<std::mutex> l(m_OutputLock);
void Log::Process(std::shared_ptr<LogMsg> msg)
{
if (!msg) return;
std::hash<std::thread::id> hasher;
unsigned short short_tid;
while (1) {
auto msg = m_Queue.GetNextWithTimeout (1);
if (!msg)
break;
short_tid = (short) (hasher(msg->tid) % 1000);
switch (m_Destination) {
short_tid = (short) (hasher(msg->tid) % 1000);
switch (m_Destination) {
#ifndef _WIN32
case eLogSyslog:
syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
break;
case eLogSyslog:
syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
break;
#endif
case eLogFile:
case eLogStream:
if (m_LogStream)
*m_LogStream << TimeAsString(msg->timestamp)
<< "@" << short_tid
<< "/" << g_LogLevelStr[msg->level]
<< " - " << msg->text << std::endl;
break;
case eLogStdout:
default:
std::cout << TimeAsString(msg->timestamp)
case eLogFile:
case eLogStream:
if (m_LogStream)
*m_LogStream << TimeAsString(msg->timestamp)
<< "@" << short_tid
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
<< "/" << g_LogLevelStr[msg->level]
<< " - " << msg->text << std::endl;
break;
} // switch
} // while
break;
case eLogStdout:
default:
std::cout << TimeAsString(msg->timestamp)
<< "@" << short_tid
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
<< " - " << msg->text << std::endl;
break;
} // switch
}
void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg) {
void Log::Run ()
{
while (m_IsRunning)
{
std::shared_ptr<LogMsg> msg;
while (msg = m_Queue.Get ())
Process (msg);
if (m_LogStream) m_LogStream->flush();
if (m_IsRunning)
m_Queue.Wait ();
}
}
void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg)
{
m_Queue.Put(msg);
if (!m_IsReady)
return;
Process();
}
void Log::SendTo (const std::string& path)

20
Log.h

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
#include <sstream>
#include <chrono>
#include <memory>
#include <thread>
#include "Queue.h"
#ifndef _WIN32
@ -56,9 +57,9 @@ namespace log { @@ -56,9 +57,9 @@ namespace log {
std::time_t m_LastTimestamp;
char m_LastDateTime[64];
i2p::util::Queue<std::shared_ptr<LogMsg> > m_Queue;
volatile bool m_IsReady;
bool m_HasColors;
mutable std::mutex m_OutputLock;
volatile bool m_IsRunning;
std::thread * m_Thread;
private:
@ -66,10 +67,8 @@ namespace log { @@ -66,10 +67,8 @@ namespace log {
Log (const Log &);
const Log& operator=(const Log&);
/**
* @brief process stored messages in queue
*/
void Process ();
void Run ();
void Process (std::shared_ptr<LogMsg> msg);
/**
* @brief Makes formatted string from unix timestamp
@ -87,6 +86,9 @@ namespace log { @@ -87,6 +86,9 @@ namespace log {
LogType GetLogType () { return m_Destination; };
LogLevel GetLogLevel () { return m_MinLevel; };
void Start ();
void Stop ();
/**
* @brief Sets minimal allowed level for log messages
* @param level String with wanted minimal msg level
@ -120,12 +122,6 @@ namespace log { @@ -120,12 +122,6 @@ namespace log {
*/
void Append(std::shared_ptr<i2p::log::LogMsg> &);
/** @brief Allow log output */
void Ready() { m_IsReady = true; }
/** @brief Flushes the output log stream */
void Flush();
/** @brief Reopen log file */
void Reopen();
};

3
api.cpp

@ -47,7 +47,7 @@ namespace api @@ -47,7 +47,7 @@ namespace api
i2p::log::Logger().SendTo (logStream);
else
i2p::log::Logger().SendTo (i2p::fs::DataDirPath (i2p::fs::GetAppName () + ".log"));
i2p::log::Logger().Ready();
i2p::log::Logger().Start ();
LogPrint(eLogInfo, "API: starting NetDB");
i2p::data::netdb.Start();
LogPrint(eLogInfo, "API: starting Transports");
@ -65,6 +65,7 @@ namespace api @@ -65,6 +65,7 @@ namespace api
i2p::transport::transports.Stop();
LogPrint(eLogInfo, "API: stopping NetDB");
i2p::data::netdb.Stop();
i2p::log::Logger().Stop ();
}
void RunPeerTest ()

Loading…
Cancel
Save