]> AND Public Git Repository - simgrid.git/blob - cruft/doc/tmpl/tbx_log.sgml
Logo AND Algorithmique Numérique Distribuée

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