Class: NRSER::Logger

Inherits:
Object
  • Object
show all
Defined in:
lib/nrser/logger.rb

Overview

TODO:

doc class

Constant Summary collapse

LEVEL_SYMS =

symbols for the level names

[
  :debug,
  :info,
  :warn,
  :error,
  :fatal,
  :unknown,
]
LOGGING_METHODS =
LEVEL_SYMS - [:unknown] + [:die]
SEVERITY_COLORS =
{
  'DEBUG' => :bright_black,
  'WARN' => :yellow,
  'INFO' => :green,
  'ERROR' => :red,
  'FATAL' => :on_red,
}
@@pastel =
Pastel, false

if pastel is present, this will be an instance of

‘Pastel` otherwise, it will be false

begin
  require 'pastel'
  Pastel.new
rescue LoadError => e
  false
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Logger

Returns a new instance of Logger.



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/nrser/logger.rb', line 288

def initialize options = {}
  options = {
    dest: $stderr,
    level: :info,
    say_hi: true,
    on: true,
  }.merge options

  @name = options[:name]
  @on = options[:on]
  @level = self.class.level_int options[:level]
  self.dest = options[:dest]

  if @on && options[:say_hi]
    info <<-END.squish
      started to logging to #{ @dest } at level
      #{ self.class.level_name @level }...
    END
  end
end

Instance Attribute Details

#destObject

.use



286
287
288
# File 'lib/nrser/logger.rb', line 286

def dest
  @dest
end

#levelObject

.use



286
287
288
# File 'lib/nrser/logger.rb', line 286

def level
  @level
end

#nameObject (readonly)

.use



286
287
288
# File 'lib/nrser/logger.rb', line 286

def name
  @name
end

#ruby_loggerObject (readonly)

.use



286
287
288
# File 'lib/nrser/logger.rb', line 286

def ruby_logger
  @ruby_logger
end

Class Method Details

.check_level(level) ⇒ Object



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

def self.check_level level
  case level
  when Fixnum
    unless level >= 0 && level < LEVEL_SYMS.length
      raise ArgumentError.new "invalid integer level: #{ level.inspect }"
    end
  when Symbol
    unless LEVEL_SYMS.include? level
      raise ArgumentError.new "invalid level symbol: #{ level.inspect }"
    end
  when String
    unless LEVEL_SYMS.map {|_| _.to_s.upcase}.include? level
      raise ArgumentError.new "invalid level name: #{ level.inspect }"
    end
  else
    raise TypeError.new binding.erb <<-END
      level must be Fixnum, Symbol or String, not <%= level.inspect %>
    END
  end
end

.dump_value(value) ⇒ Object

prev: def self.format msg, dump = {}

unless dump.empty?
  msg += "\n" + dump.map {|k, v| "  #{ k }: #{ v.inspect }" }.join("\n")
end
msg

end



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/nrser/logger.rb', line 86

def self.dump_value value
  case value
  when String, Fixnum, Float, TrueClass, FalseClass
    value
  when Array
    value.map {|v| dump_value v}
  when Hash
    Hash[value.map {|k, v| [k.to_s, dump_value(v)]}]
  else
    value.pretty_inspect
  end
end

.format(name, level, msg, dump = {}) ⇒ Object

pure

format a debug message with optional key / values to print

Parameters:

  • name (String)

    logger name.

  • level (String, Symbol, Fixnum)

    the level in string, symbol or integer form.

  • msg (String)

    message to print.

  • dump (Hash) (defaults to: {})

    optional hash of keys and vaues to dump.



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/nrser/logger.rb', line 67

def self.format name, level, msg, dump = {}
  data = {
    'logger' => name,
    'time' => Time.now,
  }
  
  data['msg'] = msg unless msg.empty?
  data['values'] = dump_value(dump) unless dump.empty?
  
  YAML.dump level_name(level) => data
end

.install(target, options = {}) ⇒ NRSER::Logger

creates a new ‘NRSER::Logger` and ’installs’ a logger on target, adding singleton (class) and instance methods as appropriate

Parameters:

  • target (Object)

    the object to install a new logger on, which can be a Module, a Class, or just any plain-old instance that you want to have it’s own logger client.

  • options (Hash) (defaults to: {})

    options used when creating the ‘NRSER::Logger`.

Returns:

See Also:



257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/nrser/logger.rb', line 257

def self.install target, options = {}
  options[:on] ||= false
  options[:name] ||= if target.respond_to?(:name) && !target.name.nil?
    target.name
  else
    target.to_s
  end
  
  logger = self.new options
  install_methods! target, logger
  
  logger
end

.install_methods!(target, logger) ⇒ Object

pure

creates methods closed around a ‘NRSER::Logger` instance to be attached to objects to access the logger and do logging and ’installs’ them on the target.

Parameters:

  • target (Object)

    object to install methods on.

  • logger (NRSER::Logger)

    the logger to bind the methods to.

Returns:

  • nil



206
207
208
209
210
211
212
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
239
240
241
242
# File 'lib/nrser/logger.rb', line 206

def self.install_methods! target, logger
  methods = {
    logger: {
      private: false,
      body: ->() { logger },
    },
  }
  
  LOGGING_METHODS.each do |sym|
    methods[sym] = {
      private: true,
      body: ->(*args, &block) { logger.send sym, *args, &block },
    }
  end
  
  if target.is_a? Class
    methods.each do |sym, stuff|
      target.define_singleton_method sym, &stuff[:body]
      target.send :define_method, sym, &stuff[:body]
      target.send :private, sym if stuff[:private]
    end
    
  elsif target.is_a? Module
    methods.each do |sym, stuff|
      target.define_singleton_method sym, &stuff[:body]
      target.private_class_method sym if stuff[:private]
    end
    
  else
    methods.each do |sym, stuff|
      target.send :define_method, sym, &stuff[:body]
      target.send :private, sym if stuff[:private]
    end
  end
  
  nil
end

.level_int(level) ⇒ Fixnum

pure

get the integer value of a level (like ::Logger::DEBUG, etc.).

Parameters:

  • level (Fixnum, Symbol, String)

    the integer level, method symbol, or string name (all caps).

Returns:

  • (Fixnum)

    level integer (between 0 and 5 inclusive).



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/nrser/logger.rb', line 133

def self.level_int level
  check_level level
  case level
  when Fixnum
    level
  when Symbol
    LEVEL_SYMS.each_with_index {|sym, index|
      return index if level == sym
    }
  when String
    LEVEL_SYMS.each_with_index {|sym, index|
      return index if level == sym.to_s.upcase
    }
  end
end

.level_name(level) ⇒ 'DEBUG', ...

pure

get the string “name” of a level (‘DEBUG’, ‘INFO’, etc.).

Parameters:

  • level (Fixnum, Symbol, String)

    the integer level, method symbol, or string name (all caps).

Returns:

  • ('DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN')


159
160
161
162
163
164
165
166
167
168
169
# File 'lib/nrser/logger.rb', line 159

def self.level_name level
  check_level level
  case level
  when Fixnum
    LEVEL_SYMS[level].to_s.upcase
  when Symbol
    level.to_s.upcase
  when String
    level
  end
end

.level_sym(level) ⇒ :debug, ...

pure

get the symbol for a level as used in method sigs.

Parameters:

  • level (Fixnum, Symbol, String)

    the integer level, method symbol, or string name (all caps).

Returns:

  • (:debug, :info, :warn, :error, :fatal, :unknown)


181
182
183
184
185
186
187
188
189
190
191
# File 'lib/nrser/logger.rb', line 181

def self.level_sym level
  check_level level
  case level
  when Fixnum
    LEVEL_SYMS[level]
  when Symbol
    level
  when String
    level.downcase.to_sym
  end
end

.use(source, target) ⇒ NRSER::Logger

singleton (class) and instance methods as appropriate

Parameters:

  • source (Object)

    source instance with a logger installed to use for the target.

  • target (Object)

    the object to use the source’s logger.

Returns:



282
283
284
# File 'lib/nrser/logger.rb', line 282

def self.use source, target
  install_methods! target, source.logger
end

Instance Method Details

#debug(*args, &block) ⇒ Object



372
373
374
# File 'lib/nrser/logger.rb', line 372

def debug *args, &block
  send_log :debug, args, block
end

#die(*args, &block) ⇒ Object



397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/nrser/logger.rb', line 397

def die *args, &block
  if @on
    send_log :fatal, args, block
    abort
  else
    abort self.class.format(
      @name,
      :fatal,
      *extract_msg_and_dump(args, block)
    )
  end
end

#error(*args, &block) ⇒ Object



387
388
389
# File 'lib/nrser/logger.rb', line 387

def error *args, &block
  send_log :error, args, block
end

#fatal(*args, &block) ⇒ Object



392
393
394
# File 'lib/nrser/logger.rb', line 392

def fatal *args, &block
  send_log :fatal, args, block
end

#info(*args, &block) ⇒ Object



377
378
379
# File 'lib/nrser/logger.rb', line 377

def info *args, &block
  send_log :info, args, block
end

#off(&block) ⇒ Object



328
329
330
331
332
333
334
335
336
337
# File 'lib/nrser/logger.rb', line 328

def off &block
  if block
    prev = @on
    @on = false
    block.call
    @on = prev
  else
    @on = false
  end
end

#off?Boolean

Returns:

  • (Boolean)


313
314
315
# File 'lib/nrser/logger.rb', line 313

def off?
  !on?
end

#on(&block) ⇒ Object



317
318
319
320
321
322
323
324
325
326
# File 'lib/nrser/logger.rb', line 317

def on &block
  if block
    prev = @on
    @on = true
    block.call
    @on = prev
  else
    @on = true
  end
end

#on?Boolean

Returns:

  • (Boolean)


309
310
311
# File 'lib/nrser/logger.rb', line 309

def on?
  @on
end

#warn(*args, &block) ⇒ Object



382
383
384
# File 'lib/nrser/logger.rb', line 382

def warn *args, &block
  send_log :warn, args, block
end

#with_level(level, &block) ⇒ Object



347
348
349
350
351
352
# File 'lib/nrser/logger.rb', line 347

def with_level level, &block
  prev_level = self.level
  self.level = level
  block.call
  self.level = prev_level
end