Pol  Revision:cb584c9
logfacility.h
Go to the documentation of this file.
1 /*
2 ATTENTION:
3 This header is part of the PCH
4 Remove the include in all StdAfx.h files or live with the consequences :)
5 */
6 
7 #ifndef CLIB_LOGFACILITY_H
8 #define CLIB_LOGFACILITY_H
9 
10 #include <format/format.h>
11 #include <boost/noncopyable.hpp>
12 #include <fstream>
13 #include <future>
14 #include <map>
15 #include <memory>
16 #include <thread>
17 #include <vector>
18 
19 #include "Debugging/LogSink.h"
20 #include "compilerspecifics.h"
21 
22 namespace Pol
23 {
24 namespace Clib
25 {
26 extern bool LogfileTimestampEveryLine;
27 
28 namespace Logging
29 {
30 struct LogFileBehaviour;
31 
32 // generic sink to log into a file
34 {
35 public:
36  LogSinkGenericFile( const LogFileBehaviour* behaviour );
38  virtual ~LogSinkGenericFile();
39  void open_log_file( bool open_timestamp );
40  void setBehaviour( const LogFileBehaviour* behaviour, std::string filename );
41  virtual void addMessage( fmt::Writer* msg ) POL_OVERRIDE;
42  virtual void addMessage( fmt::Writer* msg, const std::string& id ) POL_OVERRIDE;
43 
44 protected:
45  bool test_for_rollover( std::chrono::time_point<std::chrono::system_clock>& now );
47  std::ofstream _filestream;
48  std::string _log_filename;
49  struct tm _opened;
50  std::chrono::time_point<std::chrono::system_clock> _lasttimestamp;
52 };
53 
54 // template function to get the instance of given sink
55 template <typename Sink>
56 Sink* getSink();
57 
58 // std::cout sink
59 class LogSink_cout : public LogSink
60 {
61 public:
62  LogSink_cout();
63  virtual ~LogSink_cout(){};
64  virtual void addMessage( fmt::Writer* msg ) POL_OVERRIDE;
65  virtual void addMessage( fmt::Writer* msg, const std::string& id ) POL_OVERRIDE;
66 };
67 
68 // std::cerr sink
69 class LogSink_cerr : public LogSink
70 {
71 public:
72  LogSink_cerr();
73  virtual ~LogSink_cerr(){};
74  virtual void addMessage( fmt::Writer* msg ) POL_OVERRIDE;
75  virtual void addMessage( fmt::Writer* msg, const std::string& id ) POL_OVERRIDE;
76 };
77 
78 // pol.log (and start.log) file sink
80 {
81 public:
83  virtual ~LogSink_pollog(){};
84  void deinitialize_startlog();
85 };
86 
87 // script.log file sink
89 {
90 public:
92  virtual ~LogSink_scriptlog(){};
93 };
94 
95 // debug.log file sink
97 {
98 public:
100  virtual ~LogSink_debuglog(){};
101  virtual void addMessage( fmt::Writer* msg ) POL_OVERRIDE;
102  virtual void addMessage( fmt::Writer* msg, const std::string& id ) POL_OVERRIDE;
103  void disable();
104  static bool Disabled;
105 };
106 
107 // leak.log file sink
109 {
110 public:
111  LogSink_leaklog();
112  virtual ~LogSink_leaklog(){};
113 };
114 
115 class LogSink_flexlog : public LogSink
116 {
117 public:
118  LogSink_flexlog();
119  virtual ~LogSink_flexlog();
120  std::string create( std::string logfilename, bool open_timestamp );
121  virtual void addMessage( fmt::Writer* msg ) POL_OVERRIDE;
122  virtual void addMessage( fmt::Writer* msg, const std::string& id ) POL_OVERRIDE;
123  void close( const std::string& id );
124 
125 private:
126  std::map<std::string, std::shared_ptr<LogSinkGenericFile>> _logfiles;
127 };
128 // template class to perform a dual log eg. cout + pol.log
129 template <typename log1, typename log2>
130 class LogSink_dual : public LogSink
131 {
132 public:
133  LogSink_dual();
134  virtual ~LogSink_dual(){};
135  virtual void addMessage( fmt::Writer* msg ) POL_OVERRIDE;
136  virtual void addMessage( fmt::Writer* msg, const std::string& id ) POL_OVERRIDE;
137 };
138 
139 // main class which starts the logging
140 class LogFacility : boost::noncopyable
141 {
142 public:
143  LogFacility();
144  ~LogFacility();
145  template <typename Sink>
146  void save( fmt::Writer* message, const std::string& id );
147  void registerSink( LogSink* sink );
148  void disableDebugLog();
149  void deinitializeStartLog();
150  void closeFlexLog( const std::string& id );
151  std::string registerFlexLogger( const std::string& logfilename, bool open_timestamp );
152  void wait_for_empty_queue();
153 
154  static bool _vsDebuggerPresent;
155 
156 private:
157  class LogWorker;
158  std::unique_ptr<LogWorker> _worker;
159  std::vector<LogSink*> _registered_sinks;
160 };
161 
162 // construct a message for given sink, on deconstruction sends the msg to the facility
163 template <typename Sink>
164 class Message
165 {
166 public:
167  Message();
168  Message( const std::string& id );
169  Message(
170  const std::string& file, const int line,
171  const std::string& function ); // for internal stuff with __FILE__, __LINE__, __FUNCTION__
172  Message(
173  const std::string& id, const std::string& file, const int line,
174  const std::string& function ); // for internal stuff with __FILE__, __LINE__, __FUNCTION__
175  ~Message(); // auto flush
176 
177  fmt::Writer& message() { return *( _formater.get() ); }
178 
179 private:
180  std::unique_ptr<fmt::Writer> _formater;
181  std::string _id;
182 };
183 
184 
185 extern LogFacility* global_logger; // pointer to the instance of the main class
186 void initLogging( LogFacility* logger ); // initalize the logging
187 }
188 }
189 
190 
191 // several helper defines
192 //#define DEBUG_LOG_PRINTS
193 #ifdef DEBUG_LOG_PRINTS
194 #ifdef WINDOWS
195 #define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
196 #else
197 #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
198 #endif
199 #define LOG_PRINT_CALLER_INFO __FILENAME__, __LINE__, __FUNCTION__
200 #define LOG_PRINT_CALLER_INFO2 , __FILENAME__, __LINE__, __FUNCTION__
201 #else
202 #define LOG_PRINT_CALLER_INFO
203 #define LOG_PRINT_CALLER_INFO2
204 #endif
205 
206 // log into pol.log and std::cerr
207 #define POLLOG_ERROR \
208  Clib::Logging::Message< \
209  Clib::Logging::LogSink_dual<Clib::Logging::LogSink_cerr, Clib::Logging::LogSink_pollog>>( \
210  LOG_PRINT_CALLER_INFO ) \
211  .message()
212 // log into pol.log and std::cout
213 #define POLLOG_INFO \
214  Clib::Logging::Message< \
215  Clib::Logging::LogSink_dual<Clib::Logging::LogSink_cout, Clib::Logging::LogSink_pollog>>( \
216  LOG_PRINT_CALLER_INFO ) \
217  .message()
218 // log into pol.log
219 #define POLLOG \
220  Clib::Logging::Message<Clib::Logging::LogSink_pollog>( LOG_PRINT_CALLER_INFO ).message()
221 
222 // log only into std::cout
223 #define INFO_PRINT \
224  Clib::Logging::Message<Clib::Logging::LogSink_cout>( LOG_PRINT_CALLER_INFO ).message()
225 // log only into std::cout if level is equal or higher
226 #define INFO_PRINT_TRACE( n ) \
227  if ( Plib::systemstate.config.debug_level >= n ) \
228  INFO_PRINT
229 // log only into std::cerr
230 #define ERROR_PRINT \
231  Clib::Logging::Message<Clib::Logging::LogSink_cerr>( LOG_PRINT_CALLER_INFO ).message()
232 
233 // log into script.log
234 #define SCRIPTLOG \
235  Clib::Logging::Message<Clib::Logging::LogSink_scriptlog>( LOG_PRINT_CALLER_INFO ).message()
236 // log into debug.log (if enabled)
237 #define DEBUGLOG \
238  if ( !Clib::Logging::LogSink_debuglog::Disabled ) \
239  Clib::Logging::Message<Clib::Logging::LogSink_debuglog>( LOG_PRINT_CALLER_INFO ).message()
240 // log into leak.log
241 #define LEAKLOG \
242  Clib::Logging::Message<Clib::Logging::LogSink_leaklog>( LOG_PRINT_CALLER_INFO ).message()
243 
244 // log into sink id need a call of OPEN_LOG before
245 #define FLEXLOG( id ) \
246  Clib::Logging::Message<Clib::Logging::LogSink_flexlog>( id LOG_PRINT_CALLER_INFO2 ).message()
247 // open logfile of given filename, returns unique unsigned int for usage of logging/closing
248 #define OPEN_FLEXLOG( filename, open_timestamp ) \
249  Clib::Logging::global_logger->registerFlexLogger( filename, open_timestamp )
250 // close logfile of given id
251 #define CLOSE_FLEXLOG( id ) Clib::Logging::global_logger->closeFlexLog( id )
252 
253 // performs the switch between start.log and pol.log
254 #define DEINIT_STARTLOG Clib::Logging::global_logger->deinitializeStartLog
255 
256 // disables the debug.log
257 #define DISABLE_DEBUGLOG Clib::Logging::global_logger->disableDebugLog
258 // helper bool if the debug.log is disabled (for more complex logging) DEBUGLOG checks also
259 #define IS_DEBUGLOG_DISABLED Clib::Logging::LogSink_debuglog::Disabled
260 
261 #define GET_LOG_FILESTAMP Clib::Logging::LogSink::getTimeStamp()
262 }
263 
264 #endif // CLIB_LOGFACILITY_H
void initLogging(LogFacility *logger)
Definition: logfacility.cpp:63
#define POL_OVERRIDE
bool test_for_rollover(std::chrono::time_point< std::chrono::system_clock > &now)
std::map< std::string, std::shared_ptr< LogSinkGenericFile > > _logfiles
Definition: logfacility.h:126
bool LogfileTimestampEveryLine
Definition: logfacility.cpp:32
const LogFileBehaviour * _behaviour
Definition: logfacility.h:46
void setBehaviour(const LogFileBehaviour *behaviour, std::string filename)
std::chrono::time_point< std::chrono::system_clock > _lasttimestamp
Definition: logfacility.h:50
std::unique_ptr< LogWorker > _worker
Definition: logfacility.h:157
std::vector< LogSink * > _registered_sinks
Definition: logfacility.h:159
void open_log_file(bool open_timestamp)
virtual void addMessage(fmt::Writer *msg) POL_OVERRIDE
std::unique_ptr< fmt::Writer > _formater
Definition: logfacility.h:180
LogFacility * global_logger
Definition: logfacility.cpp:62
Definition: berror.cpp:12