Class: SemanticLogger::Logger

Inherits:
Base
  • Object
show all
Includes:
Concerns::Compatibility
Defined in:
lib/semantic_logger/logger.rb

Overview

Logger stores the class name to be used for all log messages so that every log message written by this instance will include the class name

Direct Known Subclasses

DebugAsTraceLogger

Constant Summary collapse

@@lag_check_interval =
5000
@@lag_threshold_s =
30

Instance Attribute Summary

Attributes inherited from Base

#filter, #name

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Concerns::Compatibility

#add, #close, included, #reopen

Methods inherited from Base

#fast_tag, #level, #level=, #measure, #payload, #pop_tags, #push_tags, #silence, #tagged, #tags, #with_payload

Constructor Details

#initialize(klass, level = nil, filter = nil) ⇒ Logger

Returns a Logger instance

Return the logger for a specific class, supports class specific log levels

logger = SemanticLogger::Logger.new(self)

OR

logger = SemanticLogger::Logger.new('MyClass')

Parameters:

application
  A class, module or a string with the application/class name
  to be used in the logger

level
  The initial log level to start with for this logger instance
  Default: SemanticLogger.default_level

filter [Regexp|Proc]
  RegExp: Only include log messages where the class name matches the supplied
  regular expression. All other messages will be ignored
  Proc: Only include log messages where the supplied Proc returns true
        The Proc must return true or false


29
30
31
# File 'lib/semantic_logger/logger.rb', line 29

def initialize(klass, level=nil, filter=nil)
  super
end

Class Method Details

.closeObject

Close all appenders and flush any outstanding messages



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/semantic_logger/logger.rb', line 59

def self.close
  msg = "Closing appenders with #{queue_size} log messages on the queue"
  if queue_size > 1_000
    logger.warn msg
  elsif queue_size > 100
    logger.info msg
  elsif queue_size > 0
    logger.trace msg
  end
  process_request(:close)
end

.flushObject

Flush all queued log entries disk, database, etc.

All queued log messages are written and then each appender is flushed in turn


46
47
48
49
50
51
52
53
54
55
56
# File 'lib/semantic_logger/logger.rb', line 46

def self.flush
  msg = "Flushing appenders with #{queue_size} log messages on the queue"
  if queue_size > 1_000
    logger.warn msg
  elsif queue_size > 100
    logger.info msg
  elsif queue_size > 0
    logger.trace msg
  end
  process_request(:flush)
end

.lag_check_intervalObject

Returns the check_interval which is the number of messages between checks to determine if the appender thread is falling behind



76
77
78
# File 'lib/semantic_logger/logger.rb', line 76

def self.lag_check_interval
  @@lag_check_interval
end

.lag_check_interval=(lag_check_interval) ⇒ Object

Set the check_interval which is the number of messages between checks to determine if the appender thread is falling behind



82
83
84
# File 'lib/semantic_logger/logger.rb', line 82

def self.lag_check_interval=(lag_check_interval)
  @@lag_check_interval = lag_check_interval
end

.lag_threshold_sObject

Returns the amount of time in seconds to determine if the appender thread is falling behind



88
89
90
# File 'lib/semantic_logger/logger.rb', line 88

def self.lag_threshold_s
  @@lag_threshold_s
end

.logger=(logger) ⇒ Object

Allow the internal logger to be overridden from its default to STDERR

Can be replaced with another Ruby logger or Rails logger, but never to
SemanticLogger::Logger itself since it is for reporting problems
while trying to log to the various appenders


96
97
98
# File 'lib/semantic_logger/logger.rb', line 96

def self.logger=(logger)
  @@logger = logger
end

.on_metric(options = {}, &block) ⇒ Object

Supply a metrics appender to be called whenever a logging metric is encountered

Parameters
  appender: [Symbol | Object | Proc]
    [Proc] the block to call.
    [Object] the block on which to call #call.
    [Symbol] :new_relic, or :statsd to forward metrics to

  block
    The block to be called

Example:

SemanticLogger.on_metric do |log|
  puts "#{log.metric} was received. Log Struct: #{log.inspect}"
end

Note:

  • This callback is called in the logging thread.

  • Does not slow down the application.

  • Only context is what is passed in the log struct, the original thread context is not available.



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/semantic_logger/logger.rb', line 120

def self.on_metric(options = {}, &block)
  # Backward compatibility
  options  = options.is_a?(Hash) ? options.dup : {appender: options}
  appender = block || options.delete(:appender)

  # Convert symbolized metrics appender to an actual object
  appender = SemanticLogger.constantize_symbol(appender, 'SemanticLogger::Metrics').new(options) if appender.is_a?(Symbol)

  raise('When supplying a metrics appender, it must support the #call method') unless appender.is_a?(Proc) || appender.respond_to?(:call)
  (@@metric_subscribers ||= Concurrent::Array.new) << appender
end

.queue_sizeObject

Returns [Integer] the number of log entries that have not been written to the appenders

When this number grows it is because the logging appender thread is not able to write to the appenders fast enough. Either reduce the amount of logging, increase the log level, reduce the number of appenders, or look into speeding up the appenders themselves



40
41
42
# File 'lib/semantic_logger/logger.rb', line 40

def self.queue_size
  queue.size
end

Instance Method Details

#log(log, message = nil, progname = nil, &block) ⇒ Object

Place log request on the queue for the Appender thread to write to each appender in the order that they were registered



134
135
136
137
138
# File 'lib/semantic_logger/logger.rb', line 134

def log(log, message = nil, progname = nil, &block)
  # Compatibility with ::Logger
  return add(log, message, progname, &block) unless log.is_a?(SemanticLogger::Log)
  self.class.queue << log if @@appender_thread
end