1logger(n)              Object Oriented logging facility              logger(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       logger - System to control logging of events.
9

SYNOPSIS

11       package require Tcl  8.2
12
13       package require logger  ?0.7?
14
15       logger::init service
16
17       logger::import  ?-all? ?-force? ?-prefix prefix? ?-namespace namespace?
18       service
19
20       logger::initNamespace ns ?level?
21
22       logger::services
23
24       logger::enable level
25
26       logger::disable level
27
28       logger::setlevel level
29
30       logger::levels
31
32       logger::servicecmd service
33
34       ${log}::debug message
35
36       ${log}::info message
37
38       ${log}::notice message
39
40       ${log}::warn message
41
42       ${log}::error message
43
44       ${log}::critical message
45
46       ${log}::setlevel level
47
48       ${log}::enable level
49
50       ${log}::disable level
51
52       ${log}::lvlchangeproc command
53
54       ${log}::lvlchangeproc
55
56       ${log}::logproc level
57
58       ${log}::logproc level command
59
60       ${log}::logproc level argname body
61
62       ${log}::services
63
64       ${log}::servicename
65
66       ${log}::currentloglevel
67
68       ${log}::delproc command
69
70       ${log}::delproc
71
72       ${log}::delete
73
74       ${log}::trace command
75
76       ${log}::trace on
77
78       ${log}::trace off
79
80       ${log}::trace status ?procName? ?...?
81
82       ${log}::trace add procName ?...?
83
84       ${log}::trace add ?-ns? nsName ?...?
85
86       ${log}::trace remove procName ?...?
87
88       ${log}::trace remove ?-ns? nsName ?...?
89
90_________________________________________________________________
91

DESCRIPTION

93       The logger package provides a flexible system for logging messages from
94       different services, at priority levels, with different commands.
95
96       To begin using the logger package, we do the following:
97
98           package require logger
99           set log [logger::init myservice]
100           ${log}::notice "Initialized myservice logging"
101
102           ... code ...
103
104           ${log}::notice "Ending myservice logging"
105           ${log}::delete
106
107
108       In  the  above  code, after the package is loaded, the following things
109       happen:
110
111       logger::init service
112              Initializes the service service for logging.  The service  names
113              are  actually  Tcl  namespace  names, so they are seperated with
114              '::'.  When a logger service is initialized, it "inherits" prop‐
115              erties  from its parents.  For instance, if there were a service
116              foo, and we did a logger::init foo::bar (to create a bar service
117              underneath foo), bar would copy the current configuration of the
118              foo service, although it would of course, also  be  possible  to
119              then  seperately configure bar.  If a logger service is initial‐
120              ized and the parent does not yet exist, the parent is also  cre‐
121              ated.   The  new  logger service is initialized with the default
122              loglevel set with logger::setlevel.
123
124       logger::import ?-all? ?-force? ?-prefix prefix? ?-namespace  namespace?
125       service
126              Import  the  logger service commands into the current namespace.
127              Without the -all option only the commands corresponding  to  the
128              log  levels  are imported. If -all is given, all the ${log}::cmd
129              style commands are imported. If the  import  would  overwrite  a
130              command an error is returned and no command is imported. Use the
131              -force option to force the import and  overwrite  existing  com‐
132              mands  without complaining.  If the -prefix option is given, the
133              commands are imported with the given prefix prepended  to  their
134              names.   If  the  -namespace  option  is given, the commands are
135              imported into the given namespace. If  the  namespace  does  not
136              exist,  it  is  created.  If a namespace without a leading :: is
137              given, it is interpreted as a child  namespace  to  the  current
138              namespace.
139
140       logger::initNamespace ns ?level?
141              Convenience command for setting up a namespace for logging. Cre‐
142              ates a logger service named after the namespace ns (a ::  prefix
143              is  stripped),  imports all the log commands into the namespace,
144              and sets the default logging  level,  either  to  the  specified
145              level, or the default level, "warn".
146
147       logger::services
148              Returns a list of all the available services.
149
150       logger::enable level
151              Globally enables logging at and "above" the given level.  Levels
152              are debug, info, notice, warn, error, critical.
153
154       logger::disable level
155              Globally disables logging at and "below" the given level.   Lev‐
156              els are those listed above.
157
158       logger::setlevel level
159              Globally  enable  logging at and "above" the given level. Levels
160              are  those  listed  above.  This  command  changes  the  default
161              loglevel for new loggers created with logger::init.
162
163       logger::levels
164              Returns  a  list  of the available log levels (also listed above
165              under enable).
166
167       logger::servicecmd service
168              Returns the ${log} token created by logger::init for  this  ser‐
169              vice.
170
171       ${log}::debug message
172
173       ${log}::info message
174
175       ${log}::notice message
176
177       ${log}::warn message
178
179       ${log}::error message
180
181       ${log}::critical message
182              These are the commands called to actually log a message about an
183              event.  ${log} is the variable obtained from logger::init.
184
185       ${log}::setlevel level
186              Enable logging, in the service referenced  by  ${log},  and  its
187              children,  at and above the level specified, and disable logging
188              below it.
189
190       ${log}::enable level
191              Enable logging, in the service referenced  by  ${log},  and  its
192              children, at and above the level specified.  Note that this does
193              not disable logging below this level, so you should probably use
194              setlevel instead.
195
196       ${log}::disable level
197              Disable  logging,  in  the service referenced by ${log}, and its
198              children, at and below the level specified. Note that this  does
199              not  enable logging above this level, so you should probably use
200              setlevel instead.  Disabling the loglevel critical switches log‐
201              ging off for the service and its children.
202
203       ${log}::lvlchangeproc command
204
205       ${log}::lvlchangeproc
206              Set the script to call when the log instance in question changes
207              its log level.  If called without a command it returns the  cur‐
208              rently  registered  command.  The  command  gets  two  arguments
209              appended, the old and the new loglevel. The callback is  invoked
210              after  all  changes  have  been  done.   If  child  loggers  are
211              affected, their callbacks are called before their parents  call‐
212              back.
213
214                   proc lvlcallback {old new} {
215                       puts "Loglevel changed from $old to $new"
216                   }
217                   ${log}::lvlchangeproc lvlcallback
218
219
220       ${log}::logproc level
221
222       ${log}::logproc level command
223
224       ${log}::logproc level argname body
225              This command comes in three forms - the third, older one is dep‐
226              recated and may be removed from future versions  of  the  logger
227              package.   The current set version takes one argument, a command
228              to be executed when the level is called.  The  callback  command
229              takes  on argument, the text to be logged. If called only with a
230              valid level logproc returns the name of  the  command  currently
231              registered as callback command.  logproc specifies which command
232              will perform the actual logging for a given level.   The  logger
233              package ships with default commands for all log levels, but with
234              logproc it is possible to replace them with custom  code.   This
235              would let you send your logs over the network, to a database, or
236              anything else.  For example:
237
238                  proc logtoserver {txt} {
239                      variable socket
240                      puts $socket "Notice: $txt"
241                  }
242
243                  ${log}::logproc notice logtoserver
244
245              Trace logs are slightly different: instead of a plain text argu‐
246              ment,  the argument provided to the logproc is a dictionary con‐
247              sisting of the enter or leave keyword along with another dictio‐
248              nary of details about the trace.  These include:
249
250              ·      proc - Name of the procedure being traced.
251
252              ·      level  -  The  stack  level  for the procedure invocation
253                     (from info level).
254
255              ·      script - The name of the file in which the  procedure  is
256                     defined,  or  an  empty  string if defined in interactive
257                     mode.
258
259              ·      caller - The name of the procedure calling the  procedure
260                     being  traced,  or  an  empty string if the procedure was
261                     called from the global scope (stack level 0).
262
263              ·      procargs - A dictionary consisting of the names of  argu‐
264                     ments to the procedure paired with values given for those
265                     arguments (enter traces only).
266
267              ·      status - The Tcl return code (e.g.  ok,  continue,  etc.)
268                     (leave traces only).
269
270              ·      result  -  The  value  returned  by  the procedure (leave
271                     traces only).
272
273       ${log}::services
274              Returns a list of the  registered  logging  services  which  are
275              children of this service.
276
277       ${log}::servicename
278              Returns the name of this service.
279
280       ${log}::currentloglevel
281              Returns  the currently enabled log level for this service. If no
282              logging is enabled returns none.
283
284       ${log}::delproc command
285
286       ${log}::delproc
287              Set the script to call when the  log  instance  in  question  is
288              deleted.   If  called without a command it returns the currently
289              registered command.  For example:
290
291                  ${log}::delproc [list closesock $logsock]
292
293
294       ${log}::delete
295              This command deletes a particular logging service, and its chil‐
296              dren.   You  must  call this to clean up the resources used by a
297              service.
298
299       ${log}::trace command
300              This command controls logging of enter/leave traces  for  speci‐
301              fied  procedures.   It  is  used  to enable and disable tracing,
302              query tracing status, and specify procedures are to  be  traced.
303              Trace  handlers are unregistered when tracing is disabled.  As a
304              result, there is not performance impact to a library when  trac‐
305              ing is disabled, just as with other log level commands.
306
307                proc tracecmd { dict } {
308                    puts $dict
309                }
310
311                set log [::logger::init example]
312                ${log}::logproc trace tracecmd
313
314                proc foo { args } {
315                    puts "In foo"
316                    bar 1
317                    return "foo_result"
318                }
319
320                proc bar { x } {
321                    puts "In bar"
322                    return "bar_result"
323                }
324
325                ${log}::trace add foo bar
326                ${log}::trace on
327
328                foo
329
330              # Output:
331              enter {proc ::foo level 1 script {} caller {} procargs {args {}}}
332              In foo
333              enter {proc ::bar level 2 script {} caller ::foo procargs {x 1}}
334              In bar
335              leave {proc ::bar level 2 script {} caller ::foo status ok result bar_result}
336              leave {proc ::foo level 1 script {} caller {} status ok result foo_result}
337
338
339       ${log}::trace on
340              Turns  on  trace  logging  for procedures registered through the
341              trace add command.  This is similar to the  enable  command  for
342              other  logging levels, but allows trace logging to take place at
343              any level.  The trace logging mechanism takes advantage  of  the
344              execution trace feature of Tcl 8.4 and later.  The trace on com‐
345              mand will return an error if called  from  earlier  versions  of
346              Tcl.
347
348       ${log}::trace off
349              Turns off trace logging for procedures registered for trace log‐
350              ging through the trace add command.  This is similar to the dis‐
351              able  command for other logging levels, but allows trace logging
352              to take place at any level.  Procedures are not unregistered, so
353              logging  for  them  can be turned back on with the trace on com‐
354              mand.  There is no overhead imposed by trace  registration  when
355              trace logging is disabled.
356
357       ${log}::trace status ?procName? ?...?
358              This  command  returns a list of the procedures currently regis‐
359              tered for trace logging, or a flag indicating whether or  not  a
360              trace is registered for one or more specified procedures.
361
362       ${log}::trace add procName ?...?
363
364       ${log}::trace add ?-ns? nsName ?...?
365              This  command  registers  one  or more procedures for logging of
366              entry/exit traces.  Procedures can be specified via  a  list  of
367              procedure  names or namespace names (in which case all procedure
368              within  the  namespace  are  targeted  by  the  operation).   By
369              default,  each  name is first interpreted as a procedure name or
370              glob-style search pattern, and if not found its interpreted as a
371              namespace name.  The -ns option can be used to force interpreta‐
372              tion of all provided arguments as namespace  names.   Procedures
373              must  be  defined  prior to registering them for tracing through
374              the trace add command.  Any procedure  or  namespace  names/pat‐
375              terns  that don't match any existing procedures will be silently
376              ignored.
377
378       ${log}::trace remove procName ?...?
379
380       ${log}::trace remove ?-ns? nsName ?...?
381              This command unregisters one or more  procedures  so  that  they
382              will  no  longer  have  trace  logging  performed, with the same
383              matching rules as that of the trace add command.
384

IMPLEMENTATION

386       The logger package is implemented in such a way as to optimize (for Tcl
387       8.4  and newer) log procedures which are disabled.  They are aliased to
388       a proc which has no body, which is compiled to a  no  op  in  bytecode.
389       This  should  make  the  peformance hit minimal.  If you really want to
390       pull out all the stops, you can replace the ${log} token in  your  code
391       with  the  actual  namespace  and  command (${log}::warn becomes ::log‐
392       ger::tree::myservice::warn), so that no variable lookup is done.   This
393       puts  the performance of disabled logger commands very close to no log‐
394       ging at all.
395
396       The "object orientation" is done through  a  hierarchy  of  namespaces.
397       Using  an  actual object oriented system would probably be a better way
398       of doing things, or at least provide for a cleaner implementation.
399
400       The service "object orientation" is done with namespaces.
401

Logprocs and Callstack

403       The logger package takes extra care to keep the logproc out of the call
404       stack.   This  enables logprocs to execute code in the callers scope by
405       using uplevel or linking to local variables by using  upvar.  This  may
406       fire traces with all usual side effects.
407
408            # Print caller and current vars in the calling proc
409            proc log_local_var {txt} {
410                 set caller [info level -1]
411                 set vars [uplevel 1 info vars]
412                 foreach var [lsort $vars] {
413                    if {[uplevel 1 [list array exists $var]] == 1} {
414                      lappend val $var <Array>
415                    } else {
416                      lappend val $var [uplevel 1 [list set $var]]
417                    }
418                 }
419                 puts "$txt"
420                 puts "Caller: $caller"
421                 puts "Variables in callers scope:"
422                 foreach {var value} $val {
423                      puts "$var = $value"
424                 }
425            }
426
427            # install as logproc
428            ${log}::logproc debug log_local_var
429
430

KEYWORDS

432       log, log level, logger, service
433
434
435
436log                                   0.7                            logger(n)
Impressum