1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#!/usr/bin/env tclsh
#
# Logger example - How to log to a text widget
#
# (c) 2005 Michael Schlenker <mic42@users.sourceforge.net>
#
# $Id: logtotext.tcl,v 1.2 2005/06/01 03:09:49 andreas_kupries Exp $
package require Tcl 8.4
package require Tk
package require logger
set config(elide,time) 0
set config(elide,level) 0
foreach level [logger::levels] {
set config(elide,$level) 0
}
set logmessage "A little log message"
#
# Create a simple logger with the servicename 'global'
#
#
proc createLogger {} {
global mylogger
set mylogger [logger::init global]
# loggers logproc takes just one arg, so curry
# our proc with the loglevel and use an alias
foreach level [logger::levels] {
interp alias {} insertLogLine_$level {} insertLogLine $level
${mylogger}::logproc $level insertLogLine_$level
}
}
# Put the logmessage to the logger system
proc sendMessageToLog {level} {
${::mylogger}::$level $::logmessage
}
proc createGUI {} {
global mylogger
global logwidget
wm title . "Logger example - log to text widget"
# a little compose window for entering messages
labelframe .compose -text "Compose log message"
entry .compose.logmessage -textvariable logmessage
frame .compose.levels
foreach level [logger::levels] {
set p .compose.levels.$level
button $p -command [list sendMessageToLog $level] -text "Log as $level"
lappend buttons $p
}
eval grid $buttons -sticky ew -padx 2 -pady 5
grid .compose.logmessage -sticky ew
grid .compose.levels -sticky ew
grid .compose -sticky ew
# The output window
labelframe .log -text "Log output"
text .log.text -yscrollcommand [list .log.yscroll set] -wrap none
set logwidget .log.text
scrollbar .log.yscroll -orient vertical -command [list $logwidget yview]
frame .log.buttons
frame .log.buttons.elide
checkbutton .log.buttons.elide.toggletime -text "Display Timestamp" -command [list toggleElide time] \
-onvalue 0 -offvalue 1 -variable config(elide,time)
checkbutton .log.buttons.elide.togglelevel -text "Display Level" -command [list toggleElide level] \
-onvalue 0 -offvalue 1 -variable config(elide,level)
frame .log.buttons.elidelevels
foreach level [logger::levels] {
set b .log.buttons.elidelevels.$level
checkbutton $b -text "Display $level" -command [list toggleElide $level] -variable config(elide,$level) \
-onvalue 0 -offvalue 1
lappend elides $b
}
eval grid $elides
grid .log.text .log.yscroll -sticky nsew
grid configure .log.yscroll -sticky nws
grid .log.buttons.elide.toggletime .log.buttons.elide.togglelevel
grid .log.buttons.elide -sticky ew
grid .log.buttons.elidelevels -sticky ew
grid .log.buttons -columnspan 2 -sticky ew
grid .log -sticky news
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 0
grid rowconfigure . 1 -weight 1
grid columnconfigure .log 0 -weight 1
grid columnconfigure .log 1 -weight 0
grid rowconfigure .log 0 -weight 1
#
# Now we create some fonts
# a fixed font for the first two columns, so they stay nicely lined up
# a proportional font for the message as it is probably better to read
#
font create logger::timefont -family {Courier} -size 12
font create logger::levelfont -family {Courier} -size 12
font create logger::msgfont -family {Times} -size 12
$logwidget tag configure logger::time -font logger::timefont
$logwidget tag configure logger::level -font logger::levelfont
$logwidget tag configure logger::message -font logger::msgfont
# Now we create some colors for the levels, so our messages appear in different colors
foreach level [logger::levels] color {darkgrey lightgrey brown blue orange red} {
$logwidget tag configure logger::$level -background $color
}
# Disable the widget, so it is read only
$logwidget configure -state disabled
}
# Allow toggling of display
#
# only time and level are used in this example, but you could
# elide specific messages levels too
#
proc toggleElide {type} {
global config
$::logwidget tag configure logger::$type -elide $config(elide,$type)
return
}
# A rather basic insert
#
# I a long running application we would probably add some code to only keep
# a specific number of log messages in the text widget, and throw away some older
# ones. (basic stuff, just count lines and for example add a
# $logwidget delete 1.0 2.0
# if the log grows too long, needs refinement if you have multi line log messages )
#
proc insertLogLine {level txt} {
global logwidget
$logwidget configure -state normal
$logwidget insert end "<[clock format [clock seconds] -format "%H:%M:%S"]> " [list logger::time logger::$level] \
[format "%10.10s : " <$level>] [list logger::level logger::$level] \
$txt\n [list logger::message logger::$level]
$logwidget configure -state disabled
}
proc every {time body} {
after $time [info level 0]
uplevel #0 $body
}
proc main {} {
createLogger
createGUI
}
main
# Add some repeating message
every 10000 {${mylogger}::info "The current time is [clock format [clock seconds] -format "%H:%M:%S"]"}
|