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.



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

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



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

def dest
  @dest
end

#levelObject

.use



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

def level
  @level
end

#nameObject (readonly)

.use



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

def name
  @name
end

#ruby_loggerObject (readonly)

.use



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

def ruby_logger
  @ruby_logger
end

Class Method Details

.check_level(level) ⇒ Object



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

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



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

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.



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

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:



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

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



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
243
# File 'lib/nrser/logger.rb', line 207

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).



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

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')


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

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)


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

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:



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

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

Instance Method Details

#debug(*args, &block) ⇒ Object



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

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

#die(*args, &block) ⇒ Object



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

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



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

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

#fatal(*args, &block) ⇒ Object



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

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

#info(*args, &block) ⇒ Object



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

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

#off(&block) ⇒ Object



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

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

#off?Boolean

Returns:

  • (Boolean)


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

def off?
  !on?
end

#on(&block) ⇒ Object



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

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

#on?Boolean

Returns:

  • (Boolean)


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

def on?
  @on
end

#warn(*args, &block) ⇒ Object



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

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

#with_level(level, &block) ⇒ Object



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

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