Tcl Library Source Code

Check-in [ec9cf4bb6f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add log::logsubst with command/variable substitution only in the log case. Ticket [19607f927b]
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | rfe-19607f927b-logeval
Files: files | file ages | folders
SHA3-256: ec9cf4bb6f8fd2cab80a341665d26f3e36813b3cca88a32a37fb3aaa88c1d8cc
User & Date: oehhar 2018-02-19 15:09:06.833
Original Comment: Add log::logeval with command/variable substitution only in the log case. Ticket [19607f927b]
Context
2018-02-20
09:08
Added tests to check if the purpose (no execute on no log) works check-in: c5d9906c48 user: oehhar tags: rfe-19607f927b-logeval
2018-02-19
15:09
Add log::logsubst with command/variable substitution only in the log case. Ticket [19607f927b] check-in: ec9cf4bb6f user: oehhar tags: rfe-19607f927b-logeval
2018-02-17
05:29
Bumped release information in the homepage. check-in: 7dc753b7b0 user: aku tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to modules/log/log.man.
1
2
3
4
5
6
7
8
9
[comment {-*- tcl -*- doctools manpage}]
[manpage_begin log n 1.3]
[keywords log]
[keywords {log level}]
[keywords message]
[keywords {message level}]
[copyright {2001-2009 Andreas Kupries <[email protected]>}]
[moddesc   {Logging facility}]
[titledesc {Procedures to log messages of libraries and applications.}]

|







1
2
3
4
5
6
7
8
9
[comment {-*- tcl -*- doctools manpage}]
[manpage_begin log n 1.4]
[keywords log]
[keywords {log level}]
[keywords message]
[keywords {message level}]
[copyright {2001-2009 Andreas Kupries <[email protected]>}]
[moddesc   {Logging facility}]
[titledesc {Procedures to log messages of libraries and applications.}]
219
220
221
222
223
224
225












226
227
228
229
230
231
232
none was specified.

[call [cmd ::log::loghex] [arg level] [arg text] [arg data]]

Like [cmd ::log::log], but assumes that [arg data] contains binary
data. It converts this into a mixed hex/ascii representation before
writing them to the log.













[call [cmd ::log::logMsg] [arg text]]

Convenience wrapper around [cmd ::log::log].
Equivalent to [cmd "::log::log info text"].

[call [cmd ::log::logError] [arg text]]







>
>
>
>
>
>
>
>
>
>
>
>







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
none was specified.

[call [cmd ::log::loghex] [arg level] [arg text] [arg data]]

Like [cmd ::log::log], but assumes that [arg data] contains binary
data. It converts this into a mixed hex/ascii representation before
writing them to the log.

[call [cmd ::log::logsubst] [arg level] [arg msg]]

Like [cmd ::log::log], but [arg msg] may contain substitutions and variable references, which are evaluated in the caller scope first.
The purpose of this command is to avoid overhead in the non-logging case, if the log message building is expensive.
Any substitution errors raise an error in the command execution.

The following example shows an xml text representation, which is only generated in debug mode:

[example {
    log::logsubst debug {XML of node $node is '[$node toXml]'}
}]

[call [cmd ::log::logMsg] [arg text]]

Convenience wrapper around [cmd ::log::log].
Equivalent to [cmd "::log::log info text"].

[call [cmd ::log::logError] [arg text]]
Changes to modules/log/log.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# log.tcl --
#
#	Tcl implementation of a general logging facility
#	(Reaped from Pool_Base and modified to fit into tcllib)
#
# Copyright (c) 2001 by ActiveState Tool Corp.
# See the file license.terms.

package require Tcl 8
package provide log 1.3

# ### ### ### ######### ######### #########

namespace eval ::log {
    namespace export levels lv2longform lv2color lv2priority 
    namespace export lv2cmd lv2channel lvCompare
    namespace export lvSuppress lvSuppressLE lvIsSuppressed









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# log.tcl --
#
#	Tcl implementation of a general logging facility
#	(Reaped from Pool_Base and modified to fit into tcllib)
#
# Copyright (c) 2001 by ActiveState Tool Corp.
# See the file license.terms.

package require Tcl 8
package provide log 1.4

# ### ### ### ######### ######### #########

namespace eval ::log {
    namespace export levels lv2longform lv2color lv2priority 
    namespace export lv2cmd lv2channel lvCompare
    namespace export lvSuppress lvSuppressLE lvIsSuppressed
810
811
812
813
814
815
816










































817
818
819
820
821
822
823
# Results:
#	None.

proc ::log::logError {text} {
    log error $text
}












































# log::Puts --
#
#	Standard log command, writing messages and levels to
#	user-specified channels. Assumes that the supression checks
#	were done by the caller. Expects full level names,
#	abbreviations are *not allowed*.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
# Results:
#	None.

proc ::log::logError {text} {
    log error $text
}

# log::logsubst --
#
#	Log a message with command and variable substitution in the caller
#	scope. The substitutions are only executed in the log case for
#	performance reasons. Any substitution errors rise a command error.
#
# Arguments:
#	level	The level of the message.
#	text	The message to log.
#
# Side Effects:
#	See above.
#
# Results:
#	None.

proc ::log::logsubst {level text} {
    variable cmdMap

    if {[lvIsSuppressed $level]} {
	# Ignore messages for suppressed levels.
	return
    }

    set level [lv2longform $level]

    set cmd $cmdMap($level)
    if {$cmd == {}} {
	# Ignore messages for levels without a command
	return
    }
    
    set text [uplevel 1 subst $text]

    # Delegate actual logging to the command.
    # Handle multi-line messages correctly.

    foreach line [split $text \n] {
	eval [linsert $cmd end $level $line]
    }
    return
}

# log::Puts --
#
#	Standard log command, writing messages and levels to
#	user-specified channels. Assumes that the supression checks
#	were done by the caller. Expects full level names,
#	abbreviations are *not allowed*.
Changes to modules/log/log.test.
360
361
362
363
364
365
366

























367
368
369
370
371
372
373
test log-13.3 {log error} {
    if {![catch {::log::log e foobar} msg]} {
	error "e is an unique abbreviation of a level name"
    }
    set msg
} {bad level "e": must be alert, critical, debug, emergency, error, info, notice, or warning.}



























set lastlevel warning
foreach level {alert critical debug error emergency info notice warning} {
    test log-14.0.$level {log::Puts} {
	makeFile {} test.log
	::log::lvCmdForall ::log::Puts
	::log::lvSuppressLE emergency 0







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
test log-13.3 {log error} {
    if {![catch {::log::log e foobar} msg]} {
	error "e is an unique abbreviation of a level name"
    }
    set msg
} {bad level "e": must be alert, critical, debug, emergency, error, info, notice, or warning.}

test log-13.4 {logsubst variable} {
    set _log_ [list]
    set logdata buz
    ::log::logsubst er {logging<$logdata>}
    set _log_
} {error logging<buz>}

test log-13.5 {logsubst command} {
    set _log_ [list]
    set logdata buz
    ::log::logsubst er {logging<[set logdata]>}
    set _log_
} {error logging<buz>}

test log-13.6 {logsubst escape} {
    set _log_ [list]
    set logdata buz
    ::log::logsubst er {1\n2}
    set _log_
} {error 1 error 2}

test log-13.7 {logeval evaluation error} {
    set level [catch {::log::logsubst er {[error q]} } msg]
    list $level $msg
} {1 q}

set lastlevel warning
foreach level {alert critical debug error emergency info notice warning} {
    test log-14.0.$level {log::Puts} {
	makeFile {} test.log
	::log::lvCmdForall ::log::Puts
	::log::lvSuppressLE emergency 0
Changes to modules/log/pkgIndex.tcl.
1
2
3
4
5
6
7
8
9
if {![package vsatisfies [package provide Tcl] 8]} {return}
package ifneeded log 1.3 [list source [file join $dir log.tcl]]

if {![package vsatisfies [package provide Tcl] 8.2]} {return}
package ifneeded logger           0.9.4 [list source [file join $dir logger.tcl]]
package ifneeded logger::appender 1.3   [list source [file join $dir loggerAppender.tcl]]

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
package ifneeded logger::utils    1.3   [list source [file join $dir loggerUtils.tcl]]

|







1
2
3
4
5
6
7
8
9
if {![package vsatisfies [package provide Tcl] 8]} {return}
package ifneeded log 1.4 [list source [file join $dir log.tcl]]

if {![package vsatisfies [package provide Tcl] 8.2]} {return}
package ifneeded logger           0.9.4 [list source [file join $dir logger.tcl]]
package ifneeded logger::appender 1.3   [list source [file join $dir loggerAppender.tcl]]

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
package ifneeded logger::utils    1.3   [list source [file join $dir loggerUtils.tcl]]