Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
0d6f8691489a437fefe8f2bb4a2f30bcd784ca45
[simgrid.git] / cruft / doc / tmpl / core_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 >= INFO. */
171             CWARN2(VSS, "Low fuel level.");
172
173             /* This request is disabled, because DEBUG < 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 >= INFO.  */
178             INFO1("Located nearest gas station.");
179
180             /* This request is disabled, because DEBUG < 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 & 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_debug: 
300 @gras_log_priority_verbose: 
301 @gras_log_priority_info: 
302 @gras_log_priority_warning: 
303 @gras_log_priority_error: 
304 @gras_log_priority_critical: 
305 @gras_log_priority_infinite: 
306 @gras_log_priority_uninitialized: 
307
308 <!-- ##### FUNCTION gras_log_control_set ##### -->
309 <para>
310
311 </para>
312
313 @cs: 
314 @Returns: 
315
316
317 <!-- ##### MACRO GRAS_LOG_NEW_CATEGORY ##### -->
318 <para>
319
320 </para>
321
322 @catName: 
323
324
325 <!-- ##### MACRO GRAS_LOG_NEW_SUBCATEGORY ##### -->
326 <para>
327
328 </para>
329
330 @catName: 
331 @parent: 
332
333
334 <!-- ##### MACRO GRAS_LOG_NEW_DEFAULT_CATEGORY ##### -->
335 <para>
336
337 </para>
338
339 @cname: 
340
341
342 <!-- ##### MACRO GRAS_LOG_NEW_DEFAULT_SUBCATEGORY ##### -->
343 <para>
344
345 </para>
346
347 @cname: 
348 @parent: 
349
350
351 <!-- ##### MACRO GRAS_LOG_DEFAULT_CATEGORY ##### -->
352 <para>
353
354 </para>
355
356 @cname: 
357
358
359 <!-- ##### MACRO GRAS_LOG_EXTERNAL_CATEGORY ##### -->
360 <para>
361
362 </para>
363
364 @cname: 
365
366
367 <!-- ##### MACRO GRAS_LOG_ISENABLED ##### -->
368 <para>
369
370 </para>
371
372 @catName: 
373 @priority: 
374
375
376 <!-- ##### MACRO GRAS_LOG_STATIC_THRESHOLD ##### -->
377 <para>
378
379 </para>
380
381
382
383 <!-- ##### FUNCTION gras_log_appender_set ##### -->
384 <para>
385
386 </para>
387
388 @cat: 
389 @app: 
390
391
392 <!-- ##### VARIABLE gras_log_default_appender ##### -->
393 <para>
394
395 </para>
396
397
398 <!-- ##### MACRO CDEBUG6 ##### -->
399 <para>
400
401 </para>
402
403 @c: 
404 @f: 
405 @a1: 
406 @a2: 
407 @a3: 
408 @a4: 
409 @a5: 
410 @a6: 
411
412
413 <!-- ##### MACRO CVERB6 ##### -->
414 <para>
415
416 </para>
417
418 @c: 
419 @f: 
420 @a1: 
421 @a2: 
422 @a3: 
423 @a4: 
424 @a5: 
425 @a6: 
426
427
428 <!-- ##### MACRO CINFO6 ##### -->
429 <para>
430
431 </para>
432
433 @c: 
434 @f: 
435 @a1: 
436 @a2: 
437 @a3: 
438 @a4: 
439 @a5: 
440 @a6: 
441
442
443 <!-- ##### MACRO CWARNING6 ##### -->
444 <para>
445
446 </para>
447
448 @c: 
449 @f: 
450 @a1: 
451 @a2: 
452 @a3: 
453 @a4: 
454 @a5: 
455 @a6: 
456
457
458 <!-- ##### MACRO CERROR6 ##### -->
459 <para>
460
461 </para>
462
463 @c: 
464 @f: 
465 @a1: 
466 @a2: 
467 @a3: 
468 @a4: 
469 @a5: 
470 @a6: 
471
472
473 <!-- ##### MACRO CCRITICAL6 ##### -->
474 <para>
475
476 </para>
477
478 @c: 
479 @f: 
480 @a1: 
481 @a2: 
482 @a3: 
483 @a4: 
484 @a5: 
485 @a6: 
486
487
488 <!-- ##### MACRO DEBUG6 ##### -->
489 <para>
490
491 </para>
492
493 @f: 
494 @a1: 
495 @a2: 
496 @a3: 
497 @a4: 
498 @a5: 
499 @a6: 
500
501
502 <!-- ##### MACRO VERB6 ##### -->
503 <para>
504
505 </para>
506
507 @f: 
508 @a1: 
509 @a2: 
510 @a3: 
511 @a4: 
512 @a5: 
513 @a6: 
514
515
516 <!-- ##### MACRO INFO6 ##### -->
517 <para>
518
519 </para>
520
521 @f: 
522 @a1: 
523 @a2: 
524 @a3: 
525 @a4: 
526 @a5: 
527 @a6: 
528
529
530 <!-- ##### MACRO WARNING6 ##### -->
531 <para>
532
533 </para>
534
535 @f: 
536 @a1: 
537 @a2: 
538 @a3: 
539 @a4: 
540 @a5: 
541 @a6: 
542
543
544 <!-- ##### MACRO ERROR6 ##### -->
545 <para>
546
547 </para>
548
549 @f: 
550 @a1: 
551 @a2: 
552 @a3: 
553 @a4: 
554 @a5: 
555 @a6: 
556
557
558 <!-- ##### MACRO CRITICAL6 ##### -->
559 <para>
560
561 </para>
562
563 @f: 
564 @a1: 
565 @a2: 
566 @a3: 
567 @a4: 
568 @a5: 
569 @a6: 
570
571