DDS  ver. 3.4
Logger.h
Go to the documentation of this file.
1 // Copyright 2014 GSI, Inc. All rights reserved.
2 //
3 // Log engine core.
4 //
5 #ifndef LOGGER_H
6 #define LOGGER_H
7 
8 // BOOST
9 #ifndef BOOST_LOG_DYN_LINK
10 #define BOOST_LOG_DYN_LINK
11 #endif
12 #include <boost/date_time/posix_time/posix_time_types.hpp>
13 
14 #if BOOST_VERSION < 105700
15 #pragma clang diagnostic push
16 #pragma clang diagnostic ignored "-Wdeprecated-register"
17 #endif
18 
19 #pragma clang diagnostic push
20 #pragma clang diagnostic ignored "-Wunused-local-typedef"
21 #include <boost/log/expressions.hpp>
22 #include <boost/log/support/date_time.hpp>
23 #pragma clang diagnostic pop
24 
25 #include <boost/log/attributes/current_process_id.hpp>
26 #include <boost/log/attributes/current_process_name.hpp>
27 #include <boost/log/attributes/current_thread_id.hpp>
28 #include <boost/log/sources/global_logger_storage.hpp>
29 #include <boost/log/sources/logger.hpp>
30 #include <boost/log/sources/record_ostream.hpp>
31 #include <boost/log/sources/severity_logger.hpp>
32 #include <boost/log/utility/setup/common_attributes.hpp>
33 #include <boost/log/utility/setup/console.hpp>
34 #include <boost/log/utility/setup/file.hpp>
35 #if BOOST_VERSION < 105700
36 #pragma clang diagnostic pop
37 #endif
38 // STD
39 #include <fstream>
40 #include <ostream>
41 
42 // DDS
43 #include "SysHelper.h"
44 #include "UserDefaults.h"
45 #include "def.h"
46 
47 // Main macro to be used for logging in DDS
48 // Example: LOG(info) << "My message";
49 //
50 // WORKAROUND: a bug in 1.59 version
51 // https://svn.boost.org/trac/boost/ticket/11549
52 //
53 #if BOOST_VERSION == 105900
54 #define LOG(severity) BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), severity) << ""
55 #else
56 #define LOG(severity) BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), severity)
57 #endif
58 
59 // Convenience functions
60 #define P_H BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::proto_high)
61 #define P_M BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::proto_mid)
62 #define P_L BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::proto_low)
63 #define DBG BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::debug)
64 #define INF BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::info)
65 #define WRN BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::warning)
66 #define ERR BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::error)
67 #define FAT BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::fatal)
68 #define STDOUT BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::log_stdout)
69 #define STDOUT_CLEAN BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::log_stdout_clean)
70 #define STDERR BOOST_LOG_SEV(MiscCommon::Logger::instance().logger(), MiscCommon::log_stderr)
71 
72 namespace MiscCommon
73 {
75 
76  class Logger
77  {
78  private:
79  typedef boost::shared_ptr<boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>> fileSink_t;
80 
81  public:
82  typedef boost::log::sources::severity_logger_mt<ELogSeverityLevel> logger_t;
83 
85  static Logger& instance()
86  {
87  static Logger instance;
88  return instance;
89  }
90 
91  logger_t& logger()
92  {
93  return fLogger;
94  }
95 
97  void init()
98  {
99  static bool bStarted = false;
100  if (bStarted)
101  return;
102 
103  bStarted = true;
104 
105  using namespace boost::log;
106 
107  const dds::user_defaults_api::CUserDefaults& userDefaults =
109 
110  unsigned int hasConsoleOutput = userDefaults.getOptions().m_server.m_logHasConsoleOutput;
111 
112  m_fileSink = createFileSink();
113 
114  // Logging to console
115  typedef boost::shared_ptr<sinks::synchronous_sink<sinks::text_ostream_backend>> ostreamSink_t;
116  ostreamSink_t stdoutSink = add_console_log(std::cout, keywords::format = "%Process%: %Message%");
117  ostreamSink_t stdoutCleanSink = add_console_log(std::cout, keywords::format = "%Message%");
118  ostreamSink_t stderrSink = add_console_log(std::cerr, keywords::format = "%Process%: error: %Message%");
119 
120  stdoutSink->set_filter(severity == log_stdout && hasConsoleOutput);
121  stdoutCleanSink->set_filter(severity == log_stdout_clean && hasConsoleOutput);
122  stderrSink->set_filter(severity == log_stderr && hasConsoleOutput);
123 
124  add_common_attributes();
125  core::get()->add_global_attribute("Process", attributes::current_process_name());
126 
127  LOG(info) << "Log engine is initialized with severety \""
128  << userDefaults.getOptions().m_server.m_logSeverityLevel << "\"";
129  }
130 
131  void reinit()
132  {
133  boost::log::core::get()->remove_sink(m_fileSink);
134  m_fileSink.reset();
135  m_fileSink = createFileSink();
136  }
137 
138  private:
139  fileSink_t createFileSink() const
140  {
141  using namespace boost::log;
142 
143  const dds::user_defaults_api::CUserDefaults& userDefaults =
145  unsigned int severityLevel = userDefaults.getOptions().m_server.m_logSeverityLevel;
146  unsigned int rotationSize = userDefaults.getOptions().m_server.m_logRotationSize;
147  std::string sLogFile = userDefaults.getLogFile();
148 
149  // Default format for logger
150  formatter formatter =
151  // TODO: std::setw doesn't work for the first collumn of the log (TimeStamp). Investigate!
152  expressions::stream << std::left
153  << expressions::format_date_time<boost::posix_time::ptime>("TimeStamp",
154  "%Y-%m-%d %H:%M:%S.%f")
155  << " " << std::setw(7) << expressions::attr<ELogSeverityLevel>("Severity")
156  << std::setw(20) << expressions::attr<std::string>("Process") << " <"
157  << expressions::attr<attributes::current_process_id::value_type>("ProcessID") << ":"
158  << expressions::attr<attributes::current_thread_id::value_type>("ThreadID")
159  << "> " << expressions::smessage;
160 
161  fileSink_t fileSink =
162  add_file_log(keywords::file_name = sLogFile,
163  keywords::open_mode = (std::ios::out | std::ios::app),
164  keywords::rotation_size = rotationSize * 1024 * 1024,
165  // rotate at midnight every day
166  keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
167  // log collector,
168  // -- maximum total size of the stored log files is 1GB.
169  // -- minimum free space on the drive is 2GB
170  keywords::max_size = 1000 * 1024 * 1024,
171  keywords::min_free_space = 2000 * 1024 * 1024,
172  keywords::auto_flush = true);
173 
174  fileSink->set_formatter(formatter);
175  fileSink->set_filter(severity >= severityLevel);
176 
177  return fileSink;
178  }
179 
180  private:
181  logger_t fLogger;
182 
183  fileSink_t m_fileSink;
184  };
185 }; // namespace MiscCommon
186 #endif
Definition: def.h:156
Definition: def.h:154
ELogSeverityLevel
Log Severity levels.
Definition: def.h:144
std::string getLogFile() const
Definition: UserDefaults.cpp:352
Definition: def.h:155
const SDDSUserDefaultsOptions_t getOptions() const
Definition: UserDefaults.cpp:249
#define LOG(severity)
Definition: Logger.h:56
unsigned int m_logRotationSize
True if output log also to console.
Definition: dds-user-defaults/src/Options.h:30
bool m_logHasConsoleOutput
Idle time in [s] after which process will be killed by monitoring thread.
Definition: dds-user-defaults/src/Options.h:32
Definition: UserDefaults.h:21
static CUserDefaults & instance(const boost::uuids::uuid &_sid=CUserDefaults::getInitialSID())
Return singleton instance.
Definition: UserDefaults.cpp:36
MiscCommon::ELogSeverityLevel m_logSeverityLevel
Log rotation size in MB.
Definition: dds-user-defaults/src/Options.h:28
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", ELogSeverityLevel) class Logger
Definition: Logger.h:74
Definition: def.h:150
SDDSServerOptions m_server
Definition: dds-user-defaults/src/Options.h:46
Miscellaneous functions and helpers are located here.
Definition: BOOST_FILESYSTEM.h:21