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.9.4?
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}::alert message
47
48       ${log}::emergency message
49
50       ${log}::setlevel level
51
52       ${log}::enable level
53
54       ${log}::disable level
55
56       ${log}::lvlchangeproc command
57
58       ${log}::lvlchangeproc
59
60       ${log}::logproc level
61
62       ${log}::logproc level command
63
64       ${log}::logproc level argname body
65
66       ${log}::services
67
68       ${log}::servicename
69
70       ${log}::currentloglevel
71
72       ${log}::delproc command
73
74       ${log}::delproc
75
76       ${log}::delete
77
78       ${log}::trace command
79
80       ${log}::trace on
81
82       ${log}::trace off
83
84       ${log}::trace status ?procName? ?...?
85
86       ${log}::trace add procName ?...?
87
88       ${log}::trace add ?-ns? nsName ?...?
89
90       ${log}::trace remove procName ?...?
91
92       ${log}::trace remove ?-ns? nsName ?...?
93
94______________________________________________________________________________
95

DESCRIPTION

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

IMPLEMENTATION

402       The logger package is implemented in such a way as to optimize (for Tcl
403       8.4 and newer) log procedures which are disabled.  They are aliased  to
404       a  proc  which  has  no body, which is compiled to a no op in bytecode.
405       This should make the peformance hit minimal.  If  you  really  want  to
406       pull  out  all the stops, you can replace the ${log} token in your code
407       with the actual namespace  and  command  (${log}::warn  becomes  ::log‐
408       ger::tree::myservice::warn),  so that no variable lookup is done.  This
409       puts the performance of disabled logger commands very close to no  log‐
410       ging at all.
411
412       The  "object  orientation"  is  done through a hierarchy of namespaces.
413       Using an actual object oriented system would probably be a  better  way
414       of doing things, or at least provide for a cleaner implementation.
415
416       The service "object orientation" is done with namespaces.
417

LOGPROCS AND CALLSTACK

419       The logger package takes extra care to keep the logproc out of the call
420       stack.  This enables logprocs to execute code in the callers  scope  by
421       using  uplevel  or  linking to local variables by using upvar. This may
422       fire traces with all usual side effects.
423
424
425                   # Print caller and current vars in the calling proc
426                   proc log_local_var {txt} {
427                        set caller [info level -1]
428                        set vars [uplevel 1 info vars]
429                        foreach var [lsort $vars] {
430                           if {[uplevel 1 [list array exists $var]] == 1} {
431                           lappend val $var <Array>
432                           } else {
433                           lappend val $var [uplevel 1 [list set $var]]
434                           }
435                        }
436                        puts "$txt"
437                        puts "Caller: $caller"
438                        puts "Variables in callers scope:"
439                        foreach {var value} $val {
440                        puts "$var = $value"
441                        }
442                   }
443
444                   # install as logproc
445                   ${log}::logproc debug log_local_var
446
447

BUGS, IDEAS, FEEDBACK

449       This document, and the package it describes, will  undoubtedly  contain
450       bugs  and other problems.  Please report such in the category logger of
451       the  Tcllib  Trackers  [http://core.tcl.tk/tcllib/reportlist].   Please
452       also  report any ideas for enhancements you may have for either package
453       and/or documentation.
454
455       When proposing code changes, please provide unified diffs, i.e the out‐
456       put of diff -u.
457
458       Note  further  that  attachments  are  strongly  preferred over inlined
459       patches. Attachments can be made by going  to  the  Edit  form  of  the
460       ticket  immediately  after  its  creation, and then using the left-most
461       button in the secondary navigation bar.
462

KEYWORDS

464       log, log level, logger, service
465

CATEGORY

467       Programming tools
468
469
470
471tcllib                               0.9.4                           logger(n)
Impressum