Module: Log

Extended by:
Term::ANSIColor
Defined in:
lib/scout/log.rb,
lib/scout/log/color.rb,
lib/scout/log/progress.rb,
lib/scout/log/fingerprint.rb,
lib/scout/log/progress/util.rb,
lib/scout/log/progress/report.rb

Defined Under Namespace

Classes: ProgressBar

Constant Summary collapse

LAST =
"log"
SEVERITY_COLOR =

.collect{|e| “033[#{e}”}

[reset, cyan, green, magenta, blue, yellow, red]
HIGHLIGHT =
"\033[1m"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.logfile(file = nil) ⇒ Object

Returns the value of attribute logfile.



17
18
19
# File 'lib/scout/log.rb', line 17

def logfile
  @logfile
end

.nocolorObject

Returns the value of attribute nocolor.



129
130
131
# File 'lib/scout/log/color.rb', line 129

def nocolor
  @nocolor
end

.severityObject

Returns the value of attribute severity.



17
18
19
# File 'lib/scout/log.rb', line 17

def severity
  @severity
end

.tty_sizeObject



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/scout/log.rb', line 22

def self.tty_size
  @tty_size = begin
                IO.console.winsize.last
              rescue
                begin
                  `tput li`
                rescue
                  80
                end
              end
end

Class Method Details

.clear_line(out = STDOUT) ⇒ Object



98
99
100
# File 'lib/scout/log.rb', line 98

def self.clear_line(out = STDOUT)
  out.puts Log.return_line << " " * (Log.tty_size || 80) << Log.return_line unless nocolor
end

.color(severity, str = nil, reset = false) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/scout/log/color.rb', line 147

def self.color(severity, str = nil, reset = false)
  return str.dup || "" if nocolor 
  color = reset ? Term::ANSIColor.reset : ""
  color << SEVERITY_COLOR[severity] if Integer === severity
  color << Term::ANSIColor.send(severity) if Symbol === severity and Term::ANSIColor.respond_to? severity 
  if str.nil?
    color
  else
    color + str.to_s + self.color(0)
  end
end

.color_stack(stack) ⇒ Object



204
205
206
207
208
209
210
211
# File 'lib/scout/log.rb', line 204

def self.color_stack(stack)
  stack.collect do |line|
    line = line.sub('`',"'")
    color = :green if line =~ /workflow/
    color = :blue if line =~ /scout-/
    Log.color color, line
  end unless stack.nil?
end

.count_stackObject



254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/scout/log.rb', line 254

def self.count_stack
  if ! $count_stacks
    Log.debug "Counting stacks at: " << caller.first
    return 
  end
  $stack_counts ||= {}
  head = $count_stacks_head
  stack = caller[1..head+1]
  stack.reverse.each do |line,i|
    $stack_counts[line] ||= 0
    $stack_counts[line] += 1
  end
end

.debug(message = nil, &block) ⇒ Object



159
160
161
# File 'lib/scout/log.rb', line 159

def self.debug(message = nil, &block)
  log(message, DEBUG, &block)
end

.deprecated(m) ⇒ Object



198
199
200
201
202
# File 'lib/scout/log.rb', line 198

def self.deprecated(m)
  stack = caller
  warn("DEPRECATED: " << Log.last_caller(stack))
  warn("* " << (m || "").to_s)
end

.down_lines(num = 1) ⇒ Object



90
91
92
# File 'lib/scout/log.rb', line 90

def self.down_lines(num = 1)
  nocolor ? "" : "\033[#{num+1}E"
end

.error(message = nil, &block) ⇒ Object



183
184
185
# File 'lib/scout/log.rb', line 183

def self.error(message = nil, &block)
  log(message, ERROR, &block)
end

.exception(e) ⇒ Object



187
188
189
190
191
192
193
194
195
196
# File 'lib/scout/log.rb', line 187

def self.exception(e)
  stack = caller
  if ENV["RBBT_ORIGINAL_STACK"] == 'true'
    error([e.class.to_s, e.message].compact * ": " )
    error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(e.backtrace)*"\n")
  else
    error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(e.backtrace.reverse)*"\n")
    error([e.class.to_s, e.message].compact * ": " )
  end
end

.fingerprint(obj) ⇒ Object



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
# File 'lib/scout/log/fingerprint.rb', line 3

def self.fingerprint(obj)
  return obj.fingerprint if obj.respond_to?(:fingerprint)

  case obj
  when nil
    "nil"
  when TrueClass
    "true"
  when FalseClass
    "false"
  when Symbol
    ":" << obj.to_s
  when String
    if obj.length > 100
      digest = Digest::MD5.hexdigest(obj)
      "'" << obj.slice(0,30) << "<...#{obj.length} - #{digest[0..4]}...>" << obj.slice(-10,30)<< "'"
    else 
      "'" << obj << "'"
    end
  when IO
    (obj.respond_to?(:filename) and obj.filename ) ? "<IO:" + (obj.filename || obj.inspect + rand(100000)) + ">" : obj.inspect
  when File
    "<File:" + obj.path + ">"
  when Array
    if (length = obj.length) > 10
      "[#{length}--" <<  (obj.values_at(0,1, length / 2, -2, -1).collect{|e| fingerprint(e)} * ",") << "]"
    else
      "[" << (obj.collect{|e| fingerprint(e) } * ", ") << "]"
    end
  when Hash
    if obj.length > 10
      "H:{"<< fingerprint(obj.keys) << ";" << fingerprint(obj.values) << "}"
    else
      new = "{"
      obj.each do |k,v|
        new << fingerprint(k) << '=>' << fingerprint(v) << ' '
      end
      if new.length > 1
         new[-1] =  "}"
      else
        new << '}'
      end
      new
    end
  when Float
    if obj.abs > 10
      "%.1f" % obj
    elsif obj.abs > 1
      "%.3f" % obj
    else
      "%.6f" % obj
    end
  else
    obj.to_s
  end
end

.get_level(level) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/scout/log.rb', line 45

def self.get_level(level)
  case level
  when Numeric
    level.to_i
  when String
    begin
      Log.const_get(level.upcase)
    rescue
      Log.exception $!
    end
  when Symbol
    get_level(level.to_s)
  end || 0
end

.high(message = nil, &block) ⇒ Object



171
172
173
# File 'lib/scout/log.rb', line 171

def self.high(message = nil, &block)
  log(message, HIGH, &block)
end

.highlight(str = nil) ⇒ Object



159
160
161
162
163
164
165
166
167
# File 'lib/scout/log/color.rb', line 159

def self.highlight(str = nil)
  if str.nil?
    return "" if nocolor
    HIGHLIGHT
  else
    return str if nocolor
    HIGHLIGHT + str + color(0)
  end
end

.info(message = nil, &block) ⇒ Object



175
176
177
# File 'lib/scout/log.rb', line 175

def self.info(message = nil, &block)
  log(message, INFO, &block)
end

.last_caller(stack) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/scout/log.rb', line 35

def self.last_caller(stack)
  line = nil
  pos ||= 0
  while line.nil? or line =~ /scout\/log\.rb/ and stack.any? 
    line = stack.shift 
  end
  line ||= caller.first
  line.gsub('`', "'")
end

.log(message = nil, severity = MEDIUM, &block) ⇒ Object



125
126
127
128
129
130
131
# File 'lib/scout/log.rb', line 125

def self.log(message = nil, severity = MEDIUM, &block)
  return if severity < self.severity 
  message ||= block.call if block_given?
  return if message.nil?
  message = message + "\n" unless message[-1] == "\n"
  self.logn message, severity, &block
end

.log_obj_fingerprint(obj, level, file = $stdout) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/scout/log.rb', line 146

def self.log_obj_fingerprint(obj, level, file = $stdout)
  stack = caller

  line = Log.last_caller stack

  level = Log.get_level level
  name = Log::SEVERITY_NAMES[level] + ": "
  Log.log Log.color(level, name, true) << line, level
  Log.log "", level
  Log.log Log.color(level, "=> ", true) << Log.fingerprint(obj), level
  Log.log "", level
end

.log_obj_inspect(obj, level, file = $stdout) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/scout/log.rb', line 133

def self.log_obj_inspect(obj, level, file = $stdout)
  stack = caller

  line = Log.last_caller stack

  level = Log.get_level level
  name = Log::SEVERITY_NAMES[level] + ": "
  Log.log Log.color(level, name, true) << line, level
  Log.log "", level
  Log.log Log.color(level, "=> ", true) << obj.inspect, level
  Log.log "", level
end

.logn(message = nil, severity = MEDIUM, &block) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/scout/log.rb', line 103

def self.logn(message = nil, severity = MEDIUM, &block)
  return if severity < self.severity 
  message ||= block.call if block_given?
  return if message.nil?

  time = Time.now.strftime("%m/%d/%y-%H:%M:%S.%L")

  sev_str = severity.to_s

  prefix = time << color(severity) << "["  << sev_str << "]" << color(0)
  message = "" << highlight << message << color(0) if severity >= INFO
  str = prefix << " " << message.to_s

  if logfile.nil?
    STDERR.write str
  else
    logfile.write str 
  end
  Log::LAST.replace "log"
  nil
end

.low(message = nil, &block) ⇒ Object



163
164
165
# File 'lib/scout/log.rb', line 163

def self.low(message = nil, &block)
  log(message, LOW, &block)
end

.medium(message = nil, &block) ⇒ Object



167
168
169
# File 'lib/scout/log.rb', line 167

def self.medium(message = nil, &block)
  log(message, MEDIUM, &block)
end

.no_barObject



9
10
11
12
# File 'lib/scout/log/progress.rb', line 9

def self.no_bar
  @@no_bar = false unless defined?(@@no_bar)
  @@no_bar || ENV["RBBT_NO_PROGRESS"] == "true"
end

.no_bar=(value) ⇒ Object



5
6
7
# File 'lib/scout/log/progress.rb', line 5

def self.no_bar=(value)
  @@no_bar = value
end

.reset_colorObject



143
144
145
# File 'lib/scout/log/color.rb', line 143

def self.reset_color
  reset
end

.return_lineObject



94
95
96
# File 'lib/scout/log.rb', line 94

def self.return_line
  nocolor ? "" : "\033[1A"
end

.stack(stack) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/scout/log.rb', line 240

def self.stack(stack)
  if ENV["RBBT_ORIGINAL_STACK"] == 'true'
    STDERR.puts Log.color :magenta, "Stack trace [#{Process.pid}]: " << Log.last_caller(caller)
    color_stack(stack).each do |line|
      STDERR.puts line
    end
  else
    STDERR.puts Log.color :magenta, "Stack trace [#{Process.pid}]: " << Log.last_caller(caller)
    color_stack(stack.reverse).each do |line|
      STDERR.puts line
    end
  end
end

.tsv(tsv, example = false) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/scout/log.rb', line 213

def self.tsv(tsv, example = false)
  STDERR.puts Log.color :magenta, "TSV log: " << Log.last_caller(caller).gsub('`',"'")
  STDERR.puts Log.color(:blue, "=> "<< Log.fingerprint(tsv), true) 
  STDERR.puts Log.color(:cyan, "=> " << tsv.summary)
  if example && ! tsv.empty?
    key = case example
          when TrueClass, :first, "first"
            tsv.keys.first
          when :random, "random"
            tsv.keys.shuffle.first
          else
            example
          end

    values = tsv[key]
    values = [values] if tsv.type == :flat || tsv.type == :single
    if values.nil?
      STDERR.puts Log.color(:blue, "Key (#{tsv.key_field}) not present: ") + key
    else
      STDERR.puts Log.color(:blue, "Key (#{tsv.key_field}): ") + key
      tsv.fields.zip(values).each do |field,value|
        STDERR.puts Log.color(:magenta, field + ": ") + (Array === value ? value * ", " : value.to_s)
      end
    end
  end
end

.uncolor(str) ⇒ Object



139
140
141
# File 'lib/scout/log/color.rb', line 139

def self.uncolor(str)
  "" << Term::ANSIColor.uncolor(str)
end

.up_lines(num = 1) ⇒ Object



86
87
88
# File 'lib/scout/log.rb', line 86

def self.up_lines(num = 1)
  nocolor ? "" : "\033[#{num+1}F\033[2K"
end

.warn(message = nil, &block) ⇒ Object



179
180
181
# File 'lib/scout/log.rb', line 179

def self.warn(message = nil, &block)
  log(message, WARN, &block)
end

.with_severity(level) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/scout/log.rb', line 60

def self.with_severity(level)
  orig = Log.severity
  begin
    Log.severity = level
    yield
  ensure
    Log.severity = orig
  end
end

.with_stack_counts(head = 10, total = 100) ⇒ Object



268
269
270
271
272
273
274
275
276
277
# File 'lib/scout/log.rb', line 268

def self.with_stack_counts(head = 10, total = 100)
  $count_stacks_head = head
  $count_stacks = true
  $stack_counts = {}
  res = yield
  $count_stacks = false
  Log.debug "STACK_COUNTS:\n" + $stack_counts.sort_by{|line,c| c}.reverse.collect{|line,c| [c, line] * " - "}[0..total] * "\n"
  $stack_counts = {}
  res
end