File: examples.md

package info (click to toggle)
log4cplus 2.0.8-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,592 kB
  • sloc: cpp: 53,091; sh: 10,537; ansic: 1,845; python: 1,226; perl: 263; makefile: 209; xml: 85; objc: 59
file content (327 lines) | stat: -rw-r--r-- 10,147 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# Code Examples

## Hello World

Here is a minimal [log4cplus] example for [log4cplus] version 2.0 and later:

~~~~{.cpp}
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>

int
main()
{
    // Initialization and deinitialization.
    log4cplus::Initializer initializer;

    log4cplus::BasicConfigurator config;
    config.configure();

    log4cplus::Logger logger = log4cplus::Logger::getInstance(
        LOG4CPLUS_TEXT("main"));
    LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("Hello, World!"));
    return 0;
}
~~~~

The above code prints `WARN - Hello, World!` on console. Let's dissect it:

~~~~{.cpp}
#include <log4cplus/logger.h>
~~~~

We need this header to get `Logger` class which represents a handle to named
logger.

~~~~{.cpp}
#include <log4cplus/loggingmacros.h>
~~~~

This header declares `LOG4CPLUS_WARN()` logging macro. Beside this one, it also
declares one for each standard logging level: FATAL, ERROR, WARN, INFO, DEBUG,
TRACE.

~~~~{.cpp}
#include <log4cplus/configurator.h>
~~~~

This header declares `BasicConfigurator` class.

~~~~{.cpp}
#include <log4cplus/initializer.h>
~~~~

This header declares `Initializer` class.

~~~~{.cpp}
log4cplus::Initializer initializer;
~~~~

Instantiating the `Initializer` class internally initializes [log4cplus].

The `Initializer` class also maintains a reference count. The class can be
instantiated multiple times. When this reference count reaches zero, after the
last instance of `Initializer` is destroyed, it shuts down [log4cplus]
internals. Currently, after [log4cplus] is deinitialized, it cannot be
re-initialized.

[log4cplus] tries to use some other methods of shutting down its
internals. However, that means that it **_cannot be used after `main()`
exits_**.

~~~~{.cpp}
log4cplus::BasicConfigurator config;
config.configure();
~~~~

These two lines configure _root logger_ with `ConsoleAppender` and simple
layout.

~~~~{.cpp}
log4cplus::Logger logger = log4cplus::Logger::getInstance(
    LOG4CPLUS_TEXT("main"));
~~~~

Here we obtain logger handle to logger named _main_.

The `LOG4CPLUS_TEXT()` macro used above has the same function as the `TEXT()`
or `_T()` macros do on Windows: In case `UNICODE` preprocessor symbol is
defined, it prefixes the string literal that is passed as its parameter with
the `L` to make it wide character string literal.

~~~~{.cpp}
LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("Hello, World!"));
~~~~

Here we invoke the `LOG4CPLUS_WARN()` macro to log the _Hello, World!_ message
into the _main_ logger. The logged message will be propagated from the _main_
logger towards the _root logger_ which has a `ConsoleAppender` attached to it
to print it on console.

Internally, this macro uses C++ string stream to format the _Hello, World!_
message. The consequence of this is that you can use all of the standard C++
streams manipulators.


## (De-)Initialization

### Initialization

In most cases, [log4cplus] is initialized before `main()` is executed. However,
depending on compiler, platform, run time libraries and how log4cplus is linked
to, it is possible it will not be initialized automatically. This is why
initializing [log4cplus] on top of `main()` is a good rule of thumb.

As the previous code example shows, initialization of [log4cplus] is done by
instantiation of `log4cplus::Initializer` class. This is true for [log4cplus]
versions 2.0 and later. In previous versions, instead of instantiating this
class (the header `log4cplus/initializer.h` and the class do not exist there),
call to function `log4cplus::initialize()` is used.

### Deinitialization

[log4cplus] tries to deinitialize itself and free all of its allocated
resources after `main()` exits. However, again, depending on compiler, platform
and run time libraries, it might not be possible. This is why proper
deinitialization is _necessary_.

In version 2.0 and later, it is done by the last instance of
`log4cplus::Initializer` class and its destructor. In previous versions,
calling `Logger::shutdown()` was the proper shutdown method.

## Logging macros

As we have mentioned earlier, `LOG4CPLUS_WARN()`, `LOG4CPLUS_ERROR()`, etc.,
macros use C++ string stream under the hood. The following example demonstrates
how is it possible to use it with the macros.

Beside these macros, there are two more groups of logging macros.
`LOG4CPLUS_*_STR()` can be used for logging messages that are just plain
strings that do not need any kind of formatting. There is also group of
`LOG4CPLUS_*_FMT()` macros which format logged message using `printf()`
formatting string.

~~~~{.cpp}
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
#include <iomanip>

int
main()
{
    log4cplus::Initializer initializer;

    log4cplus::BasicConfigurator config;
    config.configure();

    log4cplus::Logger logger = log4cplus::Logger::getInstance(
        LOG4CPLUS_TEXT("main"));

    LOG4CPLUS_INFO(logger,
        LOG4CPLUS_TEXT("This is")
        << LOG4CPLUS_TEXT(" a reall")
        << LOG4CPLUS_TEXT("y long message.") << std::endl
        << LOG4CPLUS_TEXT("Just testing it out") << std::endl
        << LOG4CPLUS_TEXT("What do you think?"));
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a bool: ") << true);
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a char: ")
        << LOG4CPLUS_TEXT('x'));
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a short: ")
        << static_cast<short>(-100));
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a unsigned short: ")
        << static_cast<unsigned short>(100));
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a int: ") << 1000);
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a unsigned int: ") << 1000U);
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a long(hex): ")
        << std::hex << 100000000L);
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a unsigned long: ")
        << static_cast<unsigned long>(100000000U));
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a float: ") << 1.2345f);
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a double: ")
        << std::setprecision(15)
        << 1.2345234234);
    LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a long double: ")
        << std::setprecision(15)
        << 123452342342.342L);

    return 0;
}
~~~~

The code above should just print the expected:

~~~~
INFO - This is a really long message.
Just testing it out
What do you think?
INFO - This is a bool: 1
INFO - This is a char: x
INFO - This is a short: -100
INFO - This is a unsigned short: 100
INFO - This is a int: 1000
INFO - This is a unsigned int: 1000
INFO - This is a long(hex): 5f5e100
INFO - This is a unsigned long: 100000000
INFO - This is a float: 1.2345
INFO - This is a double: 1.2345234234
INFO - This is a long double: 123452342342.342
~~~~

Beside these macros, there are two more groups of logging macros.
`LOG4CPLUS_*_STR()` can be used for logging messages that are just plain
strings that do not need any kind of formatting. There is also group of
`LOG4CPLUS_*_FMT()` macros which format logged message using `printf()`
formatting string.


## Log level

This example shows how log messages can be filtered at run time by adjusting
the _log level threshold_ on `Logger` instance.

~~~~{.cpp}
#include <log4cplus/logger.h>
#include <log4cplus/loglevel.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
#include <iomanip>

void
printMessages(log4cplus::Logger const & logger)
{
    // Print messages using all common log levels.
    LOG4CPLUS_TRACE (logger, "printMessages()");
    LOG4CPLUS_DEBUG (logger, "This is a DEBUG message");
    LOG4CPLUS_INFO (logger, "This is a INFO message");
    LOG4CPLUS_WARN (logger, "This is a WARN message");
    LOG4CPLUS_ERROR (logger, "This is a ERROR message");
    LOG4CPLUS_FATAL (logger, "This is a FATAL message");
}

void
thresholdTest(log4cplus::LogLevel ll)
{
    log4cplus::Logger logger
        = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));

    // Set log level threshold on logger.
    logger.setLogLevel(ll);

    // Print messages.
    log4cplus::tcout
        << LOG4CPLUS_TEXT("*** calling printMessages() with ")
        << log4cplus::getLogLevelManager().toString(ll)
        << LOG4CPLUS_TEXT(" set: ***")
        << std::endl;
    printMessages(logger);
    log4cplus::tcout << std::endl;
}

int
main()
{
    log4cplus::Initializer initializer;

    log4cplus::BasicConfigurator config;
    config.configure();

    thresholdTest(log4cplus::TRACE_LOG_LEVEL);
    thresholdTest(log4cplus::DEBUG_LOG_LEVEL);
    thresholdTest(log4cplus::INFO_LOG_LEVEL);
    thresholdTest(log4cplus::WARN_LOG_LEVEL);
    thresholdTest(log4cplus::ERROR_LOG_LEVEL);
    thresholdTest(log4cplus::FATAL_LOG_LEVEL);

    return 0;
}
~~~~

The code prints fewer and fewer messages as the log level threshold is being
risen.

~~~~
*** calling printMessages() with TRACE set: ***
TRACE - printMessages()
DEBUG - This is a DEBUG message
INFO - This is a INFO message
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message

*** calling printMessages() with DEBUG set: ***
DEBUG - This is a DEBUG message
INFO - This is a INFO message
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message

*** calling printMessages() with INFO set: ***
INFO - This is a INFO message
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message

*** calling printMessages() with WARN set: ***
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message

*** calling printMessages() with ERROR set: ***
ERROR - This is a ERROR message
FATAL - This is a FATAL message

*** calling printMessages() with FATAL set: ***
FATAL - This is a FATAL message
~~~~

## More examples

See sources in `tests/` directory in [log4cplus] source distribution for more
examples of [log4cplus] usage.

[log4cplus]: https://sourceforge.net/projects/log4cplus/