Browse Source

fixed formatting

pull/1515/head
orignal 5 years ago
parent
commit
53b43353eb
  1. 472
      libi2pd/Log.h

472
libi2pd/Log.h

@ -1,236 +1,236 @@
/* /*
* Copyright (c) 2013-2016, The PurpleI2P Project * Copyright (c) 2013-2016, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
* See full license text in LICENSE file at top of project tree * See full license text in LICENSE file at top of project tree
*/ */
#ifndef LOG_H__ #ifndef LOG_H__
#define LOG_H__ #define LOG_H__
#include <ctime> #include <ctime>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <chrono> #include <chrono>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include "Queue.h" #include "Queue.h"
#ifndef _WIN32 #ifndef _WIN32
#include <syslog.h> #include <syslog.h>
#endif #endif
#ifdef WIN32_APP #ifdef WIN32_APP
#include <windows.h> // TODO: move away to win32app #include <windows.h> // TODO: move away to win32app
#endif #endif
enum LogLevel enum LogLevel
{ {
eLogNone = 0, eLogNone = 0,
eLogError, eLogError,
eLogWarning, eLogWarning,
eLogInfo, eLogInfo,
eLogDebug, eLogDebug,
eNumLogLevels eNumLogLevels
}; };
enum LogType { enum LogType {
eLogStdout = 0, eLogStdout = 0,
eLogStream, eLogStream,
eLogFile, eLogFile,
#ifndef _WIN32 #ifndef _WIN32
eLogSyslog, eLogSyslog,
#endif #endif
}; };
namespace i2p { namespace i2p {
namespace log { namespace log {
struct LogMsg; /* forward declaration */ struct LogMsg; /* forward declaration */
class Log class Log
{ {
private: private:
enum LogType m_Destination; enum LogType m_Destination;
enum LogLevel m_MinLevel; enum LogLevel m_MinLevel;
std::shared_ptr<std::ostream> m_LogStream; std::shared_ptr<std::ostream> m_LogStream;
std::string m_Logfile; std::string m_Logfile;
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;
bool m_HasColors; bool m_HasColors;
std::string m_TimeFormat; std::string m_TimeFormat;
volatile bool m_IsRunning; volatile bool m_IsRunning;
std::thread * m_Thread; std::thread * m_Thread;
private: private:
/** prevent making copies */ /** prevent making copies */
Log (const Log &); Log (const Log &);
const Log& operator=(const Log&); const Log& operator=(const Log&);
void Run (); void Run ();
void Process (std::shared_ptr<LogMsg> msg); void Process (std::shared_ptr<LogMsg> msg);
/** /**
* @brief Makes formatted string from unix timestamp * @brief Makes formatted string from unix timestamp
* @param ts Second since epoch * @param ts Second since epoch
* *
* This function internally caches the result for last provided value * This function internally caches the result for last provided value
*/ */
const char * TimeAsString(std::time_t ts); const char * TimeAsString(std::time_t ts);
public: public:
Log (); Log ();
~Log (); ~Log ();
LogType GetLogType () { return m_Destination; }; LogType GetLogType () { return m_Destination; };
LogLevel GetLogLevel () { return m_MinLevel; }; LogLevel GetLogLevel () { return m_MinLevel; };
void Start (); void Start ();
void Stop (); 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
*/ */
void SetLogLevel (const std::string& level); void SetLogLevel (const std::string& level);
/** /**
* @brief Sets log destination to logfile * @brief Sets log destination to logfile
* @param path Path to logfile * @param path Path to logfile
*/ */
void SendTo (const std::string &path); void SendTo (const std::string &path);
/** /**
* @brief Sets log destination to given output stream * @brief Sets log destination to given output stream
* @param os Output stream * @param os Output stream
*/ */
void SendTo (std::shared_ptr<std::ostream> os); void SendTo (std::shared_ptr<std::ostream> os);
/** /**
* @brief Sets format for timestamps in log * @brief Sets format for timestamps in log
* @param format String with timestamp format * @param format String with timestamp format
*/ */
void SetTimeFormat (std::string format) { m_TimeFormat = format; }; void SetTimeFormat (std::string format) { m_TimeFormat = format; };
#ifndef _WIN32 #ifndef _WIN32
/** /**
* @brief Sets log destination to syslog * @brief Sets log destination to syslog
* @param name Wanted program name * @param name Wanted program name
* @param facility Wanted log category * @param facility Wanted log category
*/ */
void SendTo (const char *name, int facility); void SendTo (const char *name, int facility);
#endif #endif
/** /**
* @brief Format log message and write to output stream/syslog * @brief Format log message and write to output stream/syslog
* @param msg Pointer to processed message * @param msg Pointer to processed message
*/ */
void Append(std::shared_ptr<i2p::log::LogMsg> &); void Append(std::shared_ptr<i2p::log::LogMsg> &);
/** @brief Reopen log file */ /** @brief Reopen log file */
void Reopen(); void Reopen();
}; };
/** /**
* @struct LogMsg * @struct LogMsg
* @brief Log message container * @brief Log message container
* *
* We creating it somewhere with LogPrint(), * We creating it somewhere with LogPrint(),
* then put in MsgQueue for later processing. * then put in MsgQueue for later processing.
*/ */
struct LogMsg { struct LogMsg {
std::time_t timestamp; std::time_t timestamp;
std::string text; /**< message text as single string */ std::string text; /**< message text as single string */
LogLevel level; /**< message level */ LogLevel level; /**< message level */
std::thread::id tid; /**< id of thread that generated message */ std::thread::id tid; /**< id of thread that generated message */
LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {};
}; };
Log & Logger(); Log & Logger();
} // log } // log
} }
/** internal usage only -- folding args array to single string */ /** internal usage only -- folding args array to single string */
template<typename TValue> template<typename TValue>
void LogPrint (std::stringstream& s, TValue&& arg) noexcept void LogPrint (std::stringstream& s, TValue&& arg) noexcept
{ {
s << std::forward<TValue>(arg); s << std::forward<TValue>(arg);
} }
#if (__cplusplus < 201703L) // below C++ 17 #if (__cplusplus < 201703L) // below C++ 17
/** internal usage only -- folding args array to single string */ /** internal usage only -- folding args array to single string */
template<typename TValue, typename... TArgs> template<typename TValue, typename... TArgs>
void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept
{ {
LogPrint (s, std::forward<TValue>(arg)); LogPrint (s, std::forward<TValue>(arg));
LogPrint (s, std::forward<TArgs>(args)...); LogPrint (s, std::forward<TArgs>(args)...);
} }
#endif #endif
/** /**
* @brief Create log message and send it to queue * @brief Create log message and send it to queue
* @param level Message level (eLogError, eLogInfo, ...) * @param level Message level (eLogError, eLogInfo, ...)
* @param args Array of message parts * @param args Array of message parts
*/ */
template<typename... TArgs> template<typename... TArgs>
void LogPrint (LogLevel level, TArgs&&... args) noexcept void LogPrint (LogLevel level, TArgs&&... args) noexcept
{ {
i2p::log::Log &log = i2p::log::Logger(); i2p::log::Log &log = i2p::log::Logger();
if (level > log.GetLogLevel ()) if (level > log.GetLogLevel ())
return; return;
// fold message to single string // fold message to single string
std::stringstream ss(""); std::stringstream ss("");
#if (__cplusplus >= 201703L) // C++ 17 or higher #if (__cplusplus >= 201703L) // C++ 17 or higher
(LogPrint (ss, std::forward<TArgs>(args)), ...); (LogPrint (ss, std::forward<TArgs>(args)), ...);
#else #else
LogPrint (ss, std::forward<TArgs>(args)...); LogPrint (ss, std::forward<TArgs>(args)...);
#endif #endif
auto msg = std::make_shared<i2p::log::LogMsg>(level, std::time(nullptr), ss.str()); auto msg = std::make_shared<i2p::log::LogMsg>(level, std::time(nullptr), ss.str());
msg->tid = std::this_thread::get_id(); msg->tid = std::this_thread::get_id();
log.Append(msg); log.Append(msg);
} }
#ifdef WIN32_APP #ifdef WIN32_APP
/** /**
* @brief Show message box for user with message in it * @brief Show message box for user with message in it
* @param level Message level (eLogError, eLogInfo, ...) * @param level Message level (eLogError, eLogInfo, ...)
* @param args Array of message parts * @param args Array of message parts
*/ */
template<typename... TArgs> template<typename... TArgs>
void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept
{ {
// fold message to single string // fold message to single string
std::stringstream ss(""); std::stringstream ss("");
#if (__cplusplus >= 201703L) // C++ 17 or higher #if (__cplusplus >= 201703L) // C++ 17 or higher
(LogPrint (ss, std::forward<TArgs>(args)), ...); (LogPrint (ss, std::forward<TArgs>(args)), ...);
#else #else
LogPrint (ss, std::forward<TArgs>(args)...); LogPrint (ss, std::forward<TArgs>(args)...);
#endif #endif
UINT uType; UINT uType;
switch (level) switch (level)
{ {
case eLogError : case eLogError :
case eLogWarning : case eLogWarning :
uType = MB_ICONWARNING; uType = MB_ICONWARNING;
break; break;
default : default :
uType = MB_ICONINFORMATION; uType = MB_ICONINFORMATION;
} }
MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK );
} }
#endif // WIN32_APP #endif // WIN32_APP
#endif // LOG_H__ #endif // LOG_H__

Loading…
Cancel
Save