NetCpp  v0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros Pages
logger.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Evidence Srl - www.evidence.eu.com
3  *
4  * Boost Software License - Version 1.0 - August 17th, 2003
5  *
6  * Permission is hereby granted, free of charge, to any person or organization
7  * obtaining a copy of the software and accompanying documentation covered by
8  * this license (the "Software") to use, reproduce, display, distribute,
9  * execute, and transmit the Software, and to prepare derivative works of the
10  * Software, and to permit third-parties to whom the Software is furnished to
11  * do so, all subject to the following:
12  *
13  * The copyright notices in the Software and this entire statement, including
14  * the above license grant, this restriction and the following disclaimer,
15  * must be included in all copies of the Software, in whole or in part, and
16  * all derivative works of the Software, unless such copies or derivative
17  * works are solely in the form of machine-executable object code generated by
18  * a source language processor.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  */
28 
29 #ifndef LOGGER_HPP_
30 #define LOGGER_HPP_
31 
32 #include <fstream>
33 #include <ostream>
34 #include <string>
35 #include <sstream>
36 #include <sys/time.h>
37 #include <mutex>
38 #include <chrono>
39 
40 /**
41  * Log levels:
42  * 0: no logging
43  * 1: log only errors messages
44  * 2: log warnings and error messages
45  * 3: log debug, warning and error messages
46  */
47 #ifndef LOG_LEVEL
48 #define LOG_LEVEL 3
49 #endif
50 
51 // Uncomment for single-thread log:
52 #define LOGGER_MULTITHREAD
53 
54 /**
55  * @brief Macro to set the file used for logging.
56  *
57  * @param Base name of the file used for logging (e.g. "/tmp/myproject")
58  *
59  * Example of configuration of the Logger: *
60  * \code
61  * LOG_FILE("/tmp/myproject);
62  * \endcode
63  */
64 #define LOG_FILE(outputFile) { \
65  log::Logger::getInstance().setFile(outputFile); \
66  }
67 
68 
69 
70 #if (LOG_LEVEL < 1) || (defined NDEBUG)
71  #define ERROR(...)
72 #else
73  /**
74  * @brief Macro to print error messages.
75  *
76  * Example of usage:
77  * \code
78  * ERROR("hello " << "world");
79  * \endcode
80  */
81  #define ERROR(msg) { \
82  std::ostringstream __debug_stream__; \
83  __debug_stream__ << "[ERROR]\t"; \
84  __debug_stream__ << msg; \
85  log::Logger::getInstance().print(__FILE__, __LINE__, \
86  __debug_stream__.str()); \
87  }
88 #endif
89 
90 #if (LOG_LEVEL < 2) || (defined NDEBUG)
91  #define WARNING(...)
92 #else
93  /**
94  * @brief Macro to print warning messages.
95  *
96  * Example of usage:
97  * \code
98  * WARNING("hello " << "world");
99  * \endcode
100  */
101  #define WARNING(msg) { \
102  std::ostringstream __debug_stream__; \
103  __debug_stream__ << "[WARNING]\t"; \
104  __debug_stream__ << msg; \
105  log::Logger::getInstance().print(__FILE__, __LINE__, \
106  __debug_stream__.str()); \
107  }
108 #endif
109 
110 
111 
112 
113 #if (LOG_LEVEL < 3) || (defined NDEBUG)
114  #define DEBUG(...)
115 #else
116  /**
117  * @brief Macro to print debug messages.
118  *
119  * Example of usage:
120  * \code
121  * DEBUG("hello " << "world");
122  * \endcode
123  */
124  #define DEBUG(msg) { \
125  std::ostringstream __debug_stream__; \
126  __debug_stream__ << "[DEBUG]\t"; \
127  __debug_stream__ << msg; \
128  log::Logger::getInstance().print(__FILE__, __LINE__, \
129  __debug_stream__.str()); \
130  }
131 #endif
132 
133 
134 
135 namespace log {
136 
137 
138 
139 /**
140  * @brief Simple logger to log messages on file and console.
141  *
142  * This is the implementation of a simple logger in C++. It is implemented
143  * as a Singleton, so it can be easily called through the DEBUG, WARNING
144  * and ERROR macros.
145  * It is Pthread-safe.
146  * It allows to log on both file and screen.
147  *
148  * Example of configuration of the Logger: *
149  * \code
150  * LOG_FILE("/tmp/myproject);
151  * \endcode
152  *
153  * Example of usage of the Logger:
154  * \code
155  * DEBUG("hello " << "world");
156  * \endcode
157  */
158 class Logger
159 {
160 public:
161  static Logger& getInstance();
162 
163  void print( const std::string& sourceFile,
164  const int codeLine,
165  const std::string& message);
166 
167  void setFile (const std::string& outputFile);
168 
169 private:
170  Logger();
171  ~Logger();
172 
173 #ifdef LOGGER_MULTITHREAD
174  /**
175  * @brief Lock for mutual exclusion between different threads
176  */
177  static std::mutex lock_;
178 #endif
179 
180  /**
181  * @brief Pointer to the unique Logger (i.e., Singleton)
182  */
183  static Logger* m_;
184 
185  /**
186  * @brief Initial part of the name of the file used for Logging.
187  *
188  * Date and time are automatically appended.
189  */
190  std::string logFile_;
191 
192  /**
193  * @brief Stream used when logging on a file
194  */
195  std::ofstream out_;
196 
197  /**
198  * @brief Initial time (used to print relative times)
199  */
200  std::chrono::time_point<std::chrono::system_clock> initialTime_;
201 
202  /**
203  * @brief Method to lock in case of multithreading
204  */
205  inline static void lock();
206 
207  /**
208  * @brief Method to unlock in case of multithreading
209  */
210  inline static void unlock();
211 };
212 
213 } // log
214 
215 #endif // LOGGER_HPP_