Merge pull request #43 from tripzero/master
[profile/ivi/automotive-message-broker.git] / plugins / common / logger.h
1 /*
2 Copyright (C) 2012 Intel Corporation
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #ifndef LOGGER_H
20 #define LOGGER_H
21
22 #include <fstream>
23 #include <ostream>
24 #include <string>
25 #include <sstream>
26 #include <sys/time.h>
27 #include <sys/types.h>
28
29 // Comment this line if you don't need multithread support
30 #define LOGGER_MULTITHREAD
31 #ifdef LOGGER_MULTITHREAD
32 #include <pthread.h>
33 #endif
34
35 /** \addtogroup libamb-plugins-common
36  *  @{
37  */
38
39 namespace CUtil {
40
41 /**
42  * \brief Simple logger to log messages on file and console.
43  *
44  * This is the implementation of a simple logger in C++. It is implemented
45  * as a Singleton, so it can be easily called through two DEBUG macros.
46  * It is Pthread-safe.
47  * It allows to log on both file and screen, and to specify a verbosity
48  * threshold for both of them.
49  *
50  * @class Logger
51  */
52 class Logger
53 {
54         /**
55          * Type used for the configuration
56          */
57         enum loggerConf_        {L_nofile_      =       1 << 0,
58                                 L_file_         =       1 << 1,
59                                 L_noscreen_     =       1 << 2,
60                                 L_screen_       =       1 << 3};
61
62 #ifdef LOGGER_MULTITHREAD
63         /**
64          * \brief Lock for mutual exclusion between different threads
65          */
66         static pthread_mutex_t lock_;
67 #endif
68
69         bool configured_;
70
71         /**
72          * \brief Pointer to the unique Logger (i.e., Singleton)
73          */
74         static Logger* m_;
75
76         /**
77          * \brief Initial part of the name of the file used for Logging.
78          * Date and time are automatically appended.
79          */
80         std::string logFile_;
81
82         /**
83          * \brief Initial part of the name of the file used for Logging.
84          * Date and time are automatically appended.
85          */
86         std::string logFileName_;
87
88         /**
89          * \brief Current configuration of the logger.
90          * Variable to know if logging on file and on screen are enabled.
91          * Note that if the log on file is enabled, it means that the
92          * logger has been already configured, therefore the stream is
93          * already open.
94          */
95         loggerConf_ configuration_;
96
97         /**
98          * \brief Stream used when logging on a file
99          */
100         std::ofstream out_;
101
102         /**
103          * \brief Initial time (used to print relative times)
104          */
105         int64_t initialTime_usec_;
106
107         /**
108          * \brief Verbosity threshold for files
109          */
110         unsigned int fileVerbosityLevel_;
111
112         /**
113          * \brief Verbosity threshold for screen
114          */
115         unsigned int screenVerbosityLevel_;
116
117         Logger();
118         ~Logger();
119
120         /**
121          * \brief Method to lock in case of multithreading
122          */
123         inline static void lock();
124
125         /**
126          * \brief Method to unlock in case of multithreading
127          */
128         inline static void unlock();
129
130 public:
131
132         /**
133         * Logging level
134         * \enum Level
135         * \public
136         */
137         enum Level {
138                 EError = 0,
139                 EWarning,
140                 EMessage,
141                 EInfo,
142                 ETrace,
143                 EDebug
144         };
145
146         /**
147          * Macro to create and configure logger.
148          * \def DEBUG_CONF
149          *
150          * Example of configuration of the Logger:
151          * \code
152          *      DEBUG_CONF("outputfile", Logger::file_on|Logger::screen_on, DBG_DEBUG, DBG_ERROR);
153          * \endcode
154          */
155         #define DEBUG_CONF(outputFile, \
156                         configuration, \
157                         fileVerbosityLevel, \
158                         screenVerbosityLevel) { \
159                                 CUtil::Logger::getInstance().configure(outputFile, \
160                                                         configuration, \
161                                                         fileVerbosityLevel, \
162                                                         screenVerbosityLevel); \
163                         }
164
165         /**
166          * \brief Macro to print log messages.
167          * \def LOGGER
168          *
169          * Example of usage of the Logger:
170          * \code
171          *      LOGGER(DBG_DEBUG, "hello " << "world");
172          * \endcode
173          */
174         #define LOGGER(priority, msg) { \
175                 std::ostringstream __debug_stream__; \
176                 __debug_stream__ << msg; \
177                 CUtil::Logger::getInstance().print(priority, __FILE__, __LINE__, \
178                                 __debug_stream__.str()); \
179                 }
180
181         #ifndef _LOGGER_NO_LOG
182
183         /**
184          * Macro to log errors.
185          * \def LOG_ERROR
186          */
187         #define LOG_ERROR(M)        LOGGER(CUtil::Logger::EError, M)
188         /**
189          * Macro to log warnings.
190          * \def LOG_WARNING
191          */
192         #define LOG_WARNING(M)      LOGGER(CUtil::Logger::EWarning, M)
193         /**
194          * Macro to log messages.
195          * \def LOG_MESSAGE
196          */
197         #define LOG_MESSAGE(M)      LOGGER(CUtil::Logger::EMessage, M)
198         /**
199          * Macro to log info messages.
200          * \def LOG_INFO
201          */
202         #define LOG_INFO(M)         LOGGER(CUtil::Logger::EInfo, M)
203         /**
204          * Macro to log trace messages.
205          * \def LOG_TRACE
206          */
207         #define LOG_TRACE(M)        LOGGER(CUtil::Logger::ETrace, M)
208         /**
209          * Macro to log debug messages.
210          * \def LOG_DEBUG
211          */
212         #define LOG_DEBUG(M)        LOGGER(CUtil::Logger::EDebug, M)
213
214         #else
215
216         #define LOG_ERROR(M)        {}
217         #define LOG_WARNING(M)      {}
218         #define LOG_MESSAGE(M)      {}
219         #define LOG_INFO(M)         {}
220         #define LOG_TRACE(M)        {}
221         #define LOG_DEBUG(M)        {}
222
223         #endif
224
225         /**
226          * Type used for the configuration
227          */
228         typedef loggerConf_ loggerConf;
229         /**
230          * Disable logging to file
231          */
232         static const loggerConf file_on=        L_nofile_;
233         /**
234          * Enable logging to file
235          */
236         static const loggerConf file_off=       L_file_;
237         /**
238          * Enable logging to screen
239          */
240         static const loggerConf screen_on=      L_noscreen_;
241         /**
242          * Disable logging to screen
243          */
244         static const loggerConf screen_off= L_screen_;
245
246         static Logger& getInstance();
247
248         void print(const unsigned int           verbosityLevel,
249                         const std::string&      sourceFile,
250                         const int               codeLine,
251                         const std::string&      message);
252
253         void configure (const std::string&      outputFile,
254                         const loggerConf        configuration,
255                         const int               fileVerbosityLevel,
256                         const int               screenVerbosityLevel);
257
258         /**
259          * Flush output buffer
260          */
261         inline void flush()
262         {
263                 out_.flush();
264         }
265 };
266
267 /**
268  * operator| - Can be used in Logger::configure
269  * \param __a Configuration (i.e., log on file and on screen on or off).
270  * \param __b Configuration (i.e., log on file and on screen on or off).
271  * \return Configuration (i.e., log on file and on screen on or off).
272  */
273 inline Logger::loggerConf operator|
274         (Logger::loggerConf __a, Logger::loggerConf __b)
275 {
276         return Logger::loggerConf(static_cast<int>(__a) |
277                 static_cast<int>(__b));
278 }
279
280 /**
281  * operator& - Can be used in Logger::configure
282  * \param __a Configuration (i.e., log on file and on screen on or off).
283  * \param __b Configuration (i.e., log on file and on screen on or off).
284  * \return Configuration (i.e., log on file and on screen on or off).
285  */
286 inline Logger::loggerConf operator&
287         (Logger::loggerConf __a, Logger::loggerConf __b)
288 {
289         return Logger::loggerConf(static_cast<int>(__a) &
290                 static_cast<int>(__b)); }
291
292 }
293
294 #endif /* LOGGER_H */
295
296 /** @} */