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.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
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
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
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
432 log, log level, logger, service
433
434
435
436log 0.7 logger(n)