mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
write to log through the separate thread
This commit is contained in:
parent
164d3566e3
commit
d91691c344
@ -113,7 +113,7 @@ namespace i2p
|
|||||||
} else {
|
} else {
|
||||||
// use stdout -- default
|
// use stdout -- default
|
||||||
}
|
}
|
||||||
i2p::log::Logger().Ready();
|
i2p::log::Logger().Start();
|
||||||
|
|
||||||
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
||||||
LogPrint(eLogDebug, "FS: main config file: ", config);
|
LogPrint(eLogDebug, "FS: main config file: ", config);
|
||||||
@ -351,6 +351,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
i2p::crypto::TerminateCrypto ();
|
i2p::crypto::TerminateCrypto ();
|
||||||
|
i2p::log::Logger().Stop();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
96
Log.cpp
96
Log.cpp
@ -58,13 +58,29 @@ namespace log {
|
|||||||
|
|
||||||
Log::Log():
|
Log::Log():
|
||||||
m_Destination(eLogStdout), m_MinLevel(eLogInfo),
|
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 ()
|
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
|
#ifndef _WIN32
|
||||||
case eLogSyslog :
|
case eLogSyslog :
|
||||||
closelog();
|
closelog();
|
||||||
@ -78,7 +94,14 @@ namespace log {
|
|||||||
/* do nothing */
|
/* do nothing */
|
||||||
break;
|
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) {
|
void Log::SetLogLevel (const std::string& level) {
|
||||||
@ -106,45 +129,52 @@ namespace log {
|
|||||||
* Unfortunately, with current startup process with late fork() this
|
* Unfortunately, with current startup process with late fork() this
|
||||||
* will give us nothing but pain. Maybe later. See in NetDb as example.
|
* will give us nothing but pain. Maybe later. See in NetDb as example.
|
||||||
*/
|
*/
|
||||||
void Log::Process() {
|
void Log::Process(std::shared_ptr<LogMsg> msg)
|
||||||
std::unique_lock<std::mutex> l(m_OutputLock);
|
{
|
||||||
|
if (!msg) return;
|
||||||
std::hash<std::thread::id> hasher;
|
std::hash<std::thread::id> hasher;
|
||||||
unsigned short short_tid;
|
unsigned short short_tid;
|
||||||
while (1) {
|
short_tid = (short) (hasher(msg->tid) % 1000);
|
||||||
auto msg = m_Queue.GetNextWithTimeout (1);
|
switch (m_Destination) {
|
||||||
if (!msg)
|
|
||||||
break;
|
|
||||||
short_tid = (short) (hasher(msg->tid) % 1000);
|
|
||||||
switch (m_Destination) {
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
case eLogSyslog:
|
case eLogSyslog:
|
||||||
syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
|
syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case eLogFile:
|
case eLogFile:
|
||||||
case eLogStream:
|
case eLogStream:
|
||||||
if (m_LogStream)
|
if (m_LogStream)
|
||||||
*m_LogStream << TimeAsString(msg->timestamp)
|
*m_LogStream << TimeAsString(msg->timestamp)
|
||||||
<< "@" << short_tid
|
|
||||||
<< "/" << g_LogLevelStr[msg->level]
|
|
||||||
<< " - " << msg->text << std::endl;
|
|
||||||
break;
|
|
||||||
case eLogStdout:
|
|
||||||
default:
|
|
||||||
std::cout << TimeAsString(msg->timestamp)
|
|
||||||
<< "@" << short_tid
|
<< "@" << short_tid
|
||||||
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
|
<< "/" << g_LogLevelStr[msg->level]
|
||||||
<< " - " << msg->text << std::endl;
|
<< " - " << msg->text << std::endl;
|
||||||
break;
|
break;
|
||||||
} // switch
|
case eLogStdout:
|
||||||
} // while
|
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);
|
m_Queue.Put(msg);
|
||||||
if (!m_IsReady)
|
|
||||||
return;
|
|
||||||
Process();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::SendTo (const std::string& path)
|
void Log::SendTo (const std::string& path)
|
||||||
|
20
Log.h
20
Log.h
@ -16,6 +16,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
#include "Queue.h"
|
#include "Queue.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@ -56,9 +57,9 @@ namespace log {
|
|||||||
std::time_t m_LastTimestamp;
|
std::time_t m_LastTimestamp;
|
||||||
char m_LastDateTime[64];
|
char m_LastDateTime[64];
|
||||||
i2p::util::Queue<std::shared_ptr<LogMsg> > m_Queue;
|
i2p::util::Queue<std::shared_ptr<LogMsg> > m_Queue;
|
||||||
volatile bool m_IsReady;
|
|
||||||
bool m_HasColors;
|
bool m_HasColors;
|
||||||
mutable std::mutex m_OutputLock;
|
volatile bool m_IsRunning;
|
||||||
|
std::thread * m_Thread;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -66,10 +67,8 @@ namespace log {
|
|||||||
Log (const Log &);
|
Log (const Log &);
|
||||||
const Log& operator=(const Log&);
|
const Log& operator=(const Log&);
|
||||||
|
|
||||||
/**
|
void Run ();
|
||||||
* @brief process stored messages in queue
|
void Process (std::shared_ptr<LogMsg> msg);
|
||||||
*/
|
|
||||||
void Process ();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Makes formatted string from unix timestamp
|
* @brief Makes formatted string from unix timestamp
|
||||||
@ -87,6 +86,9 @@ namespace log {
|
|||||||
LogType GetLogType () { return m_Destination; };
|
LogType GetLogType () { return m_Destination; };
|
||||||
LogLevel GetLogLevel () { return m_MinLevel; };
|
LogLevel GetLogLevel () { return m_MinLevel; };
|
||||||
|
|
||||||
|
void Start ();
|
||||||
|
void Stop ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets minimal allowed level for log messages
|
* @brief Sets minimal allowed level for log messages
|
||||||
* @param level String with wanted minimal msg level
|
* @param level String with wanted minimal msg level
|
||||||
@ -120,12 +122,6 @@ namespace log {
|
|||||||
*/
|
*/
|
||||||
void Append(std::shared_ptr<i2p::log::LogMsg> &);
|
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 */
|
/** @brief Reopen log file */
|
||||||
void Reopen();
|
void Reopen();
|
||||||
};
|
};
|
||||||
|
3
api.cpp
3
api.cpp
@ -47,7 +47,7 @@ namespace api
|
|||||||
i2p::log::Logger().SendTo (logStream);
|
i2p::log::Logger().SendTo (logStream);
|
||||||
else
|
else
|
||||||
i2p::log::Logger().SendTo (i2p::fs::DataDirPath (i2p::fs::GetAppName () + ".log"));
|
i2p::log::Logger().SendTo (i2p::fs::DataDirPath (i2p::fs::GetAppName () + ".log"));
|
||||||
i2p::log::Logger().Ready();
|
i2p::log::Logger().Start ();
|
||||||
LogPrint(eLogInfo, "API: starting NetDB");
|
LogPrint(eLogInfo, "API: starting NetDB");
|
||||||
i2p::data::netdb.Start();
|
i2p::data::netdb.Start();
|
||||||
LogPrint(eLogInfo, "API: starting Transports");
|
LogPrint(eLogInfo, "API: starting Transports");
|
||||||
@ -65,6 +65,7 @@ namespace api
|
|||||||
i2p::transport::transports.Stop();
|
i2p::transport::transports.Stop();
|
||||||
LogPrint(eLogInfo, "API: stopping NetDB");
|
LogPrint(eLogInfo, "API: stopping NetDB");
|
||||||
i2p::data::netdb.Stop();
|
i2p::data::netdb.Stop();
|
||||||
|
i2p::log::Logger().Stop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunPeerTest ()
|
void RunPeerTest ()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user