1 | // |
2 | // Logger.h |
3 | // |
4 | // Library: Foundation |
5 | // Package: Logging |
6 | // Module: Logger |
7 | // |
8 | // Definition of the Logger class. |
9 | // |
10 | // Copyright (c) 2004-2010, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef Foundation_Logger_INCLUDED |
18 | #define Foundation_Logger_INCLUDED |
19 | |
20 | |
21 | #include "Poco/Foundation.h" |
22 | #include "Poco/Channel.h" |
23 | #include "Poco/Message.h" |
24 | #include "Poco/Format.h" |
25 | #include "Poco/AutoPtr.h" |
26 | #include <map> |
27 | #include <vector> |
28 | #include <cstddef> |
29 | #include <memory> |
30 | |
31 | |
32 | namespace Poco { |
33 | |
34 | |
35 | class Exception; |
36 | |
37 | |
38 | class Foundation_API Logger: public Channel |
39 | /// Logger is a special Channel that acts as the main |
40 | /// entry point into the logging framework. |
41 | /// |
42 | /// An application uses instances of the Logger class to generate its log messages |
43 | /// and send them on their way to their final destination. Logger instances |
44 | /// are organized in a hierarchical, tree-like manner and are maintained by |
45 | /// the framework. Every Logger object has exactly one direct ancestor, with |
46 | /// the exception of the root logger. A newly created logger inherits its properties - |
47 | /// channel and level - from its direct ancestor. Every logger is connected |
48 | /// to a channel, to which it passes on its messages. Furthermore, every logger |
49 | /// has a log level, which is used for filtering messages based on their priority. |
50 | /// Only messages with a priority equal to or higher than the specified level |
51 | /// are passed on. For example, if the level of a logger is set to three (PRIO_ERROR), |
52 | /// only messages with priority PRIO_ERROR, PRIO_CRITICAL and PRIO_FATAL will |
53 | /// propagate. If the level is set to zero, the logger is effectively disabled. |
54 | /// |
55 | /// The name of a logger determines the logger's place within the logger hierarchy. |
56 | /// The name of the root logger is always "", the empty string. For all other |
57 | /// loggers, the name is made up of one or more components, separated by a period. |
58 | /// For example, the loggers with the name HTTPServer.RequestHandler and |
59 | /// HTTPServer.Listener are descendants of the logger HTTPServer, which itself is a |
60 | /// descendant of the root logger. There is no limit as to how deep the logger hierarchy |
61 | /// can become. Once a logger has been created and it has inherited the channel and level |
62 | /// from its ancestor, it loses the connection to it. So, changes to the level or |
63 | /// channel of a logger do not affect its descendants. This greatly simplifies the |
64 | /// implementation of the framework and is no real restriction, because almost always |
65 | /// levels and channels are set up at application startup and never changed afterwards. |
66 | /// Nevertheless, there are methods to simultaneously change the level and channel of |
67 | /// all loggers in a certain hierarchy. |
68 | /// |
69 | /// There are also convenience macros available that wrap the actual |
70 | /// logging statement into a check whether the Logger's log level |
71 | /// is sufficient to actually log the message. This allows to increase |
72 | /// the application performance if many complex log statements |
73 | /// are used. The macros also add the source file path and line |
74 | /// number into the log message so that it is available to formatters. |
75 | /// Variants of these macros that allow message formatting with Poco::format() |
76 | /// are also available. Up to four arguments are supported. |
77 | /// |
78 | /// Examples: |
79 | /// poco_warning(logger, "This is a warning"); |
80 | /// poco_information_f2(logger, "An informational message with args: %d, %d", 1, 2); |
81 | { |
82 | public: |
83 | typedef AutoPtr<Logger> Ptr; |
84 | |
85 | const std::string& name() const; |
86 | /// Returns the name of the logger, which is set as the |
87 | /// message source on all messages created by the logger. |
88 | |
89 | void setChannel(Channel::Ptr pChannel); |
90 | /// Attaches the given Channel to the Logger. |
91 | |
92 | Channel::Ptr getChannel() const; |
93 | /// Returns the Channel attached to the logger. |
94 | |
95 | void setLevel(int level); |
96 | /// Sets the Logger's log level. |
97 | /// |
98 | /// See Message::Priority for valid log levels. |
99 | /// Setting the log level to zero turns off |
100 | /// logging for that Logger. |
101 | |
102 | int getLevel() const; |
103 | /// Returns the Logger's log level. |
104 | |
105 | void setLevel(const std::string& level); |
106 | /// Sets the Logger's log level using a symbolic value. |
107 | /// |
108 | /// Valid values are: |
109 | /// - none (turns off logging) |
110 | /// - fatal |
111 | /// - critical |
112 | /// - error |
113 | /// - warning |
114 | /// - notice |
115 | /// - information |
116 | /// - debug |
117 | /// - trace |
118 | |
119 | void setProperty(const std::string& name, const std::string& value); |
120 | /// Sets or changes a configuration property. |
121 | /// |
122 | /// Only the "channel" and "level" properties are supported, which allow |
123 | /// setting the target channel and log level, respectively, via the LoggingRegistry. |
124 | /// The "channel" and "level" properties are set-only. |
125 | |
126 | void log(const Message& msg); |
127 | /// Logs the given message if its priority is |
128 | /// greater than or equal to the Logger's log level. |
129 | |
130 | void log(const Exception& exc); |
131 | /// Logs the given exception with priority PRIO_ERROR. |
132 | |
133 | void log(const Exception& exc, const char* file, int line); |
134 | /// Logs the given exception with priority PRIO_ERROR. |
135 | /// |
136 | /// File must be a static string, such as the value of |
137 | /// the __FILE__ macro. The string is not copied |
138 | /// internally for performance reasons. |
139 | |
140 | void fatal(const std::string& msg); |
141 | /// If the Logger's log level is at least PRIO_FATAL, |
142 | /// creates a Message with priority PRIO_FATAL |
143 | /// and the given message text and sends it |
144 | /// to the attached channel. |
145 | |
146 | void fatal(const std::string& msg, const char* file, int line); |
147 | /// If the Logger's log level is at least PRIO_FATAL, |
148 | /// creates a Message with priority PRIO_FATAL |
149 | /// and the given message text and sends it |
150 | /// to the attached channel. |
151 | /// |
152 | /// File must be a static string, such as the value of |
153 | /// the __FILE__ macro. The string is not copied |
154 | /// internally for performance reasons. |
155 | |
156 | template <typename T, typename... Args> |
157 | void fatal(const std::string &fmt, T arg1, Args&&... args) |
158 | { |
159 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_FATAL); |
160 | } |
161 | |
162 | void critical(const std::string& msg); |
163 | /// If the Logger's log level is at least PRIO_CRITICAL, |
164 | /// creates a Message with priority PRIO_CRITICAL |
165 | /// and the given message text and sends it |
166 | /// to the attached channel. |
167 | |
168 | void critical(const std::string& msg, const char* file, int line); |
169 | /// If the Logger's log level is at least PRIO_CRITICAL, |
170 | /// creates a Message with priority PRIO_CRITICAL |
171 | /// and the given message text and sends it |
172 | /// to the attached channel. |
173 | /// |
174 | /// File must be a static string, such as the value of |
175 | /// the __FILE__ macro. The string is not copied |
176 | /// internally for performance reasons. |
177 | |
178 | template <typename T, typename... Args> |
179 | void critical(const std::string &fmt, T arg1, Args&&... args) |
180 | { |
181 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_CRITICAL); |
182 | } |
183 | |
184 | void error(const std::string& msg); |
185 | /// If the Logger's log level is at least PRIO_ERROR, |
186 | /// creates a Message with priority PRIO_ERROR |
187 | /// and the given message text and sends it |
188 | /// to the attached channel. |
189 | |
190 | void error(const std::string& msg, const char* file, int line); |
191 | /// If the Logger's log level is at least PRIO_ERROR, |
192 | /// creates a Message with priority PRIO_ERROR |
193 | /// and the given message text and sends it |
194 | /// to the attached channel. |
195 | /// |
196 | /// File must be a static string, such as the value of |
197 | /// the __FILE__ macro. The string is not copied |
198 | /// internally for performance reasons. |
199 | |
200 | template <typename T, typename... Args> |
201 | void error(const std::string &fmt, T arg1, Args&&... args) |
202 | { |
203 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_ERROR); |
204 | } |
205 | |
206 | void warning(const std::string& msg); |
207 | /// If the Logger's log level is at least PRIO_WARNING, |
208 | /// creates a Message with priority PRIO_WARNING |
209 | /// and the given message text and sends it |
210 | /// to the attached channel. |
211 | |
212 | void warning(const std::string& msg, const char* file, int line); |
213 | /// If the Logger's log level is at least PRIO_WARNING, |
214 | /// creates a Message with priority PRIO_WARNING |
215 | /// and the given message text and sends it |
216 | /// to the attached channel. |
217 | /// |
218 | /// File must be a static string, such as the value of |
219 | /// the __FILE__ macro. The string is not copied |
220 | /// internally for performance reasons. |
221 | |
222 | template <typename T, typename... Args> |
223 | void warning(const std::string &fmt, T arg1, Args&&... args) |
224 | { |
225 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_WARNING); |
226 | } |
227 | |
228 | void notice(const std::string& msg); |
229 | /// If the Logger's log level is at least PRIO_NOTICE, |
230 | /// creates a Message with priority PRIO_NOTICE |
231 | /// and the given message text and sends it |
232 | /// to the attached channel. |
233 | |
234 | void notice(const std::string& msg, const char* file, int line); |
235 | /// If the Logger's log level is at least PRIO_NOTICE, |
236 | /// creates a Message with priority PRIO_NOTICE |
237 | /// and the given message text and sends it |
238 | /// to the attached channel. |
239 | /// |
240 | /// File must be a static string, such as the value of |
241 | /// the __FILE__ macro. The string is not copied |
242 | /// internally for performance reasons. |
243 | |
244 | template <typename T, typename... Args> |
245 | void notice(const std::string &fmt, T arg1, Args&&... args) |
246 | { |
247 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_NOTICE); |
248 | } |
249 | |
250 | void information(const std::string& msg); |
251 | /// If the Logger's log level is at least PRIO_INFORMATION, |
252 | /// creates a Message with priority PRIO_INFORMATION |
253 | /// and the given message text and sends it |
254 | /// to the attached channel. |
255 | |
256 | void information(const std::string& msg, const char* file, int line); |
257 | /// If the Logger's log level is at least PRIO_INFORMATION, |
258 | /// creates a Message with priority PRIO_INFORMATION |
259 | /// and the given message text and sends it |
260 | /// to the attached channel. |
261 | /// |
262 | /// File must be a static string, such as the value of |
263 | /// the __FILE__ macro. The string is not copied |
264 | /// internally for performance reasons. |
265 | |
266 | template <typename T, typename... Args> |
267 | void information(const std::string &fmt, T arg1, Args&&... args) |
268 | { |
269 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_INFORMATION); |
270 | } |
271 | |
272 | void debug(const std::string& msg); |
273 | /// If the Logger's log level is at least PRIO_DEBUG, |
274 | /// creates a Message with priority PRIO_DEBUG |
275 | /// and the given message text and sends it |
276 | /// to the attached channel. |
277 | |
278 | void debug(const std::string& msg, const char* file, int line); |
279 | /// If the Logger's log level is at least PRIO_DEBUG, |
280 | /// creates a Message with priority PRIO_DEBUG |
281 | /// and the given message text and sends it |
282 | /// to the attached channel. |
283 | /// |
284 | /// File must be a static string, such as the value of |
285 | /// the __FILE__ macro. The string is not copied |
286 | /// internally for performance reasons. |
287 | |
288 | template <typename T, typename... Args> |
289 | void debug(const std::string &fmt, T arg1, Args&&... args) |
290 | { |
291 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_DEBUG); |
292 | } |
293 | |
294 | void trace(const std::string& msg); |
295 | /// If the Logger's log level is at least PRIO_TRACE, |
296 | /// creates a Message with priority PRIO_TRACE |
297 | /// and the given message text and sends it |
298 | /// to the attached channel. |
299 | |
300 | void trace(const std::string& msg, const char* file, int line); |
301 | /// If the Logger's log level is at least PRIO_TRACE, |
302 | /// creates a Message with priority PRIO_TRACE |
303 | /// and the given message text and sends it |
304 | /// to the attached channel. |
305 | /// |
306 | /// File must be a static string, such as the value of |
307 | /// the __FILE__ macro. The string is not copied |
308 | /// internally for performance reasons. |
309 | |
310 | template <typename T, typename... Args> |
311 | void trace(const std::string &fmt, T arg1, Args&&... args) |
312 | { |
313 | log(Poco::format(fmt, arg1, std::forward<Args>(args)...), Message::PRIO_TRACE); |
314 | } |
315 | |
316 | void dump(const std::string& msg, const void* buffer, std::size_t length, Message::Priority prio = Message::PRIO_DEBUG); |
317 | /// Logs the given message, followed by the data in buffer. |
318 | /// |
319 | /// The data in buffer is written in canonical hex+ASCII form: |
320 | /// Offset (4 bytes) in hexadecimal, followed by sixteen |
321 | /// space-separated, two column, hexadecimal bytes, |
322 | /// followed by the same sixteen bytes as ASCII characters. |
323 | /// For bytes outside the range 32 .. 127, a dot is printed. |
324 | |
325 | bool is(int level) const; |
326 | /// Returns true if at least the given log level is set. |
327 | |
328 | bool fatal() const; |
329 | /// Returns true if the log level is at least PRIO_FATAL. |
330 | |
331 | bool critical() const; |
332 | /// Returns true if the log level is at least PRIO_CRITICAL. |
333 | |
334 | bool error() const; |
335 | /// Returns true if the log level is at least PRIO_ERROR. |
336 | |
337 | bool warning() const; |
338 | /// Returns true if the log level is at least PRIO_WARNING. |
339 | |
340 | bool notice() const; |
341 | /// Returns true if the log level is at least PRIO_NOTICE. |
342 | |
343 | bool information() const; |
344 | /// Returns true if the log level is at least PRIO_INFORMATION. |
345 | |
346 | bool debug() const; |
347 | /// Returns true if the log level is at least PRIO_DEBUG. |
348 | |
349 | bool trace() const; |
350 | /// Returns true if the log level is at least PRIO_TRACE. |
351 | |
352 | static std::string format(const std::string& fmt, const std::string& arg); |
353 | /// Replaces all occurrences of $0 in fmt with the string given in arg and |
354 | /// returns the result. To include a dollar sign in the result string, |
355 | /// specify two dollar signs ($$) in the format string. |
356 | |
357 | static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1); |
358 | /// Replaces all occurrences of $<n> in fmt with the string given in arg<n> and |
359 | /// returns the result. To include a dollar sign in the result string, |
360 | /// specify two dollar signs ($$) in the format string. |
361 | |
362 | static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2); |
363 | /// Replaces all occurrences of $<n> in fmt with the string given in arg<n> and |
364 | /// returns the result. To include a dollar sign in the result string, |
365 | /// specify two dollar signs ($$) in the format string. |
366 | |
367 | static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2, const std::string& arg3); |
368 | /// Replaces all occurrences of $<n> in fmt with the string given in arg<n> and |
369 | /// returns the result. To include a dollar sign in the result string, |
370 | /// specify two dollar signs ($$) in the format string. |
371 | |
372 | static void (std::string& message, const void* buffer, std::size_t length); |
373 | /// Creates a hex-dump of the given buffer and appends it to the |
374 | /// given message string. |
375 | |
376 | static void setLevel(const std::string& name, int level); |
377 | /// Sets the given log level on all loggers that are |
378 | /// descendants of the Logger with the given name. |
379 | |
380 | static void setChannel(const std::string& name, Channel::Ptr pChannel); |
381 | /// Attaches the given Channel to all loggers that are |
382 | /// descendants of the Logger with the given name. |
383 | |
384 | static void setProperty(const std::string& loggerName, const std::string& propertyName, const std::string& value); |
385 | /// Sets or changes a configuration property for all loggers |
386 | /// that are descendants of the Logger with the given name. |
387 | |
388 | static Logger& get(const std::string& name); |
389 | /// Returns a reference to the Logger with the given name. |
390 | /// If the Logger does not yet exist, it is created, based |
391 | /// on its parent logger. |
392 | |
393 | static Logger& unsafeGet(const std::string& name); |
394 | /// Returns a reference to the Logger with the given name. |
395 | /// If the Logger does not yet exist, it is created, based |
396 | /// on its parent logger. |
397 | /// |
398 | /// WARNING: This method is not thread safe. You should |
399 | /// probably use get() instead. |
400 | /// The only time this method should be used is during |
401 | /// program initialization, when only one thread is running. |
402 | |
403 | static Logger& create(const std::string& name, Channel::Ptr pChannel, int level = Message::PRIO_INFORMATION); |
404 | /// Creates and returns a reference to a Logger with the |
405 | /// given name. The Logger's Channel and log level as set as |
406 | /// specified. |
407 | |
408 | static Logger& root(); |
409 | /// Returns a reference to the root logger, which is the ultimate |
410 | /// ancestor of all Loggers. |
411 | |
412 | static Ptr has(const std::string& name); |
413 | /// Returns a pointer to the Logger with the given name if it |
414 | /// exists, or a null pointer otherwise. |
415 | |
416 | static void destroy(const std::string& name); |
417 | /// Destroys the logger with the specified name. Does nothing |
418 | /// if the logger is not found. |
419 | /// |
420 | /// After a logger has been destroyed, all references to it |
421 | /// become invalid. |
422 | |
423 | static void shutdown(); |
424 | /// Shuts down the logging framework and releases all |
425 | /// Loggers. |
426 | |
427 | static void names(std::vector<std::string>& names); |
428 | /// Fills the given vector with the names |
429 | /// of all currently defined loggers. |
430 | |
431 | static int parseLevel(const std::string& level); |
432 | /// Parses a symbolic log level from a string and |
433 | /// returns the resulting numeric level. |
434 | /// |
435 | /// Valid symbolic levels are: |
436 | /// - none (turns off logging) |
437 | /// - fatal |
438 | /// - critical |
439 | /// - error |
440 | /// - warning |
441 | /// - notice |
442 | /// - information |
443 | /// - debug |
444 | /// - trace |
445 | /// |
446 | /// The level is not case sensitive. |
447 | |
448 | static const std::string ROOT; /// The name of the root logger (""). |
449 | |
450 | protected: |
451 | typedef std::map<std::string, Ptr> LoggerMap; |
452 | |
453 | Logger(const std::string& name, Channel::Ptr pChannel, int level); |
454 | ~Logger(); |
455 | |
456 | void log(const std::string& text, Message::Priority prio); |
457 | void log(const std::string& text, Message::Priority prio, const char* file, int line); |
458 | |
459 | static std::string format(const std::string& fmt, int argc, std::string argv[]); |
460 | static Logger& parent(const std::string& name); |
461 | static void add(Ptr pLogger); |
462 | static Ptr find(const std::string& name); |
463 | |
464 | private: |
465 | typedef std::unique_ptr<LoggerMap> LoggerMapPtr; |
466 | |
467 | Logger(); |
468 | Logger(const Logger&); |
469 | Logger& operator = (const Logger&); |
470 | |
471 | std::string _name; |
472 | Channel::Ptr _pChannel; |
473 | int _level; |
474 | |
475 | // definitions in Foundation.cpp |
476 | static LoggerMapPtr _pLoggerMap; |
477 | static Mutex _mapMtx; |
478 | }; |
479 | |
480 | |
481 | // |
482 | // convenience macros |
483 | // |
484 | #define poco_fatal(logger, msg) \ |
485 | if ((logger).fatal()) (logger).fatal(msg, __FILE__, __LINE__); else (void) 0 |
486 | |
487 | #define poco_fatal_f1(logger, fmt, arg1) \ |
488 | if ((logger).fatal()) (logger).fatal(Poco::format((fmt), arg1), __FILE__, __LINE__); else (void) 0 |
489 | |
490 | #define poco_fatal_f2(logger, fmt, arg1, arg2) \ |
491 | if ((logger).fatal()) (logger).fatal(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
492 | |
493 | #define poco_fatal_f3(logger, fmt, arg1, arg2, arg3) \ |
494 | if ((logger).fatal()) (logger).fatal(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
495 | |
496 | #define poco_fatal_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
497 | if ((logger).fatal()) (logger).fatal(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
498 | |
499 | #define poco_critical(logger, msg) \ |
500 | if ((logger).critical()) (logger).critical(msg, __FILE__, __LINE__); else (void) 0 |
501 | |
502 | #define poco_critical_f1(logger, fmt, arg1) \ |
503 | if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
504 | |
505 | #define poco_critical_f2(logger, fmt, arg1, arg2) \ |
506 | if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
507 | |
508 | #define poco_critical_f3(logger, fmt, arg1, arg2, arg3) \ |
509 | if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
510 | |
511 | #define poco_critical_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
512 | if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
513 | |
514 | #define poco_error(logger, msg) \ |
515 | if ((logger).error()) (logger).error(msg, __FILE__, __LINE__); else (void) 0 |
516 | |
517 | #define poco_error_f1(logger, fmt, arg1) \ |
518 | if ((logger).error()) (logger).error(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
519 | |
520 | #define poco_error_f2(logger, fmt, arg1, arg2) \ |
521 | if ((logger).error()) (logger).error(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
522 | |
523 | #define poco_error_f3(logger, fmt, arg1, arg2, arg3) \ |
524 | if ((logger).error()) (logger).error(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
525 | |
526 | #define poco_error_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
527 | if ((logger).error()) (logger).error(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
528 | |
529 | #define poco_warning(logger, msg) \ |
530 | if ((logger).warning()) (logger).warning(msg, __FILE__, __LINE__); else (void) 0 |
531 | |
532 | #define poco_warning_f1(logger, fmt, arg1) \ |
533 | if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
534 | |
535 | #define poco_warning_f2(logger, fmt, arg1, arg2) \ |
536 | if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
537 | |
538 | #define poco_warning_f3(logger, fmt, arg1, arg2, arg3) \ |
539 | if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
540 | |
541 | #define poco_warning_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
542 | if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
543 | |
544 | #define poco_notice(logger, msg) \ |
545 | if ((logger).notice()) (logger).notice(msg, __FILE__, __LINE__); else (void) 0 |
546 | |
547 | #define poco_notice_f1(logger, fmt, arg1) \ |
548 | if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
549 | |
550 | #define poco_notice_f2(logger, fmt, arg1, arg2) \ |
551 | if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
552 | |
553 | #define poco_notice_f3(logger, fmt, arg1, arg2, arg3) \ |
554 | if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
555 | |
556 | #define poco_notice_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
557 | if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
558 | |
559 | #define poco_information(logger, msg) \ |
560 | if ((logger).information()) (logger).information(msg, __FILE__, __LINE__); else (void) 0 |
561 | |
562 | #define poco_information_f1(logger, fmt, arg1) \ |
563 | if ((logger).information()) (logger).information(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
564 | |
565 | #define poco_information_f2(logger, fmt, arg1, arg2) \ |
566 | if ((logger).information()) (logger).information(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
567 | |
568 | #define poco_information_f3(logger, fmt, arg1, arg2, arg3) \ |
569 | if ((logger).information()) (logger).information(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
570 | |
571 | #define poco_information_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
572 | if ((logger).information()) (logger).information(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
573 | |
574 | #if defined(_DEBUG) || defined(POCO_LOG_DEBUG) |
575 | #define poco_debug(logger, msg) \ |
576 | if ((logger).debug()) (logger).debug(msg, __FILE__, __LINE__); else (void) 0 |
577 | |
578 | #define poco_debug_f1(logger, fmt, arg1) \ |
579 | if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
580 | |
581 | #define poco_debug_f2(logger, fmt, arg1, arg2) \ |
582 | if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
583 | |
584 | #define poco_debug_f3(logger, fmt, arg1, arg2, arg3) \ |
585 | if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
586 | |
587 | #define poco_debug_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
588 | if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
589 | |
590 | #define poco_trace(logger, msg) \ |
591 | if ((logger).trace()) (logger).trace(msg, __FILE__, __LINE__); else (void) 0 |
592 | |
593 | #define poco_trace_f1(logger, fmt, arg1) \ |
594 | if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 |
595 | |
596 | #define poco_trace_f2(logger, fmt, arg1, arg2) \ |
597 | if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 |
598 | |
599 | #define poco_trace_f3(logger, fmt, arg1, arg2, arg3) \ |
600 | if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 |
601 | |
602 | #define poco_trace_f4(logger, fmt, arg1, arg2, arg3, arg4) \ |
603 | if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 |
604 | #else |
605 | #define poco_debug(logger, msg) |
606 | #define poco_debug_f1(logger, fmt, arg1) |
607 | #define poco_debug_f2(logger, fmt, arg1, arg2) |
608 | #define poco_debug_f3(logger, fmt, arg1, arg2, arg3) |
609 | #define poco_debug_f4(logger, fmt, arg1, arg2, arg3, arg4) |
610 | #define poco_trace(logger, msg) |
611 | #define poco_trace_f1(logger, fmt, arg1) |
612 | #define poco_trace_f2(logger, fmt, arg1, arg2) |
613 | #define poco_trace_f3(logger, fmt, arg1, arg2, arg3) |
614 | #define poco_trace_f4(logger, fmt, arg1, arg2, arg3, arg4) |
615 | #endif |
616 | |
617 | // |
618 | // inlines |
619 | // |
620 | inline const std::string& Logger::name() const |
621 | { |
622 | return _name; |
623 | } |
624 | |
625 | |
626 | inline int Logger::getLevel() const |
627 | { |
628 | return _level; |
629 | } |
630 | |
631 | |
632 | inline void Logger::log(const std::string& text, Message::Priority prio) |
633 | { |
634 | if (_level >= prio && _pChannel) |
635 | { |
636 | _pChannel->log(Message(_name, text, prio)); |
637 | } |
638 | } |
639 | |
640 | |
641 | inline void Logger::log(const std::string& text, Message::Priority prio, const char* file, int line) |
642 | { |
643 | if (_level >= prio && _pChannel) |
644 | { |
645 | _pChannel->log(Message(_name, text, prio, file, line)); |
646 | } |
647 | } |
648 | |
649 | |
650 | inline void Logger::fatal(const std::string& msg) |
651 | { |
652 | log(msg, Message::PRIO_FATAL); |
653 | } |
654 | |
655 | |
656 | inline void Logger::fatal(const std::string& msg, const char* file, int line) |
657 | { |
658 | log(msg, Message::PRIO_FATAL, file, line); |
659 | } |
660 | |
661 | |
662 | |
663 | inline void Logger::critical(const std::string& msg) |
664 | { |
665 | log(msg, Message::PRIO_CRITICAL); |
666 | } |
667 | |
668 | |
669 | inline void Logger::critical(const std::string& msg, const char* file, int line) |
670 | { |
671 | log(msg, Message::PRIO_CRITICAL, file, line); |
672 | } |
673 | |
674 | |
675 | inline void Logger::error(const std::string& msg) |
676 | { |
677 | log(msg, Message::PRIO_ERROR); |
678 | } |
679 | |
680 | |
681 | inline void Logger::error(const std::string& msg, const char* file, int line) |
682 | { |
683 | log(msg, Message::PRIO_ERROR, file, line); |
684 | } |
685 | |
686 | |
687 | inline void Logger::warning(const std::string& msg) |
688 | { |
689 | log(msg, Message::PRIO_WARNING); |
690 | } |
691 | |
692 | |
693 | inline void Logger::warning(const std::string& msg, const char* file, int line) |
694 | { |
695 | log(msg, Message::PRIO_WARNING, file, line); |
696 | } |
697 | |
698 | |
699 | inline void Logger::notice(const std::string& msg) |
700 | { |
701 | log(msg, Message::PRIO_NOTICE); |
702 | } |
703 | |
704 | |
705 | inline void Logger::notice(const std::string& msg, const char* file, int line) |
706 | { |
707 | log(msg, Message::PRIO_NOTICE, file, line); |
708 | } |
709 | |
710 | |
711 | inline void Logger::information(const std::string& msg) |
712 | { |
713 | log(msg, Message::PRIO_INFORMATION); |
714 | } |
715 | |
716 | |
717 | inline void Logger::information(const std::string& msg, const char* file, int line) |
718 | { |
719 | log(msg, Message::PRIO_INFORMATION, file, line); |
720 | } |
721 | |
722 | |
723 | inline void Logger::debug(const std::string& msg) |
724 | { |
725 | log(msg, Message::PRIO_DEBUG); |
726 | } |
727 | |
728 | |
729 | inline void Logger::debug(const std::string& msg, const char* file, int line) |
730 | { |
731 | log(msg, Message::PRIO_DEBUG, file, line); |
732 | } |
733 | |
734 | |
735 | inline void Logger::trace(const std::string& msg) |
736 | { |
737 | log(msg, Message::PRIO_TRACE); |
738 | } |
739 | |
740 | |
741 | inline void Logger::trace(const std::string& msg, const char* file, int line) |
742 | { |
743 | log(msg, Message::PRIO_TRACE, file, line); |
744 | } |
745 | |
746 | |
747 | inline bool Logger::is(int level) const |
748 | { |
749 | return _level >= level; |
750 | } |
751 | |
752 | |
753 | inline bool Logger::fatal() const |
754 | { |
755 | return _level >= Message::PRIO_FATAL; |
756 | } |
757 | |
758 | |
759 | inline bool Logger::critical() const |
760 | { |
761 | return _level >= Message::PRIO_CRITICAL; |
762 | } |
763 | |
764 | |
765 | inline bool Logger::error() const |
766 | { |
767 | return _level >= Message::PRIO_ERROR; |
768 | } |
769 | |
770 | |
771 | inline bool Logger::warning() const |
772 | { |
773 | return _level >= Message::PRIO_WARNING; |
774 | } |
775 | |
776 | |
777 | inline bool Logger::notice() const |
778 | { |
779 | return _level >= Message::PRIO_NOTICE; |
780 | } |
781 | |
782 | |
783 | inline bool Logger::information() const |
784 | { |
785 | return _level >= Message::PRIO_INFORMATION; |
786 | } |
787 | |
788 | |
789 | inline bool Logger::debug() const |
790 | { |
791 | return _level >= Message::PRIO_DEBUG; |
792 | } |
793 | |
794 | |
795 | inline bool Logger::trace() const |
796 | { |
797 | return _level >= Message::PRIO_TRACE; |
798 | } |
799 | |
800 | |
801 | } // namespace Poco |
802 | |
803 | |
804 | #endif // Foundation_Logger_INCLUDED |
805 | |