SimpleTrace 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -0
- data/README +4 -0
- data/lib/SimpleTrace.rb +253 -0
- data/samples/Sample1.rb +65 -0
- metadata +39 -0
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This is released under the same terms as the Ruby license.
|
data/README
ADDED
data/lib/SimpleTrace.rb
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
#
|
2
|
+
# SimpleTrace is a very simple tracing facility that will output the file and line
|
3
|
+
# number and date/time when a trace came out.
|
4
|
+
#
|
5
|
+
# It allows:
|
6
|
+
#
|
7
|
+
# * logging to a file or an io stream
|
8
|
+
# * filtering traces by the file that they are in or by the function that they are in
|
9
|
+
# * it can be turned on and off at run time
|
10
|
+
# * always accessible is a global $TRACE variable for tracing (you can choose to use it or not)
|
11
|
+
#
|
12
|
+
# A simple example:
|
13
|
+
#
|
14
|
+
# * s = SimpleTracer.new
|
15
|
+
# * s.set_level 5
|
16
|
+
# * s.trace "hello" ==> outputs: [file.rb:3 ] [09-07-2005 06:43:00] hello
|
17
|
+
#
|
18
|
+
class SimpleTracer
|
19
|
+
#
|
20
|
+
# build a new tracer object
|
21
|
+
#
|
22
|
+
def initialize
|
23
|
+
@trace_level = 0
|
24
|
+
@width = 25
|
25
|
+
@excluded_functions = []
|
26
|
+
@excluded_files = []
|
27
|
+
@output_to_screen_always = false
|
28
|
+
@datetime_format_string = "%m-%d-%Y %H:%M:%S"
|
29
|
+
@save_file = false
|
30
|
+
@filename = nil
|
31
|
+
@indent_level = 0
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# sets the width of the filename portion of the trace
|
36
|
+
#
|
37
|
+
def set_width(width)
|
38
|
+
@width = width
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# The actual tracing routine. The parameters are only a string and a
|
43
|
+
# trace level. If level is less than the current trace level then it
|
44
|
+
# is output
|
45
|
+
#
|
46
|
+
def trace(str, level=1)
|
47
|
+
#old_dollar_equal = $=
|
48
|
+
#$= = false
|
49
|
+
|
50
|
+
if @trace_level >= level then
|
51
|
+
#puts "caller = '#{caller.inspect}'"
|
52
|
+
m = /([\w_]+\.rb):(\d+)(:in `(.*)')?/.match(caller[0])
|
53
|
+
#puts "m[1] = '#{m[1]}'"
|
54
|
+
if m then
|
55
|
+
line = m[2].to_i
|
56
|
+
if /SimpleTrace\.rb$/.match(m[1]) then
|
57
|
+
m = /([\w_]+\.rb):(\d+)(:in `(.*)')?/.match(caller[1])
|
58
|
+
line = m[3].to_i
|
59
|
+
end
|
60
|
+
filename = m[1]
|
61
|
+
if m[4] then
|
62
|
+
function = m[5]
|
63
|
+
else
|
64
|
+
function = "$TOP_LEVEL$"
|
65
|
+
end
|
66
|
+
|
67
|
+
#if $BOB then
|
68
|
+
# print "@width = #{@width}, str = '#{str}', m[1] = '#{m[1]}', m[2] = '#{m[2]}'\n"
|
69
|
+
#end
|
70
|
+
if @datetime_format_string then
|
71
|
+
t = Time.now.strftime(" [#{@datetime_format_string}] ")
|
72
|
+
else
|
73
|
+
t = " "
|
74
|
+
end
|
75
|
+
|
76
|
+
str = sprintf "[%-#{@width}s]%s%s", "#{m[1]}:#{m[2]}", t, str
|
77
|
+
|
78
|
+
if @included_files then
|
79
|
+
return unless @included_files.include?(filename)
|
80
|
+
else
|
81
|
+
if @excluded_functions.include?(function) then
|
82
|
+
return
|
83
|
+
end
|
84
|
+
|
85
|
+
if @excluded_files.include?(filename) then
|
86
|
+
return
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
if @filename then
|
92
|
+
File.open(@filename, "a") {|f| f.print str, "\n"}
|
93
|
+
end
|
94
|
+
|
95
|
+
if !@filename || @output_to_screen_always then
|
96
|
+
STDOUT.puts(str)
|
97
|
+
STDOUT.flush
|
98
|
+
end
|
99
|
+
|
100
|
+
if @io then
|
101
|
+
@io.print str, "\n"
|
102
|
+
@io.flush
|
103
|
+
end
|
104
|
+
=begin
|
105
|
+
|
106
|
+
if !@io || @output_to_screen_always then
|
107
|
+
print str, "\n"
|
108
|
+
$stdout.flush
|
109
|
+
end
|
110
|
+
=end
|
111
|
+
end
|
112
|
+
ensure
|
113
|
+
#$= = old_dollar_equal
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# debug is the same as trace however with the level first. trace is
|
118
|
+
# usually called with the string only (default trace level 1)
|
119
|
+
#
|
120
|
+
def debug(level, str)
|
121
|
+
trace(str, level)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# this sets the current level of tracing and can be called either with
|
126
|
+
# or without a block. Without a block it sets the level permanently
|
127
|
+
# with a block it sets the level for the duration of the block and
|
128
|
+
# then reverts to the last level.
|
129
|
+
#
|
130
|
+
def set_level(level)
|
131
|
+
if block_given? then
|
132
|
+
save_level = @trace_level
|
133
|
+
begin
|
134
|
+
@trace_level = level
|
135
|
+
yield
|
136
|
+
ensure
|
137
|
+
@trace_level = save_level
|
138
|
+
end
|
139
|
+
else
|
140
|
+
@trace_level = level
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# this simple sets the current trace level and sets included files
|
146
|
+
#
|
147
|
+
def set_level_include(level, included_files)
|
148
|
+
@trace_level = level
|
149
|
+
@included_files = included_files
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# This sets whether delete_log will actually delete the
|
154
|
+
# log file when called
|
155
|
+
#
|
156
|
+
def save_log_on_exit (sav = true)
|
157
|
+
@save_file = sav
|
158
|
+
end
|
159
|
+
|
160
|
+
#
|
161
|
+
# this deletes the log file if there is one and if the
|
162
|
+
# object was not directed to delete it
|
163
|
+
#
|
164
|
+
def delete_log
|
165
|
+
if @save_file == false
|
166
|
+
debug 5, "Delete the Log #{@filename}"
|
167
|
+
File.delete(@filename) if @filename
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# this sets the filename for the output log
|
173
|
+
#
|
174
|
+
def set_output_filename(filename)
|
175
|
+
@filename = filename
|
176
|
+
File.open(@filename, "w") {}
|
177
|
+
=begin
|
178
|
+
@io = File.new(filename, "w")
|
179
|
+
if !@io then
|
180
|
+
raise "Can't open trace file '#{filename}'"
|
181
|
+
end
|
182
|
+
=end
|
183
|
+
end
|
184
|
+
|
185
|
+
#
|
186
|
+
# this sets the io stream to output traces to. It is up to the caller
|
187
|
+
# to open (before tracing starts) and close (after tracing ends) this io stream.
|
188
|
+
#
|
189
|
+
def set_output_io(io)
|
190
|
+
@io = io
|
191
|
+
end
|
192
|
+
|
193
|
+
#
|
194
|
+
# calling this allows traces to go to the screen always even if it
|
195
|
+
# is being logged to a file or an io stream
|
196
|
+
#
|
197
|
+
def set_output_to_screen_always
|
198
|
+
@output_to_screen_always = true
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# excludes particular functions from tracing output
|
203
|
+
#
|
204
|
+
def exclude_functions(functions)
|
205
|
+
@excluded_functions += functions
|
206
|
+
end
|
207
|
+
|
208
|
+
#
|
209
|
+
# excludes whole files from tracing output
|
210
|
+
#
|
211
|
+
def exclude_files(filenames)
|
212
|
+
@excluded_files += filenames
|
213
|
+
end
|
214
|
+
|
215
|
+
#
|
216
|
+
# sets the date and time format strings for trace output
|
217
|
+
# the format strings us strftime % vars and if they are both
|
218
|
+
# nil, then no date or time is put out at all.
|
219
|
+
#
|
220
|
+
def set_date_time_format(datetime_format_string)
|
221
|
+
@datetime_format_string = datetime_format_string
|
222
|
+
end
|
223
|
+
|
224
|
+
#
|
225
|
+
# indents the level for tracing output. This is useful for recursive
|
226
|
+
# tracing. If a block is given then an outdent is done automatically at
|
227
|
+
# the end of the block
|
228
|
+
#
|
229
|
+
def indent
|
230
|
+
@indent_level += 2
|
231
|
+
if block_given? then
|
232
|
+
begin
|
233
|
+
yield self
|
234
|
+
ensure
|
235
|
+
outdent
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
#
|
241
|
+
# outdents the tracing. This should correspond to an earlier
|
242
|
+
# indent call
|
243
|
+
#
|
244
|
+
def outdent
|
245
|
+
@indent_level -= 2
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# define the $TRACE variable if not already defined
|
250
|
+
if !$TRACE then
|
251
|
+
$TRACE = SimpleTracer.new
|
252
|
+
end
|
253
|
+
|
data/samples/Sample1.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require "SimpleTrace"
|
3
|
+
|
4
|
+
#
|
5
|
+
# This example of the simplest trace
|
6
|
+
#
|
7
|
+
|
8
|
+
s = SimpleTracer.new
|
9
|
+
|
10
|
+
s.set_level 1 # tracing is off by default
|
11
|
+
s.trace "hello world"
|
12
|
+
|
13
|
+
#
|
14
|
+
# This illustrates the different levels of trace
|
15
|
+
#
|
16
|
+
|
17
|
+
s.set_level 5
|
18
|
+
s.debug 1, "this is a high level trace so it comes out"
|
19
|
+
s.debug 5, "this is a mid level trace and it is at the trace level so it comes out"
|
20
|
+
s.debug 9, "this is a low level trace and so this doesn't come out"
|
21
|
+
|
22
|
+
|
23
|
+
#
|
24
|
+
# This illustrates how the level can be set just for a block. This is useful when
|
25
|
+
# running unit tests so that the level is set only for that failing test
|
26
|
+
#
|
27
|
+
s.debug 9, "this doesn't come out"
|
28
|
+
s.set_level 9 do
|
29
|
+
s.debug 9, "but this does"
|
30
|
+
end
|
31
|
+
s.debug 9, "and this doesn't"
|
32
|
+
|
33
|
+
#
|
34
|
+
# This illustrates how the trace output can go to a file, or io stream and also
|
35
|
+
# to the screen if that is wanted
|
36
|
+
#
|
37
|
+
s.set_output_filename("log.txt")
|
38
|
+
s.debug 5, "this goes in the file"
|
39
|
+
puts "Below is what went in the file"
|
40
|
+
puts File.readlines("log.txt").join("\n")
|
41
|
+
puts "Above is what went in the file"
|
42
|
+
f = File.open("log.txt", "w")
|
43
|
+
|
44
|
+
s.set_output_io(f)
|
45
|
+
s.debug 5, "this goes to an io (which is a file)"
|
46
|
+
f.close
|
47
|
+
puts "Below is what went in the file from IO"
|
48
|
+
puts File.readlines("log.txt").join("\n")
|
49
|
+
puts "Above is what went in the file from IO"
|
50
|
+
s.set_output_io(nil)
|
51
|
+
|
52
|
+
s.set_output_filename("log.txt")
|
53
|
+
s.set_output_to_screen_always
|
54
|
+
s.debug 5, "this will be on the screen first, then in the file"
|
55
|
+
puts "Below is what went in the file plus from IO"
|
56
|
+
puts File.readlines("log.txt").join("\n")
|
57
|
+
puts "Above is what went in the file plus from IO"
|
58
|
+
|
59
|
+
#
|
60
|
+
# You can change or elimate the date and time stamp
|
61
|
+
#
|
62
|
+
s.set_date_time_format("%M:%S")
|
63
|
+
s.trace "Here is just a minutes and seconds trace"
|
64
|
+
s.set_date_time_format(nil)
|
65
|
+
s.trace "Here is one with no date or time stamp at all"
|
metadata
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.3
|
3
|
+
specification_version: 1
|
4
|
+
name: SimpleTrace
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2005-09-13
|
8
|
+
summary: This module implements a simple tracing/logging scheme
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email:
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: SimpleTrace
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors: []
|
28
|
+
files:
|
29
|
+
- "./LICENSE"
|
30
|
+
- "./README"
|
31
|
+
- lib/SimpleTrace.rb
|
32
|
+
- samples/Sample1.rb
|
33
|
+
test_files: []
|
34
|
+
rdoc_options: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
requirements: []
|
39
|
+
dependencies: []
|