~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/tcl/common/mash-log.tcl

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 # HOWTO: Using MashLog to log messages.

  2 # MashLog provides a general logging facility in Mash.  Programmers can

  3 # define multiple logging channel, identified by a "type".  Three types

  4 # of logging channels are predefined, "info", "warn", and "error". 

  5 # Additional logging channels, (such as "debug") can be defined using 

  6 # the "file" method.  Each type is associated with exactly one file

  7 # channel, but a channel can be shared by different types.  Messages

  8 # will be sent to the channel associated with its type.  For example,

  9 # by default "info" is associated with "stdout" and "warn"/"error" are

 10 # associated with "stderr".  To send a message use "log" command.

 11 #

 12 # Example:

 13 #  MashLog file "info" stdout

 14 #  # Print "Hello World" to stdout.

 15 #  MashLog log "info" "Hello World!"

 16 #  MashLog file "info" info.log

 17 #  MashLog log "info" "Hello World!"

 18 #

 19 # Programmers can change the channel by reissuing the "file" method.

 20 # For simplicity, everytime a "file" method is called, a new method

 21 # named "type" is created.

 22 #

 23 #  MashLog file "debug" stdout

 24 #  MashLog debug "foobar"

 25 #

 26 # You can turn timestamping and pid printing on and off.

 27 #  MashLog timestamp on

 28 #  MashLog debug "foobar"

 29 #  MashLog pid on

 30 #  MashLog debug "foobar"

 31 #

 32 # The following keyword are reserved and cannot be used to name

 33 # message types -- "log", "show", "pid", "timestamp", "file", "all".  

 34 # The first five are methods already exist in MashLog and the last

 35 # are used to refered to all defined types.  So for example,

 36 #  MashLog file "all" stdout

 37 # redirects all messages to stdout.

 38 # 

 39 # The following command can help with debugging MashLog.

 40 #  MashLog show

 41 #

 42 # Logging can be turned on and off.  If it is turned off, all logging

 43 # methods are ignored.

 44 #  

 45 
 46 
 47 #---------------------------------------------------------------------

 48 # Class:

 49 #   MashLog

 50 # Description:

 51 #   Implementation of general logging facility in Mash.

 52 #---------------------------------------------------------------------

 53 Class MashLog
 54 
 55 # Turn logging on by default.

 56 MashLog set on_ 1
 57 
 58 #---------------------------------------------------------------------

 59 # Method:

 60 #   MashLog file 

 61 # Description:

 62 #   Create a new channel, and a new procedure for logging 

 63 #   messages.  

 64 # Arguments:

 65 #   type --

 66 #   channel_name -- 

 67 #---------------------------------------------------------------------

 68 MashLog proc file { type channel_name } {
 69     $self instvar chan_by_type_ chan_by_name_ ref_count_ name_by_type_
 70 
 71     # typs is "all" means do this for all existing type.

 72     if {$type == "all"} {
 73         foreach type [array names chan_by_type_] {
 74             MashLog file $type $channel_name
 75         }
 76         return
 77     }
 78 
 79     if {[lsearch {file log pid timestamp} $type] != -1} {
 80         error "$type is a reserved word and cannot be used as log type."
 81     }
 82 
 83     # Clean up existing channel

 84     if {[info exists chan_by_type_($type)]} {
 85         if {$chan_by_type_($type) != "stdout"  &&
 86             $chan_by_type_($type) != "stderr"} {
 87             incr ref_count_($chan_by_type_($type)) -1
 88             if {$ref_count_($chan_by_type_($type)) == 0} {
 89                 # noone is using this channel, close it.

 90                 close $chan_by_type_($type)
 91                 set oldname $name_by_type_($type)
 92                 unset chan_by_name_($oldname)
 93             }
 94         }
 95     }
 96 
 97     set name_by_type_($type) $channel_name
 98 
 99     # A file with that name is already open, share it with this

100     # channel.

101     if [info exists chan_by_name_($channel_name)] {
102         set chan_by_type_($type) $chan_by_name_($channel_name)
103         incr ref_count_($chan_by_type_($type))
104     } else {
105         if {$channel_name != "stdout" && $channel_name != "stderr"} {
106             if {[catch {open $channel_name "w"} f]} {
107                 puts stderr "Unable to open log channel $channel_name"
108             }
109         } else {
110             set f $channel_name
111         }
112         set chan_by_type_($type) $f
113         set chan_by_name_($channel_name) $f
114         set ref_count_($chan_by_type_($type)) 1
115     }
116     MashLog proc $type { msg } "
117         MashLog log $type \$msg
118     "
119 }
120 
121 
122 #---------------------------------------------------------------------

123 # Method:

124 #   MashLog log

125 # Description:

126 #   Print a message to channel with id "type".  If no such type is 

127 #   defined, do nothing.

128 #---------------------------------------------------------------------

129 MashLog proc log { type msg } {
130     $self instvar chan_by_type_ timestamp_ pid_ on_
131     if {!$on_} {
132         return 
133     }
134     if {[info exists timestamp_($type)]} {
135         set msg "[lrange [gettimeofday ascii] 1 3] $msg"
136         #set msg "\[[clock clicks -milliseconds]\] $msg"

137     }
138     if {[info exists pid_($type)]} {
139         set msg "\[$pid_($type)\] $msg"
140     }
141     if {[info exists chan_by_type_($type)]} {
142         puts $chan_by_type_($type) $msg
143         flush $chan_by_type_($type)
144     }
145 }
146 
147 
148 #---------------------------------------------------------------------

149 # Method:

150 #   MashLog timestamp

151 # Description:

152 #   Print a message to channel with id "type"

153 #---------------------------------------------------------------------

154 MashLog proc timestamp { type {onoff  ""} } {
155     $self instvar timestamp_ chan_by_type_
156 
157     if {$type == "all"} {
158         foreach t [array names chan_by_type_] {
159             MashLog timestamp $t $onoff
160         }
161         return
162     }
163     if ![info exists chan_by_type_($type)] {
164         error "no such channel $type"
165     }
166     if {$onoff == ""}  {
167         if [info exists timestamp_($type)] {
168             return on
169         } else {
170             return off
171         }
172     } else {
173         if {$onoff == "on"} {
174             set timestamp_($type) on
175         } else {
176             unset timestamp_($type)
177         }
178     }
179 }
180 
181 
182 #---------------------------------------------------------------------

183 # Method:

184 #   MashLog pid

185 # Description:

186 #   Print a message to channel with id "type"

187 #---------------------------------------------------------------------

188 MashLog proc pid { type {onoff  ""} } {
189     $self instvar pid_ chan_by_type_
190     if {$type == "all"} {
191         foreach t [array names chan_by_type_] {
192             MashLog pid $t $onoff
193         }
194         return
195     }
196     if ![info exists chan_by_type_($type)] {
197         error "no such channel $type"
198     }
199     if {$onoff == ""}  {
200         if [info exists pid_($type)] {
201             return on
202         } else {
203             return off
204         }
205     } else {
206         if {$onoff == "on"} {
207             set pid_($type) [pid]
208         } else {
209             unset pid_($type)
210         }
211     }
212 }
213 
214 
215 #---------------------------------------------------------------------

216 # Method:

217 #   MashLog off

218 # Description:

219 #   Turned off all logging.

220 #---------------------------------------------------------------------

221 MashLog proc off { } {
222     $self instvar on_
223     set on_ 0
224 }
225 
226 
227 #---------------------------------------------------------------------

228 # Method:

229 #   MashLog on

230 # Description:

231 #   Turned on all logging.

232 #---------------------------------------------------------------------

233 MashLog proc on { } {
234     $self instvar on_
235     set on_ 1
236 }
237 
238 
239 #---------------------------------------------------------------------

240 # Method:

241 #   MashLog show

242 # Description:

243 #   Return all existing types and their filename.

244 #---------------------------------------------------------------------

245 MashLog proc show { } {
246     $self instvar chan_by_type_ 
247     return [array get chan_by_type_]
248 }
249 
250 MashLog file info stdout
251 MashLog file warn stderr
252 MashLog file error stderr
253 # 7319752

254 # vim:ts=8:sw=4:expandtab

255 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.