Log.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright (c) 2013-2016, The PurpleI2P Project
  3. *
  4. * This file is part of Purple i2pd project and licensed under BSD3
  5. *
  6. * See full license text in LICENSE file at top of project tree
  7. */
  8. #ifndef LOG_H__
  9. #define LOG_H__
  10. #include <ctime>
  11. #include <string>
  12. #include <iostream>
  13. #include <fstream>
  14. #include <sstream>
  15. #include <chrono>
  16. #include <memory>
  17. #include <thread>
  18. #include "Queue.h"
  19. #ifndef _WIN32
  20. #include <syslog.h>
  21. #endif
  22. enum LogLevel
  23. {
  24. eLogNone = 0,
  25. eLogError,
  26. eLogWarning,
  27. eLogInfo,
  28. eLogDebug,
  29. eNumLogLevels
  30. };
  31. enum LogType {
  32. eLogStdout = 0,
  33. eLogStream,
  34. eLogFile,
  35. #ifndef _WIN32
  36. eLogSyslog,
  37. #endif
  38. };
  39. namespace i2p {
  40. namespace log {
  41. struct LogMsg; /* forward declaration */
  42. class Log
  43. {
  44. private:
  45. enum LogType m_Destination;
  46. enum LogLevel m_MinLevel;
  47. std::shared_ptr<std::ostream> m_LogStream;
  48. std::string m_Logfile;
  49. std::time_t m_LastTimestamp;
  50. char m_LastDateTime[64];
  51. i2p::util::Queue<std::shared_ptr<LogMsg> > m_Queue;
  52. bool m_HasColors;
  53. std::string m_TimeFormat;
  54. volatile bool m_IsRunning;
  55. std::thread * m_Thread;
  56. private:
  57. /** prevent making copies */
  58. Log (const Log &);
  59. const Log& operator=(const Log&);
  60. void Run ();
  61. void Process (std::shared_ptr<LogMsg> msg);
  62. /**
  63. * @brief Makes formatted string from unix timestamp
  64. * @param ts Second since epoch
  65. *
  66. * This function internally caches the result for last provided value
  67. */
  68. const char * TimeAsString(std::time_t ts);
  69. public:
  70. Log ();
  71. ~Log ();
  72. LogType GetLogType () { return m_Destination; };
  73. LogLevel GetLogLevel () { return m_MinLevel; };
  74. void Start ();
  75. void Stop ();
  76. /**
  77. * @brief Sets minimal allowed level for log messages
  78. * @param level String with wanted minimal msg level
  79. */
  80. void SetLogLevel (const std::string& level);
  81. /**
  82. * @brief Sets log destination to logfile
  83. * @param path Path to logfile
  84. */
  85. void SendTo (const std::string &path);
  86. /**
  87. * @brief Sets log destination to given output stream
  88. * @param os Output stream
  89. */
  90. void SendTo (std::shared_ptr<std::ostream> os);
  91. /**
  92. * @brief Sets format for timestamps in log
  93. * @param format String with timestamp format
  94. */
  95. void SetTimeFormat (std::string format) { m_TimeFormat = format; };
  96. #ifndef _WIN32
  97. /**
  98. * @brief Sets log destination to syslog
  99. * @param name Wanted program name
  100. * @param facility Wanted log category
  101. */
  102. void SendTo (const char *name, int facility);
  103. #endif
  104. /**
  105. * @brief Format log message and write to output stream/syslog
  106. * @param msg Pointer to processed message
  107. */
  108. void Append(std::shared_ptr<i2p::log::LogMsg> &);
  109. /** @brief Reopen log file */
  110. void Reopen();
  111. };
  112. /**
  113. * @struct LogMsg
  114. * @brief Log message container
  115. *
  116. * We creating it somewhere with LogPrint(),
  117. * then put in MsgQueue for later processing.
  118. */
  119. struct LogMsg {
  120. std::time_t timestamp;
  121. std::string text; /**< message text as single string */
  122. LogLevel level; /**< message level */
  123. std::thread::id tid; /**< id of thread that generated message */
  124. LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {};
  125. };
  126. Log & Logger();
  127. } // log
  128. }
  129. /** internal usage only -- folding args array to single string */
  130. template<typename TValue>
  131. void LogPrint (std::stringstream& s, TValue&& arg) noexcept
  132. {
  133. s << std::forward<TValue>(arg);
  134. }
  135. /** internal usage only -- folding args array to single string */
  136. template<typename TValue, typename... TArgs>
  137. void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept
  138. {
  139. LogPrint (s, std::forward<TValue>(arg));
  140. LogPrint (s, std::forward<TArgs>(args)...);
  141. }
  142. /**
  143. * @brief Create log message and send it to queue
  144. * @param level Message level (eLogError, eLogInfo, ...)
  145. * @param args Array of message parts
  146. */
  147. template<typename... TArgs>
  148. void LogPrint (LogLevel level, TArgs&&... args) noexcept
  149. {
  150. i2p::log::Log &log = i2p::log::Logger();
  151. if (level > log.GetLogLevel ())
  152. return;
  153. // fold message to single string
  154. std::stringstream ss("");
  155. LogPrint (ss, std::forward<TArgs>(args)...);
  156. auto msg = std::make_shared<i2p::log::LogMsg>(level, std::time(nullptr), ss.str());
  157. msg->tid = std::this_thread::get_id();
  158. log.Append(msg);
  159. }
  160. #endif // LOG_H__