1logger(n) Object Oriented logging facility logger(n)
2
3
4
5______________________________________________________________________________
6
8 logger - System to control logging of events.
9
11 package require Tcl 8.2
12
13 package require logger ?0.8?
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
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 seperated with
118 '::'. When a logger service is initialized, it "inherits" prop‐
119 erties from its parents. For instance, if there were a service
120 foo, and we did a logger::init foo::bar (to create a bar service
121 underneath foo), bar would copy the current configuration of the
122 foo service, although it would of course, also be possible to
123 then seperately configure bar. If a logger service is initial‐
124 ized and the parent does not yet exist, the parent is also cre‐
125 ated. The new logger service is initialized with the default
126 loglevel set with logger::setlevel.
127
128 logger::import ?-all? ?-force? ?-prefix prefix? ?-namespace namespace?
129 service
130 Import the logger service commands into the current namespace.
131 Without the -all option only the commands corresponding to the
132 log levels are imported. If -all is given, all the ${log}::cmd
133 style commands are imported. If the import would overwrite a
134 command an error is returned and no command is imported. Use the
135 -force option to force the import and overwrite existing com‐
136 mands without complaining. If the -prefix option is given, the
137 commands are imported with the given prefix prepended to their
138 names. If the -namespace option is given, the commands are
139 imported into the given namespace. If the namespace does not
140 exist, it is created. If a namespace without a leading :: is
141 given, it is interpreted as a child namespace to the current
142 namespace.
143
144 logger::initNamespace ns ?level?
145 Convenience command for setting up a namespace for logging. Cre‐
146 ates a logger service named after the namespace ns (a :: prefix
147 is stripped), imports all the log commands into the namespace,
148 and sets the default logging level, either to the specified
149 level, or the default level, "warn".
150
151 logger::services
152 Returns a list of all the available services.
153
154 logger::enable level
155 Globally enables logging at and "above" the given level. Levels
156 are debug, info, notice, warn, error, critical, alert, emer‐
157 gency.
158
159 logger::disable level
160 Globally disables logging at and "below" the given level. Lev‐
161 els are those listed above.
162
163 logger::setlevel level
164 Globally enable logging at and "above" the given level. Levels
165 are those listed above. This command changes the default
166 loglevel for new loggers created with logger::init.
167
168 logger::levels
169 Returns a list of the available log levels (also listed above
170 under enable).
171
172 logger::servicecmd service
173 Returns the ${log} token created by logger::init for this ser‐
174 vice.
175
176 ${log}::debug message
177
178 ${log}::info message
179
180 ${log}::notice message
181
182 ${log}::warn message
183
184 ${log}::error message
185
186 ${log}::critical message
187
188 ${log}::alert message
189
190 ${log}::emergency message
191 These are the commands called to actually log a message about an
192 event. ${log} is the variable obtained from logger::init.
193
194 ${log}::setlevel level
195 Enable logging, in the service referenced by ${log}, and its
196 children, at and above the level specified, and disable logging
197 below it.
198
199 ${log}::enable level
200 Enable logging, in the service referenced by ${log}, and its
201 children, at and above the level specified. Note that this does
202 not disable logging below this level, so you should probably use
203 setlevel instead.
204
205 ${log}::disable level
206 Disable logging, in the service referenced by ${log}, and its
207 children, at and below the level specified. Note that this does
208 not enable logging above this level, so you should probably use
209 setlevel instead. Disabling the loglevel emergency switches
210 logging off for the service and its children.
211
212 ${log}::lvlchangeproc command
213
214 ${log}::lvlchangeproc
215 Set the script to call when the log instance in question changes
216 its log level. If called without a command it returns the cur‐
217 rently registered command. The command gets two arguments
218 appended, the old and the new loglevel. The callback is invoked
219 after all changes have been done. If child loggers are
220 affected, their callbacks are called before their parents call‐
221 back.
222
223 proc lvlcallback {old new} {
224 puts "Loglevel changed from $old to $new"
225 }
226 ${log}::lvlchangeproc lvlcallback
227
228
229 ${log}::logproc level
230
231 ${log}::logproc level command
232
233 ${log}::logproc level argname body
234 This command comes in three forms - the third, older one is dep‐
235 recated and may be removed from future versions of the logger
236 package. The current set version takes one argument, a command
237 to be executed when the level is called. The callback command
238 takes on argument, the text to be logged. If called only with a
239 valid level logproc returns the name of the command currently
240 registered as callback command. logproc specifies which command
241 will perform the actual logging for a given level. The logger
242 package ships with default commands for all log levels, but with
243 logproc it is possible to replace them with custom code. This
244 would let you send your logs over the network, to a database, or
245 anything else. For example:
246
247 proc logtoserver {txt} {
248 variable socket
249 puts $socket "Notice: $txt"
250 }
251
252 ${log}::logproc notice logtoserver
253
254 Trace logs are slightly different: instead of a plain text argu‐
255 ment, the argument provided to the logproc is a dictionary con‐
256 sisting of the enter or leave keyword along with another dictio‐
257 nary of details about the trace. These include:
258
259 · proc - Name of the procedure being traced.
260
261 · level - The stack level for the procedure invocation
262 (from info level).
263
264 · script - The name of the file in which the procedure is
265 defined, or an empty string if defined in interactive
266 mode.
267
268 · caller - The name of the procedure calling the procedure
269 being traced, or an empty string if the procedure was
270 called from the global scope (stack level 0).
271
272 · procargs - A dictionary consisting of the names of argu‐
273 ments to the procedure paired with values given for those
274 arguments (enter traces only).
275
276 · status - The Tcl return code (e.g. ok, continue, etc.)
277 (leave traces only).
278
279 · result - The value returned by the procedure (leave
280 traces only).
281
282 ${log}::services
283 Returns a list of the registered logging services which are
284 children of this service.
285
286 ${log}::servicename
287 Returns the name of this service.
288
289 ${log}::currentloglevel
290 Returns the currently enabled log level for this service. If no
291 logging is enabled returns none.
292
293 ${log}::delproc command
294
295 ${log}::delproc
296 Set the script to call when the log instance in question is
297 deleted. If called without a command it returns the currently
298 registered command. For example:
299
300 ${log}::delproc [list closesock $logsock]
301
302
303 ${log}::delete
304 This command deletes a particular logging service, and its chil‐
305 dren. You must call this to clean up the resources used by a
306 service.
307
308 ${log}::trace command
309 This command controls logging of enter/leave traces for speci‐
310 fied procedures. It is used to enable and disable tracing,
311 query tracing status, and specify procedures are to be traced.
312 Trace handlers are unregistered when tracing is disabled. As a
313 result, there is not performance impact to a library when trac‐
314 ing is disabled, just as with other log level commands.
315
316 proc tracecmd { dict } {
317 puts $dict
318 }
319
320 set log [::logger::init example]
321 ${log}::logproc trace tracecmd
322
323 proc foo { args } {
324 puts "In foo"
325 bar 1
326 return "foo_result"
327 }
328
329 proc bar { x } {
330 puts "In bar"
331 return "bar_result"
332 }
333
334 ${log}::trace add foo bar
335 ${log}::trace on
336
337 foo
338
339 # Output:
340 enter {proc ::foo level 1 script {} caller {} procargs {args {}}}
341 In foo
342 enter {proc ::bar level 2 script {} caller ::foo procargs {x 1}}
343 In bar
344 leave {proc ::bar level 2 script {} caller ::foo status ok result bar_result}
345 leave {proc ::foo level 1 script {} caller {} status ok result foo_result}
346
347
348 ${log}::trace on
349 Turns on trace logging for procedures registered through the
350 trace add command. This is similar to the enable command for
351 other logging levels, but allows trace logging to take place at
352 any level. The trace logging mechanism takes advantage of the
353 execution trace feature of Tcl 8.4 and later. The trace on com‐
354 mand will return an error if called from earlier versions of
355 Tcl.
356
357 ${log}::trace off
358 Turns off trace logging for procedures registered for trace log‐
359 ging through the trace add command. This is similar to the dis‐
360 able command for other logging levels, but allows trace logging
361 to take place at any level. Procedures are not unregistered, so
362 logging for them can be turned back on with the trace on com‐
363 mand. There is no overhead imposed by trace registration when
364 trace logging is disabled.
365
366 ${log}::trace status ?procName? ?...?
367 This command returns a list of the procedures currently regis‐
368 tered for trace logging, or a flag indicating whether or not a
369 trace is registered for one or more specified procedures.
370
371 ${log}::trace add procName ?...?
372
373 ${log}::trace add ?-ns? nsName ?...?
374 This command registers one or more procedures for logging of
375 entry/exit traces. Procedures can be specified via a list of
376 procedure names or namespace names (in which case all procedure
377 within the namespace are targeted by the operation). By
378 default, each name is first interpreted as a procedure name or
379 glob-style search pattern, and if not found its interpreted as a
380 namespace name. The -ns option can be used to force interpreta‐
381 tion of all provided arguments as namespace names. Procedures
382 must be defined prior to registering them for tracing through
383 the trace add command. Any procedure or namespace names/pat‐
384 terns that don't match any existing procedures will be silently
385 ignored.
386
387 ${log}::trace remove procName ?...?
388
389 ${log}::trace remove ?-ns? nsName ?...?
390 This command unregisters one or more procedures so that they
391 will no longer have trace logging performed, with the same
392 matching rules as that of the trace add command.
393
395 The logger package is implemented in such a way as to optimize (for Tcl
396 8.4 and newer) log procedures which are disabled. They are aliased to
397 a proc which has no body, which is compiled to a no op in bytecode.
398 This should make the peformance hit minimal. If you really want to
399 pull out all the stops, you can replace the ${log} token in your code
400 with the actual namespace and command (${log}::warn becomes ::log‐
401 ger::tree::myservice::warn), so that no variable lookup is done. This
402 puts the performance of disabled logger commands very close to no log‐
403 ging at all.
404
405 The "object orientation" is done through a hierarchy of namespaces.
406 Using an actual object oriented system would probably be a better way
407 of doing things, or at least provide for a cleaner implementation.
408
409 The service "object orientation" is done with namespaces.
410
412 The logger package takes extra care to keep the logproc out of the call
413 stack. This enables logprocs to execute code in the callers scope by
414 using uplevel or linking to local variables by using upvar. This may
415 fire traces with all usual side effects.
416
417 # Print caller and current vars in the calling proc
418 proc log_local_var {txt} {
419 set caller [info level -1]
420 set vars [uplevel 1 info vars]
421 foreach var [lsort $vars] {
422 if {[uplevel 1 [list array exists $var]] == 1} {
423 lappend val $var <Array>
424 } else {
425 lappend val $var [uplevel 1 [list set $var]]
426 }
427 }
428 puts "$txt"
429 puts "Caller: $caller"
430 puts "Variables in callers scope:"
431 foreach {var value} $val {
432 puts "$var = $value"
433 }
434 }
435
436 # install as logproc
437 ${log}::logproc debug log_local_var
438
439
441 This document, and the package it describes, will undoubtedly contain
442 bugs and other problems. Please report such in the category logger of
443 the Tcllib SF Trackers [http://source‐
444 forge.net/tracker/?group_id=12883]. Please also report any ideas for
445 enhancements you may have for either package and/or documentation.
446
448 log, log level, logger, service
449
450
451
452log 0.8 logger(n)