debuglog 1.0.0 → 1.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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/History.txt +8 -0
- data/LICENCE +19 -0
- data/README.txt +47 -0
- data/Rakefile +1 -0
- data/TODO.txt +11 -0
- data/debuglog.gemspec +29 -0
- data/doc/debuglog.markdown +278 -262
- data/etc/example.rb +24 -0
- data/lib/debuglog.rb +17 -17
- data/lib/debuglog/auto.rb +2 -2
- data/lib/debuglog/manual.rb +177 -177
- data/lib/debuglog/version.rb +3 -0
- data/test/_setup.rb +13 -14
- data/test/debuglog-auto.rb +79 -66
- data/test/debuglog-manual-1.rb +41 -39
- data/test/debuglog-manual-2.rb +29 -27
- metadata +62 -45
- data/README +0 -38
data/etc/example.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'debuglog'
|
2
|
+
|
3
|
+
debug "Starting example program"
|
4
|
+
x = 6
|
5
|
+
trace :x, binding
|
6
|
+
trace "ENV['rvm_bin_path']", binding
|
7
|
+
|
8
|
+
debug "Environment variables containing PATH"
|
9
|
+
keys = ENV.keys.grep /PATH/
|
10
|
+
keys.each do |key|
|
11
|
+
trace " ENV[#{key.inspect}]", binding, 40
|
12
|
+
end
|
13
|
+
|
14
|
+
debug "(end of list)"
|
15
|
+
|
16
|
+
t = time('sleep 3.52') { sleep 3.52 }
|
17
|
+
debug "Time actually slept (rounded): #{t}"
|
18
|
+
|
19
|
+
debug ""
|
20
|
+
debug "Multi-\nline\ntext\n with an indented (3 spaces) final line"
|
21
|
+
debug ""
|
22
|
+
debug "Display large array/hash with pp"
|
23
|
+
hash = ENV.select { |k,v| k =~ /PATH/ }
|
24
|
+
trace :hash, binding
|
data/lib/debuglog.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
#
|
2
|
-
# Usage:
|
3
|
-
#
|
4
|
-
# require 'debuglog'
|
5
|
-
# debug "..." # -> writes "..." to 'debug.log'
|
6
|
-
#
|
7
|
-
# Note: +debug+ is the _default_ method name. You can set a different one like
|
8
|
-
# this:
|
9
|
-
#
|
10
|
-
# require 'debuglog/manual'
|
11
|
-
# DebugLog.configure(...) # todo: complete
|
12
|
-
# dbg "..." # -> writes "..." to 'debug.log'
|
13
|
-
#
|
14
|
-
# If +debug+ (or the name you choose manually) is the name of an existing
|
15
|
-
# method, it will _not_ be overwritten.
|
16
|
-
|
17
|
-
require 'debuglog/auto'
|
1
|
+
#
|
2
|
+
# Usage:
|
3
|
+
#
|
4
|
+
# require 'debuglog'
|
5
|
+
# debug "..." # -> writes "..." to 'debug.log'
|
6
|
+
#
|
7
|
+
# Note: +debug+ is the _default_ method name. You can set a different one like
|
8
|
+
# this:
|
9
|
+
#
|
10
|
+
# require 'debuglog/manual'
|
11
|
+
# DebugLog.configure(...) # todo: complete
|
12
|
+
# dbg "..." # -> writes "..." to 'debug.log'
|
13
|
+
#
|
14
|
+
# If +debug+ (or the name you choose manually) is the name of an existing
|
15
|
+
# method, it will _not_ be overwritten.
|
16
|
+
|
17
|
+
require 'debuglog/auto'
|
data/lib/debuglog/auto.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'debuglog/manual'
|
2
|
-
DebugLog.autoconfigure
|
1
|
+
require 'debuglog/manual'
|
2
|
+
DebugLog.autoconfigure
|
data/lib/debuglog/manual.rb
CHANGED
@@ -1,177 +1,177 @@
|
|
1
|
-
#
|
2
|
-
# require 'debuglog/manual'
|
3
|
-
#
|
4
|
-
# DebugLog.configure(:debug => :dbg)
|
5
|
-
# dbg "..." # -> writes "..." to file 'debug.log'
|
6
|
-
#
|
7
|
-
|
8
|
-
class DebugLog
|
9
|
-
|
10
|
-
@@instance = nil
|
11
|
-
|
12
|
-
DEFAULT_CONFIGURATION = {
|
13
|
-
:debug => :debug,
|
14
|
-
:trace => :trace,
|
15
|
-
:time => :time,
|
16
|
-
:file => 'debug.log'
|
17
|
-
}
|
18
|
-
|
19
|
-
class Error < StandardError; end
|
20
|
-
|
21
|
-
def DebugLog.err(string)
|
22
|
-
raise ::DebugLog::Error, "DebugLog error -- #{string}"
|
23
|
-
end
|
24
|
-
|
25
|
-
def DebugLog.configure(hash)
|
26
|
-
if @@instance.nil?
|
27
|
-
@@instance = DebugLog.new(hash)
|
28
|
-
else
|
29
|
-
err("DebugLog already configured") # todo: replace
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def DebugLog.autoconfigure
|
34
|
-
configure(DEFAULT_CONFIGURATION)
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(config)
|
38
|
-
@kernel_methods_defined = []
|
39
|
-
_create_kernel_method(config[:debug], :debug)
|
40
|
-
_create_kernel_method(config[:trace], :trace)
|
41
|
-
_create_kernel_method(config[:time], :time)
|
42
|
-
@filename = config[:filename] || 'debug.log'
|
43
|
-
begin
|
44
|
-
@fh = File.open(@filename, 'w')
|
45
|
-
rescue => e
|
46
|
-
raise DebugLog::Error, "#{e.class} (#{e.message})"
|
47
|
-
end
|
48
|
-
@fh.sync = true
|
49
|
-
@start_time = Time.now
|
50
|
-
header = "DebugLog -- #{@start_time}"
|
51
|
-
@fh.puts header
|
52
|
-
@fh.puts('-' * header.length)
|
53
|
-
end
|
54
|
-
|
55
|
-
def debug(*args)
|
56
|
-
string = args.map { |x| x.to_s }.join
|
57
|
-
_write(string)
|
58
|
-
end
|
59
|
-
|
60
|
-
def trace(expr, _binding, *options)
|
61
|
-
value = eval expr, _binding
|
62
|
-
require 'pp'
|
63
|
-
formatter = :pretty_inspect
|
64
|
-
## if (m = options.find { |o| o.is_a? Symbol })
|
65
|
-
## case m
|
66
|
-
## when :p then :inspect
|
67
|
-
## when :s, :to_s then :to_s
|
68
|
-
## when :pp then (require 'pp'; :pretty_inspect)
|
69
|
-
## when :yaml then (require 'yaml'; :to_yaml)
|
70
|
-
## when :ap then (require 'ap'; :ap)
|
71
|
-
## else then :inspect
|
72
|
-
## end
|
73
|
-
## else
|
74
|
-
## :inspect
|
75
|
-
## end
|
76
|
-
value = value.send(formatter)
|
77
|
-
if (n = options.find { |o| o.is_a? Integer })
|
78
|
-
value = value[0...n] + "..."
|
79
|
-
end
|
80
|
-
message =
|
81
|
-
if value.index("\n")
|
82
|
-
value = value.gsub(/^/, ' ')
|
83
|
-
"#{expr} ==\n#{value}"
|
84
|
-
else
|
85
|
-
"#{expr} == #{value}"
|
86
|
-
end
|
87
|
-
_write(message)
|
88
|
-
end
|
89
|
-
|
90
|
-
def time(task, &block)
|
91
|
-
result = nil
|
92
|
-
message =
|
93
|
-
if block.nil?
|
94
|
-
"*** Debuglog.task: block required (#{caller[0]}) ***"
|
95
|
-
else
|
96
|
-
t = Time.now
|
97
|
-
result = block.call
|
98
|
-
t = sprintf "%.3f", (Time.now - t)
|
99
|
-
"#{task}: #{t} sec"
|
100
|
-
end
|
101
|
-
_write(message)
|
102
|
-
result
|
103
|
-
end
|
104
|
-
|
105
|
-
def _write(message)
|
106
|
-
time = (Time.now - @start_time)
|
107
|
-
if time.to_i != @time.to_i
|
108
|
-
elapsed = time.to_i - @time.to_i
|
109
|
-
if elapsed > 1
|
110
|
-
@fh.puts "------- (#{elapsed} sec)"
|
111
|
-
else
|
112
|
-
@fh.puts "-------"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
@time = time
|
116
|
-
time = sprintf "%04.1f", time.to_f
|
117
|
-
if message.index("\n")
|
118
|
-
lines = message.split("\n")
|
119
|
-
@fh.puts "[#{time}] #{lines.shift}"
|
120
|
-
indent = " " * (time.size+3)
|
121
|
-
lines.each do |line| @fh.puts "#{indent}#{line}" end
|
122
|
-
else
|
123
|
-
text = "[#{time}] #{message}"
|
124
|
-
@fh.puts(text)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def _create_kernel_method(name, target)
|
129
|
-
if name.nil?
|
130
|
-
return
|
131
|
-
elsif Kernel.respond_to? name
|
132
|
-
DebugLog.err "DebugLog: Method clash in Kernel: #{name.inspect}"
|
133
|
-
else
|
134
|
-
Kernel.module_eval %{
|
135
|
-
def #{name}(*args, &block)
|
136
|
-
DebugLog.call_method(:#{target}, *args, &block)
|
137
|
-
end
|
138
|
-
}, __FILE__, __LINE__ - 4
|
139
|
-
@kernel_methods_defined << name
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
DEBUG_METHODS = [:debug, :trace, :time]
|
144
|
-
def DebugLog.call_method(name, *args, &block)
|
145
|
-
if DEBUG_METHODS.include? name
|
146
|
-
if @@instance
|
147
|
-
@@instance.send(name, *args, &block)
|
148
|
-
else
|
149
|
-
err %{
|
150
|
-
~ DebugLog is not configured. You can:
|
151
|
-
~ * require 'debuglog/auto' or call DebugLog.autoconfigure; or
|
152
|
-
~ * call DebugLog.configure(...) to configure it manually
|
153
|
-
}.strip.gsub(/^\s+~ /, '')
|
154
|
-
end
|
155
|
-
else
|
156
|
-
err "illegitimate method called: #{name}"
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def terminate # For testing
|
161
|
-
@fh.close unless @fh.closed?
|
162
|
-
@kernel_methods_defined.each do |m|
|
163
|
-
Kernel.send(:remove_method, m)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
private :terminate
|
167
|
-
|
168
|
-
def DebugLog.wipe_slate_clean_for_testing
|
169
|
-
if @@instance
|
170
|
-
@@instance.send(:terminate)
|
171
|
-
@@instance = nil
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
end # class DebugLog
|
176
|
-
|
177
|
-
Debuglog = DebugLog
|
1
|
+
#
|
2
|
+
# require 'debuglog/manual'
|
3
|
+
#
|
4
|
+
# DebugLog.configure(:debug => :dbg)
|
5
|
+
# dbg "..." # -> writes "..." to file 'debug.log'
|
6
|
+
#
|
7
|
+
|
8
|
+
class DebugLog
|
9
|
+
|
10
|
+
@@instance = nil
|
11
|
+
|
12
|
+
DEFAULT_CONFIGURATION = {
|
13
|
+
:debug => :debug,
|
14
|
+
:trace => :trace,
|
15
|
+
:time => :time,
|
16
|
+
:file => 'debug.log'
|
17
|
+
}
|
18
|
+
|
19
|
+
class Error < StandardError; end
|
20
|
+
|
21
|
+
def DebugLog.err(string)
|
22
|
+
raise ::DebugLog::Error, "DebugLog error -- #{string}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def DebugLog.configure(hash)
|
26
|
+
if @@instance.nil?
|
27
|
+
@@instance = DebugLog.new(hash)
|
28
|
+
else
|
29
|
+
err("DebugLog already configured") # todo: replace
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def DebugLog.autoconfigure
|
34
|
+
configure(DEFAULT_CONFIGURATION)
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(config)
|
38
|
+
@kernel_methods_defined = []
|
39
|
+
_create_kernel_method(config[:debug], :debug)
|
40
|
+
_create_kernel_method(config[:trace], :trace)
|
41
|
+
_create_kernel_method(config[:time], :time)
|
42
|
+
@filename = config[:filename] || 'debug.log'
|
43
|
+
begin
|
44
|
+
@fh = File.open(@filename, 'w')
|
45
|
+
rescue => e
|
46
|
+
raise DebugLog::Error, "#{e.class} (#{e.message})"
|
47
|
+
end
|
48
|
+
@fh.sync = true
|
49
|
+
@start_time = Time.now
|
50
|
+
header = "DebugLog -- #{@start_time}"
|
51
|
+
@fh.puts header
|
52
|
+
@fh.puts('-' * header.length)
|
53
|
+
end
|
54
|
+
|
55
|
+
def debug(*args)
|
56
|
+
string = args.map { |x| x.to_s }.join
|
57
|
+
_write(string)
|
58
|
+
end
|
59
|
+
|
60
|
+
def trace(expr, _binding, *options)
|
61
|
+
value = eval expr.to_s, _binding
|
62
|
+
require 'pp'
|
63
|
+
formatter = :pretty_inspect
|
64
|
+
## if (m = options.find { |o| o.is_a? Symbol })
|
65
|
+
## case m
|
66
|
+
## when :p then :inspect
|
67
|
+
## when :s, :to_s then :to_s
|
68
|
+
## when :pp then (require 'pp'; :pretty_inspect)
|
69
|
+
## when :yaml then (require 'yaml'; :to_yaml)
|
70
|
+
## when :ap then (require 'ap'; :ap)
|
71
|
+
## else then :inspect
|
72
|
+
## end
|
73
|
+
## else
|
74
|
+
## :inspect
|
75
|
+
## end
|
76
|
+
value = value.send(formatter).strip
|
77
|
+
if (n = options.find { |o| o.is_a? Integer })
|
78
|
+
value = value[0...n] + "..." if value.length > n
|
79
|
+
end
|
80
|
+
message =
|
81
|
+
if value.index("\n")
|
82
|
+
value = value.gsub(/^/, ' ')
|
83
|
+
"#{expr} ==\n#{value}"
|
84
|
+
else
|
85
|
+
"#{expr} == #{value}"
|
86
|
+
end
|
87
|
+
_write(message)
|
88
|
+
end
|
89
|
+
|
90
|
+
def time(task, &block)
|
91
|
+
result = nil
|
92
|
+
message =
|
93
|
+
if block.nil?
|
94
|
+
"*** Debuglog.task: block required (#{caller[0]}) ***"
|
95
|
+
else
|
96
|
+
t = Time.now
|
97
|
+
result = block.call
|
98
|
+
t = sprintf "%.3f", (Time.now - t)
|
99
|
+
"#{task}: #{t} sec"
|
100
|
+
end
|
101
|
+
_write(message)
|
102
|
+
result
|
103
|
+
end
|
104
|
+
|
105
|
+
def _write(message)
|
106
|
+
time = (Time.now - @start_time)
|
107
|
+
if time.to_i != @time.to_i
|
108
|
+
elapsed = time.to_i - @time.to_i
|
109
|
+
if elapsed > 1
|
110
|
+
@fh.puts "------- (#{elapsed} sec)"
|
111
|
+
else
|
112
|
+
@fh.puts "-------"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
@time = time
|
116
|
+
time = sprintf "%04.1f", time.to_f
|
117
|
+
if message.index("\n")
|
118
|
+
lines = message.split("\n")
|
119
|
+
@fh.puts "[#{time}] #{lines.shift}"
|
120
|
+
indent = " " * (time.size+3)
|
121
|
+
lines.each do |line| @fh.puts "#{indent}#{line}" end
|
122
|
+
else
|
123
|
+
text = "[#{time}] #{message}"
|
124
|
+
@fh.puts(text)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def _create_kernel_method(name, target)
|
129
|
+
if name.nil?
|
130
|
+
return
|
131
|
+
elsif Kernel.respond_to? name
|
132
|
+
DebugLog.err "DebugLog: Method clash in Kernel: #{name.inspect}"
|
133
|
+
else
|
134
|
+
Kernel.module_eval %{
|
135
|
+
def #{name}(*args, &block)
|
136
|
+
DebugLog.call_method(:#{target}, *args, &block)
|
137
|
+
end
|
138
|
+
}, __FILE__, __LINE__ - 4
|
139
|
+
@kernel_methods_defined << name
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
DEBUG_METHODS = [:debug, :trace, :time]
|
144
|
+
def DebugLog.call_method(name, *args, &block)
|
145
|
+
if DEBUG_METHODS.include? name
|
146
|
+
if @@instance
|
147
|
+
@@instance.send(name, *args, &block)
|
148
|
+
else
|
149
|
+
err %{
|
150
|
+
~ DebugLog is not configured. You can:
|
151
|
+
~ * require 'debuglog/auto' or call DebugLog.autoconfigure; or
|
152
|
+
~ * call DebugLog.configure(...) to configure it manually
|
153
|
+
}.strip.gsub(/^\s+~ /, '')
|
154
|
+
end
|
155
|
+
else
|
156
|
+
err "illegitimate method called: #{name}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def terminate # For testing
|
161
|
+
@fh.close unless @fh.closed?
|
162
|
+
@kernel_methods_defined.each do |m|
|
163
|
+
Kernel.send(:remove_method, m)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
private :terminate
|
167
|
+
|
168
|
+
def DebugLog.wipe_slate_clean_for_testing
|
169
|
+
if @@instance
|
170
|
+
@@instance.send(:terminate)
|
171
|
+
@@instance = nil
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end # class DebugLog
|
176
|
+
|
177
|
+
Debuglog = DebugLog
|
data/test/_setup.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
require 'debuglog'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
:
|
6
|
-
:
|
7
|
-
|
8
|
-
file_data
|
9
|
-
test('file
|
10
|
-
|
11
|
-
last_line
|
12
|
-
|
13
|
-
|
14
|
-
}
|
1
|
+
require 'debuglog'
|
2
|
+
|
3
|
+
Whitestone.custom :debuglog, {
|
4
|
+
:description => "Last line of log file",
|
5
|
+
:parameters => [ [:regex, Regexp], [:filename, String] ],
|
6
|
+
:run => proc {
|
7
|
+
file_data = File.read(filename)
|
8
|
+
test('file exists') { N! file_data }
|
9
|
+
test('file has data in it') { file_data.size > 0 }
|
10
|
+
last_line = file_data.split("\n").last
|
11
|
+
test('match') { Mt last_line, regex }
|
12
|
+
}
|
13
|
+
}
|