Tcl Library Source Code

EuroTcl/OpenACS 11 - 12 JULY 2024, VIENNA

[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]


logger - System to control logging of events.

Table Of Contents


package require Tcl 8.5 9
package require logger ?0.9.5?

logger::init service
logger::import ?-all? ?-force? ?-prefix prefix? ?-namespace namespace? service
logger::initNamespace ns ?level?
logger::enable level
logger::disable level
logger::setlevel level
logger::servicecmd service
${log}::debug message
${log}::info message
${log}::notice message
${log}::warn message
${log}::error message
${log}::critical message
${log}::alert message
${log}::emergency message
${log}::setlevel level
${log}::enable level
${log}::disable level
${log}::lvlchangeproc command
${log}::logproc level
${log}::logproc level command
${log}::logproc level argname body
${log}::delproc command
${log}::trace command
${log}::trace on
${log}::trace off
${log}::trace status ?procName? ?...?
${log}::trace add procName ?...?
${log}::trace add ?-ns? nsName ?...?
${log}::trace remove procName ?...?
${log}::trace remove ?-ns? nsName ?...?


The logger package provides a flexible system for logging messages from different services, at priority levels, with different commands.

To begin using the logger package, we do the following:

package require logger
set log [logger::init myservice]
${log}::notice "Initialized myservice logging"

... code ...

${log}::notice "Ending myservice logging"

In the above code, after the package is loaded, the following things happen:


The logger package is implemented in such a way as to optimize (for Tcl 8.4 and newer) log procedures which are disabled. They are aliased to a proc which has no body, which is compiled to a no op in bytecode. This should make the peformance hit minimal. If you really want to pull out all the stops, you can replace the ${log} token in your code with the actual namespace and command (${log}::warn becomes ::logger::tree::myservice::warn), so that no variable lookup is done. This puts the performance of disabled logger commands very close to no logging at all.

The "object orientation" is done through a hierarchy of namespaces. Using an actual object oriented system would probably be a better way of doing things, or at least provide for a cleaner implementation.

The service "object orientation" is done with namespaces.

Logprocs and Callstack

The logger package takes extra care to keep the logproc out of the call stack. This enables logprocs to execute code in the callers scope by using uplevel or linking to local variables by using upvar. This may fire traces with all usual side effects.

# Print caller and current vars in the calling proc
proc log_local_var {txt} {
     set caller [info level -1]
     set vars [uplevel 1 info vars]
     foreach var [lsort $vars] {
        if {[uplevel 1 [list array exists $var]] == 1} {
        	lappend val $var <Array>
        } else {
        	lappend val $var [uplevel 1 [list set $var]]
     puts "$txt"
     puts "Caller: $caller"
     puts "Variables in callers scope:"
     foreach {var value} $val {
     	puts "$var = $value"

# install as logproc
${log}::logproc debug log_local_var

Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category logger of the Tcllib Trackers. Please also report any ideas for enhancements you may have for either package and/or documentation.

When proposing code changes, please provide unified diffs, i.e the output of diff -u.

Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar.


log, log level, logger, service


Programming tools