scout-gear 7.3.0 → 8.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.vimproject +44 -16
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/bin/scout +21 -7
- data/doc/lib/scout/path.md +35 -0
- data/doc/lib/scout/workflow/task.md +13 -0
- data/lib/rbbt-scout.rb +1 -0
- data/lib/scout/cmd.rb +24 -25
- data/lib/scout/concurrent_stream.rb +59 -39
- data/lib/scout/config.rb +1 -1
- data/lib/scout/exceptions.rb +10 -0
- data/lib/scout/log/color.rb +15 -12
- data/lib/scout/log/progress/report.rb +8 -6
- data/lib/scout/log/progress/util.rb +61 -54
- data/lib/scout/log/progress.rb +1 -1
- data/lib/scout/log/trap.rb +107 -0
- data/lib/scout/log.rb +115 -52
- data/lib/scout/meta_extension.rb +47 -6
- data/lib/scout/misc/digest.rb +12 -3
- data/lib/scout/misc/format.rb +24 -7
- data/lib/scout/misc/insist.rb +1 -1
- data/lib/scout/misc/monitor.rb +22 -0
- data/lib/scout/misc/system.rb +58 -0
- data/lib/scout/named_array.rb +73 -3
- data/lib/scout/offsite/ssh.rb +171 -0
- data/lib/scout/offsite/step.rb +83 -0
- data/lib/scout/offsite/sync.rb +55 -0
- data/lib/scout/offsite.rb +3 -0
- data/lib/scout/open/lock/lockfile.rb +587 -0
- data/lib/scout/open/lock.rb +9 -2
- data/lib/scout/open/remote.rb +16 -1
- data/lib/scout/open/stream.rb +146 -83
- data/lib/scout/open/util.rb +22 -3
- data/lib/scout/open.rb +5 -4
- data/lib/scout/path/find.rb +24 -11
- data/lib/scout/path/util.rb +40 -0
- data/lib/scout/persist/serialize.rb +19 -6
- data/lib/scout/persist.rb +29 -13
- data/lib/scout/resource/path.rb +57 -0
- data/lib/scout/resource/produce.rb +0 -8
- data/lib/scout/resource/util.rb +12 -5
- data/lib/scout/tmpfile.rb +7 -8
- data/lib/scout/tsv/attach.rb +177 -0
- data/lib/scout/tsv/change_id.rb +40 -0
- data/lib/scout/tsv/dumper.rb +74 -46
- data/lib/scout/tsv/index.rb +85 -87
- data/lib/scout/tsv/open.rb +160 -85
- data/lib/scout/tsv/parser.rb +142 -80
- data/lib/scout/tsv/path.rb +1 -2
- data/lib/scout/tsv/persist/adapter.rb +15 -45
- data/lib/scout/tsv/persist/fix_width_table.rb +3 -0
- data/lib/scout/tsv/persist/tokyocabinet.rb +6 -1
- data/lib/scout/tsv/persist.rb +4 -0
- data/lib/scout/tsv/stream.rb +204 -0
- data/lib/scout/tsv/transformer.rb +152 -0
- data/lib/scout/tsv/traverse.rb +96 -92
- data/lib/scout/tsv/util/filter.rb +9 -0
- data/lib/scout/tsv/util/reorder.rb +81 -0
- data/lib/scout/tsv/util/select.rb +78 -33
- data/lib/scout/tsv/util/unzip.rb +86 -0
- data/lib/scout/tsv/util.rb +60 -11
- data/lib/scout/tsv.rb +34 -4
- data/lib/scout/work_queue/socket.rb +6 -1
- data/lib/scout/work_queue/worker.rb +5 -2
- data/lib/scout/work_queue.rb +51 -20
- data/lib/scout/workflow/definition.rb +23 -3
- data/lib/scout/workflow/deployment/orchestrator.rb +245 -0
- data/lib/scout/workflow/deployment.rb +1 -0
- data/lib/scout/workflow/step/dependencies.rb +56 -10
- data/lib/scout/workflow/step/file.rb +5 -0
- data/lib/scout/workflow/step/info.rb +40 -7
- data/lib/scout/workflow/step/load.rb +1 -1
- data/lib/scout/workflow/step/provenance.rb +9 -7
- data/lib/scout/workflow/step/status.rb +43 -0
- data/lib/scout/workflow/step.rb +160 -49
- data/lib/scout/workflow/task/dependencies.rb +114 -0
- data/lib/scout/workflow/task/inputs.rb +40 -32
- data/lib/scout/workflow/task.rb +38 -102
- data/lib/scout/workflow/usage.rb +48 -18
- data/lib/scout/workflow.rb +4 -2
- data/lib/scout-gear.rb +2 -0
- data/lib/scout.rb +6 -0
- data/scout-gear.gemspec +52 -23
- data/scout_commands/doc +37 -0
- data/scout_commands/find +1 -0
- data/scout_commands/offsite +30 -0
- data/scout_commands/update +29 -0
- data/scout_commands/workflow/info +15 -3
- data/scout_commands/workflow/install +102 -0
- data/scout_commands/workflow/task +57 -9
- data/test/scout/offsite/test_ssh.rb +15 -0
- data/test/scout/offsite/test_step.rb +33 -0
- data/test/scout/offsite/test_sync.rb +36 -0
- data/test/scout/offsite/test_task.rb +0 -0
- data/test/scout/open/test_stream.rb +60 -58
- data/test/scout/path/test_find.rb +10 -1
- data/test/scout/resource/test_path.rb +6 -0
- data/test/scout/resource/test_produce.rb +15 -0
- data/test/scout/test_meta_extension.rb +25 -0
- data/test/scout/test_named_array.rb +24 -0
- data/test/scout/test_persist.rb +9 -2
- data/test/scout/test_tsv.rb +229 -2
- data/test/scout/test_work_queue.rb +65 -41
- data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
- data/test/scout/tsv/test_attach.rb +227 -0
- data/test/scout/tsv/test_change_id.rb +98 -0
- data/test/scout/tsv/test_dumper.rb +1 -1
- data/test/scout/tsv/test_index.rb +49 -3
- data/test/scout/tsv/test_open.rb +160 -2
- data/test/scout/tsv/test_parser.rb +33 -2
- data/test/scout/tsv/test_persist.rb +2 -0
- data/test/scout/tsv/test_stream.rb +200 -0
- data/test/scout/tsv/test_transformer.rb +120 -0
- data/test/scout/tsv/test_traverse.rb +88 -3
- data/test/scout/tsv/test_util.rb +1 -0
- data/test/scout/tsv/util/test_reorder.rb +94 -0
- data/test/scout/tsv/util/test_select.rb +25 -11
- data/test/scout/tsv/util/test_unzip.rb +112 -0
- data/test/scout/work_queue/test_socket.rb +0 -1
- data/test/scout/workflow/deployment/test_orchestrator.rb +272 -0
- data/test/scout/workflow/step/test_dependencies.rb +68 -0
- data/test/scout/workflow/step/test_info.rb +18 -0
- data/test/scout/workflow/step/test_status.rb +30 -0
- data/test/scout/workflow/task/test_dependencies.rb +355 -0
- data/test/scout/workflow/task/test_inputs.rb +67 -14
- data/test/scout/workflow/test_definition.rb +18 -0
- data/test/scout/workflow/test_documentation.rb +24 -0
- data/test/scout/workflow/test_step.rb +112 -3
- data/test/scout/workflow/test_task.rb +0 -151
- data/test/scout/workflow/test_usage.rb +33 -6
- data/test/test_scout.rb +9 -0
- metadata +100 -8
- data/scout_commands/workflow/task_old +0 -706
data/lib/scout/config.rb
CHANGED
@@ -148,7 +148,7 @@ module Scout::Config
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def self.process_config(config)
|
151
|
-
if
|
151
|
+
if Path.is_filename?(config) && File.exist?(config)
|
152
152
|
Scout::Config.load_file(config)
|
153
153
|
elsif Scout.etc.config_profile[config].exists?
|
154
154
|
Scout::Config.load_file(Scout.etc.config_profile[config].find)
|
data/lib/scout/exceptions.rb
CHANGED
@@ -139,3 +139,13 @@ class SemaphoreInterrupted < TryAgain; end
|
|
139
139
|
#
|
140
140
|
#
|
141
141
|
class ResourceNotFound < ScoutException; end
|
142
|
+
|
143
|
+
class SSHProcessFailed < StandardError
|
144
|
+
attr_accessor :host, :cmd
|
145
|
+
def initialize(host, cmd)
|
146
|
+
@host = host
|
147
|
+
@cmd = cmd
|
148
|
+
message = "SSH server #{host} failed cmd '#{cmd}'"
|
149
|
+
super(message)
|
150
|
+
end
|
151
|
+
end
|
data/lib/scout/log/color.rb
CHANGED
@@ -10,8 +10,8 @@ module Colorize
|
|
10
10
|
|
11
11
|
def self.colors
|
12
12
|
@colors ||= IndiferentHash.setup(Hash[<<-EOF.split("\n").collect{|l| l.split(" ")}])
|
13
|
-
green #00cd00
|
14
|
-
red #cd0000
|
13
|
+
green #00cd00
|
14
|
+
red #cd0000
|
15
15
|
yellow #ffd700
|
16
16
|
blue #0000cd
|
17
17
|
path blue
|
@@ -49,26 +49,26 @@ EOF
|
|
49
49
|
when "black"
|
50
50
|
'#fff'
|
51
51
|
when 'green'
|
52
|
-
colors["green3"]
|
52
|
+
colors["green3"]
|
53
53
|
when 'red'
|
54
|
-
colors["red3"]
|
54
|
+
colors["red3"]
|
55
55
|
when 'yellow'
|
56
|
-
colors["gold1"]
|
56
|
+
colors["gold1"]
|
57
57
|
when 'blue'
|
58
|
-
colors["RoyalBlue"]
|
58
|
+
colors["RoyalBlue"]
|
59
59
|
else
|
60
60
|
colors[color.to_s] || color.to_s
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def self.continuous(array, start = "#40324F", eend = "#EABD5D", percent = false)
|
64
|
+
def self.continuous(array, start = "#40324F", eend = "#EABD5D", percent = false)
|
65
65
|
start_color = Color.new from_name(start)
|
66
66
|
end_color = Color.new from_name(eend)
|
67
67
|
|
68
68
|
if percent
|
69
69
|
array = array.collect{|v| n = v.to_f; n = n > 100 ? 100 : n; n < 0.001 ? 0.001 : n}
|
70
70
|
else
|
71
|
-
array = array.collect{|v| v.to_f }
|
71
|
+
array = array.collect{|v| v.to_f }
|
72
72
|
end
|
73
73
|
max = array.max
|
74
74
|
min = array.min
|
@@ -134,7 +134,7 @@ module Log
|
|
134
134
|
attr_accessor :nocolor
|
135
135
|
end
|
136
136
|
|
137
|
-
self.nocolor = ENV["
|
137
|
+
self.nocolor = ENV["SCOUT_NOCOLOR"] == 'true'
|
138
138
|
|
139
139
|
WHITE, DARK, GREEN, YELLOW, RED = Color::SOLARIZED.values_at :base0, :base00, :green, :yellow, :magenta
|
140
140
|
|
@@ -152,9 +152,12 @@ module Log
|
|
152
152
|
:start => cyan,
|
153
153
|
:done => green,
|
154
154
|
:error => red,
|
155
|
+
:time => cyan,
|
156
|
+
:task => yellow,
|
157
|
+
:workflow => yellow,
|
155
158
|
})
|
156
159
|
HIGHLIGHT = "\033[1m"
|
157
|
-
|
160
|
+
|
158
161
|
def self.uncolor(str)
|
159
162
|
"" << Term::ANSIColor.uncolor(str)
|
160
163
|
end
|
@@ -164,7 +167,7 @@ module Log
|
|
164
167
|
end
|
165
168
|
|
166
169
|
def self.color(color, str = nil, reset = false)
|
167
|
-
return str.dup || "" if nocolor
|
170
|
+
return str.dup || "" if nocolor
|
168
171
|
|
169
172
|
if (color == :integer || color == :float) && Numeric === str
|
170
173
|
color = if str < 0
|
@@ -176,7 +179,7 @@ module Log
|
|
176
179
|
end
|
177
180
|
end
|
178
181
|
|
179
|
-
if color == :status
|
182
|
+
if color == :status
|
180
183
|
color = case str.to_sym
|
181
184
|
when :done
|
182
185
|
:green
|
@@ -4,8 +4,7 @@ module Log
|
|
4
4
|
def print(io, str)
|
5
5
|
return if self.severity && self.severity < Log.severity
|
6
6
|
return if Log.no_bar
|
7
|
-
|
8
|
-
Log.logfile.puts str unless Log.logfile.nil?
|
7
|
+
Log.log_write str
|
9
8
|
Log::LAST.replace "progress"
|
10
9
|
end
|
11
10
|
|
@@ -57,9 +56,12 @@ module Log
|
|
57
56
|
thr = short_mean
|
58
57
|
else
|
59
58
|
thr = begin
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
d = Time.now - @start
|
60
|
+
if d == 0
|
61
|
+
1
|
62
|
+
else
|
63
|
+
(@ticks || 1) / d
|
64
|
+
end
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
@@ -229,7 +231,7 @@ module Log
|
|
229
231
|
done_msg << Log.color(:magenta, " · " << desc)
|
230
232
|
print(io, Log.up_lines(@depth) << done_msg << Log.down_lines(@depth))
|
231
233
|
|
232
|
-
|
234
|
+
FileUtils.rm file if file and File.exist?(file)
|
233
235
|
|
234
236
|
begin
|
235
237
|
@callback.call self
|
@@ -29,7 +29,7 @@ module Log
|
|
29
29
|
|
30
30
|
def self.new_bar(max, options = {})
|
31
31
|
options, max = max, nil if Hash === max
|
32
|
-
max = options[:max] if max.nil?
|
32
|
+
max = options[:max] if options && max.nil?
|
33
33
|
cleanup_bars
|
34
34
|
BAR_MUTEX.synchronize do
|
35
35
|
Log::LAST.replace "new_bar" if Log::LAST == "progress"
|
@@ -74,6 +74,7 @@ module Log
|
|
74
74
|
BAR_MUTEX.synchronize do
|
75
75
|
REMOVE << bar
|
76
76
|
end
|
77
|
+
cleanup_bars
|
77
78
|
Log::LAST.replace "remove_bar" if Log::LAST == "progress"
|
78
79
|
end
|
79
80
|
|
@@ -82,7 +83,7 @@ module Log
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def self.with_bar(max = nil, options = {})
|
85
|
-
bar = new_bar(max, options)
|
86
|
+
bar = options.include?(:bar) ? options[:bar] : new_bar(max, options)
|
86
87
|
begin
|
87
88
|
error = false
|
88
89
|
keep = false
|
@@ -98,69 +99,75 @@ module Log
|
|
98
99
|
end
|
99
100
|
|
100
101
|
def self.guess_obj_max(obj)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
102
|
+
begin
|
103
|
+
case obj
|
104
|
+
when (defined? Step and Step)
|
105
|
+
if obj.done?
|
106
|
+
path = obj.path
|
107
|
+
path = path.find if path.respond_to? :find
|
108
|
+
if File.exist? path
|
109
|
+
CMD.cmd("wc -l '#{path}'").read.to_i
|
110
|
+
else
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
else
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
when TSV
|
117
|
+
obj.length
|
118
|
+
when Array, Hash
|
119
|
+
obj.size
|
120
|
+
when File
|
121
|
+
return nil if Open.gzip?(obj.filename) or Open.bgzip?(obj.filename) or Open.remote?(obj.filename)
|
122
|
+
CMD.cmd("wc -l '#{obj.filename}'").read.to_i
|
123
|
+
when Path, String
|
124
|
+
obj = obj.find if Path === obj
|
125
|
+
if File.exist? obj
|
126
|
+
return nil if Open.gzip?(obj) or Open.bgzip?(obj)
|
127
|
+
CMD.cmd("wc -l '#{obj}'").read.to_i
|
109
128
|
else
|
110
129
|
nil
|
111
130
|
end
|
112
|
-
else
|
113
|
-
nil
|
114
|
-
end
|
115
|
-
when TSV
|
116
|
-
obj.length
|
117
|
-
when Array, Hash
|
118
|
-
obj.size
|
119
|
-
when File
|
120
|
-
return nil if Open.gzip?(obj) or Open.bgzip?(obj)
|
121
|
-
CMD.cmd("wc -l '#{obj.path}'").read.to_i
|
122
|
-
when Path, String
|
123
|
-
obj = obj.find if Path === obj
|
124
|
-
if File.exist? obj
|
125
|
-
return nil if Open.gzip?(obj) or Open.bgzip?(obj)
|
126
|
-
CMD.cmd("wc -l '#{obj}'").read.to_i
|
127
|
-
else
|
128
|
-
nil
|
129
131
|
end
|
132
|
+
rescue Interrupt
|
133
|
+
raise $!
|
134
|
+
rescue Exception
|
135
|
+
nil
|
130
136
|
end
|
131
|
-
rescue Exception
|
132
|
-
Log.exception $!
|
133
|
-
nil
|
134
137
|
end
|
135
|
-
end
|
136
138
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
Log::ProgressBar.new_bar(max, {:desc => bar})
|
142
|
-
when TrueClass
|
143
|
-
max = guess_obj_max(obj)
|
144
|
-
Log::ProgressBar.new_bar(max, nil)
|
145
|
-
when Numeric
|
146
|
-
max = guess_obj_max(obj)
|
147
|
-
Log::ProgressBar.new_bar(bar)
|
148
|
-
when Hash
|
149
|
-
max = Misc.process_options(bar, :max) || max
|
150
|
-
Log::ProgressBar.new_bar(max, bar)
|
151
|
-
when Log::ProgressBar
|
152
|
-
bar.max ||= guess_obj_max(obj)
|
153
|
-
bar
|
154
|
-
else
|
155
|
-
if (defined? Step and Step === bar)
|
139
|
+
def self.get_obj_bar(obj, bar = nil)
|
140
|
+
return nil if bar.nil? || bar == false
|
141
|
+
case bar
|
142
|
+
when String
|
156
143
|
max = guess_obj_max(obj)
|
157
|
-
Log::ProgressBar.new_bar(max, {:desc => bar
|
158
|
-
|
144
|
+
Log::ProgressBar.new_bar(max, {:desc => bar})
|
145
|
+
when TrueClass
|
146
|
+
max = guess_obj_max(obj)
|
147
|
+
Log::ProgressBar.new_bar(max)
|
148
|
+
when Numeric
|
149
|
+
max = guess_obj_max(obj)
|
150
|
+
Log::ProgressBar.new_bar(bar)
|
151
|
+
when Hash
|
152
|
+
max = IndiferentHash.process_options(bar, :max) || max
|
153
|
+
Log::ProgressBar.new_bar(max, bar)
|
154
|
+
when Log::ProgressBar
|
155
|
+
bar.max ||= guess_obj_max(obj)
|
159
156
|
bar
|
157
|
+
else
|
158
|
+
if (defined? Step and Step === bar)
|
159
|
+
max = guess_obj_max(obj)
|
160
|
+
Log::ProgressBar.new_bar(max, {:desc => bar.status, :file => bar.file(:progress)})
|
161
|
+
else
|
162
|
+
bar
|
163
|
+
end
|
160
164
|
end
|
161
165
|
end
|
162
|
-
end
|
163
|
-
end
|
164
166
|
|
167
|
+
def self.with_obj_bar(obj, bar = true, &block)
|
168
|
+
bar = get_obj_bar(obj, bar)
|
169
|
+
with_bar nil, bar: bar, &block
|
170
|
+
end
|
171
|
+
end
|
165
172
|
end
|
166
173
|
|
data/lib/scout/log/progress.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
module Log
|
2
|
+
def self.trap_std(msg = "STDOUT", msge = "STDERR", severity = 0, severity_err = nil)
|
3
|
+
sout, sin = Open.pipe
|
4
|
+
soute, sine = Open.pipe
|
5
|
+
backup_stderr = STDERR.dup
|
6
|
+
backup_stdout = STDOUT.dup
|
7
|
+
old_logfile = Log.logfile
|
8
|
+
Log.logfile(backup_stderr)
|
9
|
+
|
10
|
+
severity_err ||= severity
|
11
|
+
th_log = Thread.new do
|
12
|
+
while line = sout.gets
|
13
|
+
Log.logn "#{msg}: " + line, severity
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
th_loge = Thread.new do
|
18
|
+
while line = soute.gets
|
19
|
+
Log.logn "#{msge}: " + line, severity_err
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
STDOUT.reopen(sin)
|
25
|
+
STDERR.reopen(sine)
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
STDERR.reopen backup_stderr
|
29
|
+
STDOUT.reopen backup_stdout
|
30
|
+
sin.close
|
31
|
+
sine.close
|
32
|
+
th_log.join
|
33
|
+
th_loge.join
|
34
|
+
backup_stdout.close
|
35
|
+
backup_stderr.close
|
36
|
+
Log.logfile = old_logfile
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.trap_stderr(msg = "STDERR", severity = 0)
|
41
|
+
sout, sin = Open.pipe
|
42
|
+
backup_stderr = STDERR.dup
|
43
|
+
old_logfile = Log.logfile
|
44
|
+
Log.logfile(backup_stderr)
|
45
|
+
|
46
|
+
th_log = Thread.new do
|
47
|
+
while line = sout.gets
|
48
|
+
Log.logn "#{msg}: " + line, severity
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
begin
|
53
|
+
STDERR.reopen(sin)
|
54
|
+
yield
|
55
|
+
sin.close
|
56
|
+
ensure
|
57
|
+
STDERR.reopen backup_stderr
|
58
|
+
th_log.join
|
59
|
+
backup_stderr.close
|
60
|
+
Log.logfile = old_logfile
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self._ignore_stderr
|
65
|
+
begin
|
66
|
+
File.open('/dev/null', 'w') do |f|
|
67
|
+
backup_stderr = STDERR.dup
|
68
|
+
STDERR.reopen(f)
|
69
|
+
begin
|
70
|
+
yield
|
71
|
+
ensure
|
72
|
+
STDERR.reopen backup_stderr
|
73
|
+
backup_stderr.close
|
74
|
+
end
|
75
|
+
end
|
76
|
+
rescue Errno::ENOENT
|
77
|
+
yield
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def self.ignore_stderr(&block)
|
83
|
+
_ignore_stderr &block
|
84
|
+
end
|
85
|
+
|
86
|
+
def self._ignore_stdout
|
87
|
+
begin
|
88
|
+
File.open('/dev/null', 'w') do |f|
|
89
|
+
backup_stdout = STDOUT.dup
|
90
|
+
STDOUT.reopen(f)
|
91
|
+
begin
|
92
|
+
yield
|
93
|
+
ensure
|
94
|
+
STDOUT.reopen backup_stdout
|
95
|
+
backup_stdout.close
|
96
|
+
end
|
97
|
+
end
|
98
|
+
rescue Errno::ENOENT
|
99
|
+
yield
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
def self.ignore_stdout(&block)
|
105
|
+
_ignore_stdout &block
|
106
|
+
end
|
107
|
+
end
|
data/lib/scout/log.rb
CHANGED
@@ -1,42 +1,76 @@
|
|
1
1
|
require_relative 'log/color'
|
2
2
|
require_relative 'log/fingerprint'
|
3
3
|
require_relative 'log/progress'
|
4
|
+
require_relative 'log/trap'
|
4
5
|
|
5
6
|
require 'io/console'
|
6
7
|
|
7
8
|
module Log
|
9
|
+
class << self
|
10
|
+
attr_accessor :severity
|
11
|
+
attr_writer :tty_size, :logfile
|
12
|
+
end
|
13
|
+
|
8
14
|
SEVERITY_NAMES ||= begin
|
9
|
-
names = %w(DEBUG LOW MEDIUM HIGH INFO WARN ERROR NONE )
|
15
|
+
names = %w(DEBUG LOW MEDIUM HIGH INFO WARN ERROR NONE )
|
10
16
|
names.each_with_index do |name,i|
|
11
|
-
eval "#{ name } = #{ i }"
|
17
|
+
eval "#{ name } = #{ i }"
|
12
18
|
end
|
13
19
|
names
|
14
20
|
end
|
21
|
+
def self.default_severity
|
22
|
+
@@default_severity ||= begin
|
23
|
+
file = File.join(ENV["HOME"], '.scout/etc/log_severity')
|
24
|
+
if File.exist? file
|
25
|
+
File.open(file) do |f|
|
26
|
+
SEVERITY_NAMES.index f.read.strip
|
27
|
+
end
|
28
|
+
else
|
29
|
+
INFO
|
30
|
+
end
|
31
|
+
end
|
32
|
+
@@default_severity
|
33
|
+
end
|
15
34
|
|
16
|
-
|
17
|
-
|
18
|
-
|
35
|
+
case ENV['SCOUT_LOG']
|
36
|
+
when 'DEBUG'
|
37
|
+
self.severity = DEBUG
|
38
|
+
when 'LOW'
|
39
|
+
self.severity = LOW
|
40
|
+
when 'MEDIUM'
|
41
|
+
self.severity = MEDIUM
|
42
|
+
when 'HIGH'
|
43
|
+
self.severity = HIGH
|
44
|
+
when nil
|
45
|
+
self.severity = default_severity
|
46
|
+
else
|
47
|
+
self.severity = default_severity
|
19
48
|
end
|
20
49
|
|
21
50
|
|
51
|
+
|
22
52
|
def self.tty_size
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
53
|
+
@@tty_size ||= Log.ignore_stderr do
|
54
|
+
begin
|
55
|
+
IO.console.winsize.last
|
56
|
+
rescue Exception
|
57
|
+
begin
|
58
|
+
res = `tput li`
|
59
|
+
res = nil if res == ""
|
60
|
+
res || ENV["TTY_SIZE"] || 80
|
61
|
+
rescue Exception
|
62
|
+
ENV["TTY_SIZE"] || 80
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
32
66
|
end
|
33
67
|
|
34
68
|
|
35
69
|
def self.last_caller(stack)
|
36
70
|
line = nil
|
37
71
|
pos ||= 0
|
38
|
-
while line.nil? or line =~ /scout\/log\.rb/ and stack.any?
|
39
|
-
line = stack.shift
|
72
|
+
while line.nil? or line =~ /scout\/log\.rb/ and stack.any?
|
73
|
+
line = stack.shift
|
40
74
|
end
|
41
75
|
line ||= caller.first
|
42
76
|
line.gsub('`', "'")
|
@@ -99,9 +133,36 @@ module Log
|
|
99
133
|
out.puts Log.return_line << " " * (Log.tty_size || 80) << Log.return_line unless nocolor
|
100
134
|
end
|
101
135
|
|
136
|
+
MUTEX = Mutex.new
|
137
|
+
def self.log_write(str)
|
138
|
+
MUTEX.synchronize do
|
139
|
+
if logfile.nil?
|
140
|
+
begin
|
141
|
+
STDERR.write str
|
142
|
+
rescue
|
143
|
+
end
|
144
|
+
else
|
145
|
+
logfile.write str
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.log_puts(str)
|
151
|
+
MUTEX.synchronize do
|
152
|
+
if logfile.nil?
|
153
|
+
begin
|
154
|
+
STDERR.puts str
|
155
|
+
rescue
|
156
|
+
end
|
157
|
+
else
|
158
|
+
logfile.puts str
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
102
163
|
LAST = "log"
|
103
164
|
def self.logn(message = nil, severity = MEDIUM, &block)
|
104
|
-
return if severity < self.severity
|
165
|
+
return if severity < self.severity
|
105
166
|
message ||= block.call if block_given?
|
106
167
|
return if message.nil?
|
107
168
|
|
@@ -109,21 +170,22 @@ module Log
|
|
109
170
|
|
110
171
|
sev_str = severity.to_s
|
111
172
|
|
112
|
-
|
173
|
+
if ENV["SCOUT_DEBUG_PID"] == "true"
|
174
|
+
prefix = time << "[" << Process.pid.to_s << "]" << color(severity) << "[" << sev_str << "]" << color(0)
|
175
|
+
else
|
176
|
+
prefix = time << color(severity) << "[" << sev_str << "]" << color(0)
|
177
|
+
end
|
113
178
|
message = "" << highlight << message << color(0) if severity >= INFO
|
114
179
|
str = prefix << " " << message.to_s
|
115
180
|
|
116
|
-
|
117
|
-
|
118
|
-
else
|
119
|
-
logfile.write str
|
120
|
-
end
|
181
|
+
log_write str
|
182
|
+
|
121
183
|
Log::LAST.replace "log"
|
122
184
|
nil
|
123
185
|
end
|
124
186
|
|
125
187
|
def self.log(message = nil, severity = MEDIUM, &block)
|
126
|
-
return if severity < self.severity
|
188
|
+
return if severity < self.severity
|
127
189
|
message ||= block.call if block_given?
|
128
190
|
return if message.nil?
|
129
191
|
message = message + "\n" unless message[-1] == "\n"
|
@@ -187,7 +249,7 @@ module Log
|
|
187
249
|
def self.exception(e)
|
188
250
|
stack = caller
|
189
251
|
backtrace = e.backtrace || []
|
190
|
-
if ENV["
|
252
|
+
if ENV["SCOUT_ORIGINAL_STACK"] == 'true'
|
191
253
|
error([e.class.to_s, e.message].compact * ": " )
|
192
254
|
error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(backtrace)*"\n")
|
193
255
|
else
|
@@ -216,9 +278,9 @@ module Log
|
|
216
278
|
end
|
217
279
|
|
218
280
|
def self.tsv(tsv, example = false)
|
219
|
-
|
220
|
-
|
221
|
-
|
281
|
+
log_puts Log.color :magenta, "TSV log: " << Log.last_caller(caller).gsub('`',"'")
|
282
|
+
log_puts Log.color(:blue, "=> "<< Log.fingerprint(tsv), true)
|
283
|
+
log_puts Log.color(:cyan, "=> " << tsv.summary)
|
222
284
|
if example && ! tsv.empty?
|
223
285
|
key = case example
|
224
286
|
when TrueClass, :first, "first"
|
@@ -232,26 +294,26 @@ module Log
|
|
232
294
|
values = tsv[key]
|
233
295
|
values = [values] if tsv.type == :flat || tsv.type == :single
|
234
296
|
if values.nil?
|
235
|
-
|
297
|
+
log_puts Log.color(:blue, "Key (#{tsv.key_field}) not present: ") + key
|
236
298
|
else
|
237
|
-
|
299
|
+
log_puts Log.color(:blue, "Key (#{tsv.key_field}): ") + key
|
238
300
|
tsv.fields.zip(values).each do |field,value|
|
239
|
-
|
301
|
+
log_puts Log.color(:magenta, field + ": ") + (Array === value ? value * ", " : value.to_s)
|
240
302
|
end
|
241
303
|
end
|
242
304
|
end
|
243
305
|
end
|
244
306
|
|
245
307
|
def self.stack(stack)
|
246
|
-
if ENV["
|
247
|
-
|
308
|
+
if ENV["SCOUT_ORIGINAL_STACK"] == 'true'
|
309
|
+
log_puts Log.color :magenta, "Stack trace [#{Process.pid}]: " << Log.last_caller(caller)
|
248
310
|
color_stack(stack).each do |line|
|
249
|
-
|
311
|
+
log_puts line
|
250
312
|
end
|
251
313
|
else
|
252
|
-
|
314
|
+
log_puts Log.color :magenta, "Stack trace [#{Process.pid}]: " << Log.last_caller(caller)
|
253
315
|
color_stack(stack.reverse).each do |line|
|
254
|
-
|
316
|
+
log_puts line
|
255
317
|
end
|
256
318
|
end
|
257
319
|
end
|
@@ -259,7 +321,7 @@ module Log
|
|
259
321
|
def self.count_stack
|
260
322
|
if ! $count_stacks
|
261
323
|
Log.debug "Counting stacks at: " << caller.first
|
262
|
-
return
|
324
|
+
return
|
263
325
|
end
|
264
326
|
$stack_counts ||= {}
|
265
327
|
head = $count_stacks_head
|
@@ -280,21 +342,6 @@ module Log
|
|
280
342
|
$stack_counts = {}
|
281
343
|
res
|
282
344
|
end
|
283
|
-
|
284
|
-
case ENV['RBBT_LOG']
|
285
|
-
when 'DEBUG'
|
286
|
-
self.severity = DEBUG
|
287
|
-
when 'LOW'
|
288
|
-
self.severity = LOW
|
289
|
-
when 'MEDIUM'
|
290
|
-
self.severity = MEDIUM
|
291
|
-
when 'HIGH'
|
292
|
-
self.severity = HIGH
|
293
|
-
when nil
|
294
|
-
self.severity = INFO
|
295
|
-
else
|
296
|
-
self.severity = ENV['RBBT_LOG'].to_i
|
297
|
-
end
|
298
345
|
end
|
299
346
|
|
300
347
|
def ppp(message)
|
@@ -373,3 +420,19 @@ def sss(level, &block)
|
|
373
420
|
end
|
374
421
|
end
|
375
422
|
|
423
|
+
$scout_debug_log = false
|
424
|
+
def ccc(obj=nil, file = $stdout)
|
425
|
+
if block_given?
|
426
|
+
old_scout_debug_log = $scout_debug_log
|
427
|
+
$scout_debug_log = 'true'
|
428
|
+
begin
|
429
|
+
yield
|
430
|
+
ensure
|
431
|
+
$scout_debug_log = old_scout_debug_log
|
432
|
+
end
|
433
|
+
else
|
434
|
+
Log.log_obj_inspect(obj, :info, file) if $scout_debug_log
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
|