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
32namespace Poco {
33
34
35class Exception;
36
37
38class 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{
82public:
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 formatDump(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
450protected:
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
464private:
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//
620inline const std::string& Logger::name() const
621{
622 return _name;
623}
624
625
626inline int Logger::getLevel() const
627{
628 return _level;
629}
630
631
632inline 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
641inline 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
650inline void Logger::fatal(const std::string& msg)
651{
652 log(msg, Message::PRIO_FATAL);
653}
654
655
656inline 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
663inline void Logger::critical(const std::string& msg)
664{
665 log(msg, Message::PRIO_CRITICAL);
666}
667
668
669inline void Logger::critical(const std::string& msg, const char* file, int line)
670{
671 log(msg, Message::PRIO_CRITICAL, file, line);
672}
673
674
675inline void Logger::error(const std::string& msg)
676{
677 log(msg, Message::PRIO_ERROR);
678}
679
680
681inline void Logger::error(const std::string& msg, const char* file, int line)
682{
683 log(msg, Message::PRIO_ERROR, file, line);
684}
685
686
687inline void Logger::warning(const std::string& msg)
688{
689 log(msg, Message::PRIO_WARNING);
690}
691
692
693inline void Logger::warning(const std::string& msg, const char* file, int line)
694{
695 log(msg, Message::PRIO_WARNING, file, line);
696}
697
698
699inline void Logger::notice(const std::string& msg)
700{
701 log(msg, Message::PRIO_NOTICE);
702}
703
704
705inline void Logger::notice(const std::string& msg, const char* file, int line)
706{
707 log(msg, Message::PRIO_NOTICE, file, line);
708}
709
710
711inline void Logger::information(const std::string& msg)
712{
713 log(msg, Message::PRIO_INFORMATION);
714}
715
716
717inline void Logger::information(const std::string& msg, const char* file, int line)
718{
719 log(msg, Message::PRIO_INFORMATION, file, line);
720}
721
722
723inline void Logger::debug(const std::string& msg)
724{
725 log(msg, Message::PRIO_DEBUG);
726}
727
728
729inline void Logger::debug(const std::string& msg, const char* file, int line)
730{
731 log(msg, Message::PRIO_DEBUG, file, line);
732}
733
734
735inline void Logger::trace(const std::string& msg)
736{
737 log(msg, Message::PRIO_TRACE);
738}
739
740
741inline void Logger::trace(const std::string& msg, const char* file, int line)
742{
743 log(msg, Message::PRIO_TRACE, file, line);
744}
745
746
747inline bool Logger::is(int level) const
748{
749 return _level >= level;
750}
751
752
753inline bool Logger::fatal() const
754{
755 return _level >= Message::PRIO_FATAL;
756}
757
758
759inline bool Logger::critical() const
760{
761 return _level >= Message::PRIO_CRITICAL;
762}
763
764
765inline bool Logger::error() const
766{
767 return _level >= Message::PRIO_ERROR;
768}
769
770
771inline bool Logger::warning() const
772{
773 return _level >= Message::PRIO_WARNING;
774}
775
776
777inline bool Logger::notice() const
778{
779 return _level >= Message::PRIO_NOTICE;
780}
781
782
783inline bool Logger::information() const
784{
785 return _level >= Message::PRIO_INFORMATION;
786}
787
788
789inline bool Logger::debug() const
790{
791 return _level >= Message::PRIO_DEBUG;
792}
793
794
795inline 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