Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Version 0.5 (protocol not changed; ABI changed)
[simgrid.git] / cruft / doc / tmpl / tbx_log.sgml
1 <!-- ##### SECTION Title ##### -->
2 Logging facilities
3
4 <!-- ##### SECTION Short_Description ##### -->
5 An easy-to-use, fast and flexible message logging architecture.
6
7 <!-- ##### SECTION Long_Description ##### -->
8 <para> 
9   This is an adaptation of the log4c project, which is dead upstream, and which
10   I was given the permission to fork under the LGPL licence by the authors. log4c
11   itself was loosely based on the Apache project's Log4J, Log4CC,
12   etc. project. Because C is not object oriented, a lot had to change.
13 </para>
14
15 <refsect2>
16   <title>Overview</title>
17
18   <para>
19     There is 3 main concepts: category, priority and appender. These three
20     concepts work together to enable developers to log messages according to
21     message type and priority, and to control at runtime how these messages are
22     formatted and where they are reported.
23   </para>
24 </refsect2>
25
26 <refsect2>
27  <title>Category hierarchy</title>
28
29   <para>
30     The first and foremost advantage of any logging API over plain printf()
31     resides in its ability to disable certain log statements while allowing
32     others to print unhindered. This capability assumes that the logging space,
33     that is, the space of all possible logging statements, is categorized
34     according to some developer-chosen criteria.
35   </para>
36
37   <para>
38     This observation led to choosing category as the central concept of the
39     system. Every category is declared by providing a name and an optional
40     parent. If no parent is explicitly named, the root category, LOG_ROOT_CAT
41     is the category's parent.
42   </para>
43
44   <para>
45     A category is created by a macro call at the top level of a file.  A
46     category can be created with any one of the following macros:
47   </para>
48
49   <itemizedlist>
50     <listitem>
51      <para>@GRAS_LOG_NEW_CATEGORY(MyCat);</para>
52      <para>create a new root</para>
53     </listitem>
54
55     <listitem>
56       <para>@GRAS_LOG_NEW_SUBCATEGORY(MyCat, ParentCat);</para>
57       <para>Create a new category being child of the category ParentCat</para>
58     </listitem>
59
60     <listitem>
61       <para>@GRAS_LOG_NEW_DEFAULT_CATEGORY(MyCat);</para>
62       <para>Like GRAS_LOG_NEW_CATEGORY, but the new category is the default one
63       in this file</para>
64     </listitem>
65
66     <listitem>
67       <para>@GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(MyCat, ParentCat);</para>
68       <para>Like GRAS_LOG_NEW_SUBCATEGORY, but the new category is the default one
69       in this file</para>
70     </listitem>
71   </itemizedlist>
72
73   <para>
74     The parent cat can be defined in the same file or in another file, but each
75     category may have only one definition.
76   </para>
77
78   <para>
79     Typically, there will be a Category for each module and sub-module, so you
80     can independently control logging for each module.
81   </para>
82 </refsect2>
83
84 <refsect2>
85   <title>Priority</title>
86
87   <para>
88     A category may be assigned a threshold priorty. The set of priorites are
89     defined by the @gras_log_priority_t enum. Their values are DEBUG, VERBOSE,
90     INFO, WARNING, ERROR and CRITICAL.
91   </para>
92
93   <para>
94     If a given category is not assigned a threshold priority, then it inherits
95     one from its closest ancestor with an assigned threshold.
96   </para>
97  
98   <para>
99     To ensure that all categories can eventually inherit a threshold, the root
100     category always has an assigned threshold priority.
101   </para>
102
103   <para>
104     Logging requests are made by invoking a logging macro on a category.  All
105     of the macros have a printf-style format string followed by arguments.
106     Because most C compilers do not support vararg macros, there is a version
107     of the macro for any number of arguments from 0 to 6. The macro name ends
108     with the total number of arguments.
109   </para>
110
111   <para>
112     Here is an example of the most basic type of macro:
113   </para>
114   
115   <programlisting>CLOG5(MyCat, gras_log_priority_warning, "Values are: %d and '%s'", 5, "oops");</programlisting>
116   
117   <para>This is a logging request with priority WARN.</para>
118
119   <para>
120     A logging request is said to be enabled if its priority is higher than or
121     equal to the threshold priority of its category. Otherwise, the request is
122     said to be disabled. A category without an assigned priority will inherit
123     one from the hierarchy.
124   </para>
125
126   <para>
127     It is possible to use any non-negative integer as a priority. If, as in the
128     example, one of the standard priorites is used, then there is a convenience
129     macro that is typically used instead. For example, the above example is
130     equivalent to the shorter:
131   </para>
132
133   <programlisting>CWARN4(MyCat, "Values are: %d and '%s'", 5, "oops");</programlisting>
134 </refsect2>
135
136 <refsect2>
137   <title>Default category</title>
138
139   <para>
140     If @GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(MyCat, Parent) or
141     @GRAS_LOG_NEW_DEFAULT_CATEGORY(MyCat) is used to create the category, then
142     the even shorter form can be used:
143   </para>
144
145   <programlisting>WARN3("Values are: %d and '%s'", 5, "oops");</programlisting>
146
147   <para>
148    Only one default category can be created per file, though multiple
149    non-defaults can be created and used.
150   </para>
151 </refsect2>
152
153 <refsect2>
154   <title>Example</title>
155
156   <para>Here is a more complete example:</para>
157
158   <programlisting>
159      #include "gras.h"
160
161      /* create a category and a default subcategory */
162      GRAS_LOG_NEW_CATEGORY(VSS);
163      GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(SA, VSS);
164
165      main() {
166             /* Now set the parent's priority.
167                (the string would typcially be a runtime option) */
168             gras_log_control_set("SA.thresh=3");
169
170             /* This request is enabled, because WARNING &gt;= INFO. */
171             CWARN2(VSS, "Low fuel level.");
172
173             /* This request is disabled, because DEBUG &lt; INFO. */
174             CDEBUG2(VSS, "Starting search for nearest gas station."); 
175
176             /* The default category SA inherits its priority from VSS. Thus,
177                the following request is enabled because INFO &gt;= INFO.  */
178             INFO1("Located nearest gas station.");
179
180             /* This request is disabled, because DEBUG &lt; INFO. */
181             DEBUG1("Exiting gas station search");
182       }</programlisting>
183 </refsect2>
184
185 <refsect2>
186   <title>Configuration</title>
187
188   <para>
189     Configuration is typically done during program initialization by invoking
190     the gras_log_control_set() method. The control string passed to it
191     typically comes from the command line. Look at the doucmentation for that
192     function for the format of the control string.
193   </para>
194 </refsect2>
195
196 <refsect2>
197   <title>Performance</title>
198
199   <para>
200     Clever design insures efficiency. Except for the first invocation, a
201     disabled logging request requires an a single comparison of a static
202     variable to a constant.
203   </para>
204
205   <para>
206     There is also compile time constant, @GRAS_LOG_STATIC_THRESHOLD, which
207     causes all logging requests with a lower priority to be optimized to 0 cost
208     by the compiler. By setting it to gras_log_priority_infinite, all logging
209     requests are statically disabled and cost nothing. Released executables
210     might typically be compiled with
211     "-DGRAS_LOG_STATIC_THRESHOLD=gras_log_priority_infinite".
212   </para>
213 </refsect2>
214
215 <refsect2>
216   <title>Appenders</title>
217
218   <para>
219     Each category has an optional appender. An appender is a pointer to a
220     structure whcih starts with a pointer to a doAppend() function. DoAppend()
221     prints a message to a log.
222   </para>
223
224   <para>
225     WHen a category is passed a message by one of the logging macros, the
226     category performs the following actions:
227   </para>
228
229   <itemizedlist>
230     <listitem>
231        <para>
232          if the category has an appender, the message is passed to the
233          appender's doAppend() function,
234        </para>
235     </listitem>
236
237     <listitem>
238        <para>
239          if 'willLogToParent' is true for the category, the message is passed
240          to the category's parent.
241       </para>
242
243       <para>
244          By default, all categories except root have no appender and
245          'willLogToParent' is true. This situation causes all messages to be
246          logged by the root category's appender.
247       </para>
248
249       <para>
250          Typically, you would only change the root category's appender when you
251          wanted, say, a different output format. Copying defaultLogAppender.c
252          would be a good start.
253       </para>
254
255       <para>
256          The default appender function currently prints to stderr, but more
257          would be needed, like the one able to send the logs to a remote
258          dedicated server.
259       </para>
260     </listitem>
261   </itemizedlist>
262 </refsect2>
263
264 <refsect2>
265   <title>Misc and Caveats</title>
266
267   <para>
268     Do not use any of the macros that start with '_'.
269   </para>
270
271   <para>
272     The current set of macros force each file to use categories declared in
273     that file. This is intentional. Make the category a child of the file's
274     module category.
275   </para>
276
277   <para>
278     Log4J has a 'rolling file appender' which you can select with a run-time
279     option and specify the max file size. This would be a nice default for
280     non-kernel applications.
281   </para>
282
283   <para>
284     Careful, category names are global variables.
285   </para>
286 </refsect2>
287
288 <!-- ##### SECTION See_Also ##### -->
289 <para>
290
291 </para>
292
293 <!-- ##### ENUM gras_log_priority_t ##### -->
294 <para>
295
296 </para>
297
298 @gras_log_priority_none: 
299 @gras_log_priority_trace: 
300 @gras_log_priority_debug: 
301 @gras_log_priority_verbose: 
302 @gras_log_priority_info: 
303 @gras_log_priority_warning: 
304 @gras_log_priority_error: 
305 @gras_log_priority_critical: 
306 @gras_log_priority_infinite: 
307 @gras_log_priority_uninitialized: 
308
309 <!-- ##### FUNCTION gras_log_control_set ##### -->
310 <para>
311
312 </para>
313
314 @cs: 
315 @Returns: 
316
317
318 <!-- ##### MACRO GRAS_LOG_NEW_CATEGORY ##### -->
319 <para>
320
321 </para>
322
323 @catName: 
324
325
326 <!-- ##### MACRO GRAS_LOG_NEW_SUBCATEGORY ##### -->
327 <para>
328
329 </para>
330
331 @catName: 
332 @parent: 
333
334
335 <!-- ##### MACRO GRAS_LOG_NEW_DEFAULT_CATEGORY ##### -->
336 <para>
337
338 </para>
339
340 @cname: 
341
342
343 <!-- ##### MACRO GRAS_LOG_NEW_DEFAULT_SUBCATEGORY ##### -->
344 <para>
345
346 </para>
347
348 @cname: 
349 @parent: 
350
351
352 <!-- ##### MACRO GRAS_LOG_DEFAULT_CATEGORY ##### -->
353 <para>
354
355 </para>
356
357 @cname: 
358
359
360 <!-- ##### MACRO GRAS_LOG_EXTERNAL_CATEGORY ##### -->
361 <para>
362
363 </para>
364
365 @cname: 
366
367
368 <!-- ##### MACRO GRAS_LOG_ISENABLED ##### -->
369 <para>
370
371 </para>
372
373 @catName: 
374 @priority: 
375
376
377 <!-- ##### MACRO GRAS_LOG_STATIC_THRESHOLD ##### -->
378 <para>
379
380 </para>
381
382
383
384 <!-- ##### FUNCTION gras_log_appender_set ##### -->
385 <para>
386
387 </para>
388
389 @cat: 
390 @app: 
391
392
393 <!-- ##### VARIABLE gras_log_default_appender ##### -->
394 <para>
395
396 </para>
397
398
399 <!-- ##### MACRO CDEBUG6 ##### -->
400 <para>
401
402 </para>
403
404 @c: 
405 @f: 
406 @a1: 
407 @a2: 
408 @a3: 
409 @a4: 
410 @a5: 
411 @a6: 
412
413
414 <!-- ##### MACRO CVERB6 ##### -->
415 <para>
416
417 </para>
418
419 @c: 
420 @f: 
421 @a1: 
422 @a2: 
423 @a3: 
424 @a4: 
425 @a5: 
426 @a6: 
427
428
429 <!-- ##### MACRO CINFO6 ##### -->
430 <para>
431
432 </para>
433
434 @c: 
435 @f: 
436 @a1: 
437 @a2: 
438 @a3: 
439 @a4: 
440 @a5: 
441 @a6: 
442
443
444 <!-- ##### MACRO CWARN6 ##### -->
445 <para>
446
447 </para>
448
449 @c: 
450 @f: 
451 @a1: 
452 @a2: 
453 @a3: 
454 @a4: 
455 @a5: 
456 @a6: 
457
458
459 <!-- ##### MACRO CERROR6 ##### -->
460 <para>
461
462 </para>
463
464 @c: 
465 @f: 
466 @a1: 
467 @a2: 
468 @a3: 
469 @a4: 
470 @a5: 
471 @a6: 
472
473
474 <!-- ##### MACRO CCRITICAL6 ##### -->
475 <para>
476
477 </para>
478
479 @c: 
480 @f: 
481 @a1: 
482 @a2: 
483 @a3: 
484 @a4: 
485 @a5: 
486 @a6: 
487
488
489 <!-- ##### MACRO DEBUG6 ##### -->
490 <para>
491
492 </para>
493
494 @f: 
495 @a1: 
496 @a2: 
497 @a3: 
498 @a4: 
499 @a5: 
500 @a6: 
501
502
503 <!-- ##### MACRO VERB6 ##### -->
504 <para>
505
506 </para>
507
508 @f: 
509 @a1: 
510 @a2: 
511 @a3: 
512 @a4: 
513 @a5: 
514 @a6: 
515
516
517 <!-- ##### MACRO INFO6 ##### -->
518 <para>
519
520 </para>
521
522 @f: 
523 @a1: 
524 @a2: 
525 @a3: 
526 @a4: 
527 @a5: 
528 @a6: 
529
530
531 <!-- ##### MACRO WARN6 ##### -->
532 <para>
533
534 </para>
535
536 @f: 
537 @a1: 
538 @a2: 
539 @a3: 
540 @a4: 
541 @a5: 
542 @a6: 
543
544
545 <!-- ##### MACRO ERROR6 ##### -->
546 <para>
547
548 </para>
549
550 @f: 
551 @a1: 
552 @a2: 
553 @a3: 
554 @a4: 
555 @a5: 
556 @a6: 
557
558
559 <!-- ##### MACRO CRITICAL6 ##### -->
560 <para>
561
562 </para>
563
564 @f: 
565 @a1: 
566 @a2: 
567 @a3: 
568 @a4: 
569 @a5: 
570 @a6: 
571
572