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.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
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
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
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
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
464 log, log level, logger, service
465
467 Programming tools
468
469
470
471tcllib 0.9.4 logger(n)