Class: Sapience::Logger

Inherits:
Base
  • Object
show all
Includes:
Concerns::Compatibility
Defined in:
lib/sapience/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

Sapience::Loggers::Concurrent

Constant Summary collapse

@@appender_thread =
nil
@@logger =
nil

Instance Attribute Summary

Attributes inherited from Base

#filter, #log_hooks, #name

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Concerns::Compatibility

#add, #close, included, #reopen

Methods inherited from Base

#app_name, #default_formatter, #fast_tag, #host, #level, #level=, #payload, #pop_tags, #push_tags, #silence, #tagged, #tags, #with_payload

Methods included from LogMethods

#debug, #debug?, #error, #error!, #error?, #fatal, #fatal!, #fatal?, #info, #info?, #level_to_index, #log_with_exception, #log_with_level, #measure, #measure_debug, #measure_error, #measure_fatal, #measure_info, #measure_trace, #measure_warn, #trace, #trace?, #warn, #warn?

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 = Sapience::Logger.new(self)

OR

logger = Sapience::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: Sapience.config.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


126
127
128
# File 'lib/sapience/logger.rb', line 126

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

Class Method Details

.appender_threadObject

Separate appender thread responsible for reading log messages and calling the appenders in it’s thread



89
90
91
# File 'lib/sapience/logger.rb', line 89

def self.appender_thread
  @@appender_thread
end

.appender_thread_active?Boolean

Returns true if the appender_thread is active

Returns:

  • (Boolean)


83
84
85
# File 'lib/sapience/logger.rb', line 83

def self.appender_thread_active?
  @@appender_thread && @@appender_thread.running?
end

.closeObject

Close all appenders and flush any outstanding messages



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/sapience/logger.rb', line 31

def self.close
  return unless appender_thread
  appender_thread << lambda do
    Sapience.appenders.each do |appender|
      next unless appender.valid?
      begin
        close_appender(appender)
      rescue StandardError => exc
        logger.error "Appender thread: Failed to close appender: #{appender.inspect}", exc
      end
    end
    logger.trace "Appender thread: All appenders flushed"
  end
end

.close_appender(appender) ⇒ Object



46
47
48
49
50
51
# File 'lib/sapience/logger.rb', line 46

def self.close_appender(appender)
  logger.trace "Appender thread: Closing appender: #{appender.name}"
  appender.flush
  appender.close
  Sapience.remove_appender(appender)
end

.flushObject

Flush all queued log entries disk, database, etc.

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


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/sapience/logger.rb', line 13

def self.flush # rubocop:disable AbcSize
  return unless appender_thread
  appender_thread << lambda do
    Sapience.appenders.each do |appender|
      next unless appender.valid?
      begin
        logger.trace "Appender thread: Flushing appender: #{appender.class.name}"
        appender.flush
      rescue StandardError => exc
        $stderr.write("Appender thread: Failed to flush to appender: #{appender.inspect}\n #{exc.inspect}")
      end
    end

    logger.trace "Appender thread: All appenders flushed"
  end
end

.invalid_appenders_taskObject



93
94
95
# File 'lib/sapience/logger.rb', line 93

def self.invalid_appenders_task
  @@invalid_appenders_task
end

.loggerObject

Internal logger for Sapience

For example when an appender is not working etc..
By default logs to STDERR


59
60
61
# File 'lib/sapience/logger.rb', line 59

def self.logger
  @@logger ||= Sapience[Sapience]
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
Sapience::Logger itself since it is for reporting problems
while trying to log to the various appenders


101
102
103
# File 'lib/sapience/logger.rb', line 101

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

.start_appender_threadObject

Start the appender thread



64
65
66
67
68
69
70
# File 'lib/sapience/logger.rb', line 64

def self.start_appender_thread
  return false if appender_thread_active?

  @@appender_thread = Sapience.log_executor_class.new
  fail "Failed to start Appender Thread" unless @@appender_thread
  true
end

.start_invalid_appenders_taskObject



72
73
74
75
76
77
78
79
80
# File 'lib/sapience/logger.rb', line 72

def self.start_invalid_appenders_task
  @@invalid_appenders_task = Concurrent::TimerTask.new(execution_interval: 120, timeout_interval: 5) do
    Sapience.appenders.each do |appender|
      next if appender.valid?
      logger.warn { "#{appender.class} is not valid. #{appender::VALIDATION_MESSAGE}" }
    end
  end
  invalid_appenders_task.execute
end

Instance Method Details

#flushObject



150
151
152
# File 'lib/sapience/logger.rb', line 150

def flush
  self.class.flush
end

#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



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

def log(log, message = nil, progname = nil, &block)
  # Compatibility with ::Logger
  return add(log, message, progname, &block) unless log.is_a?(Sapience::Log)
  if @@appender_thread
    @@appender_thread << lambda do
      Sapience.appenders.each do |appender|
        next unless appender.valid?
        begin
          appender.log(log)
        rescue StandardError => exc
          $stderr.write("Appender thread: Failed to log to appender: #{appender.inspect}\n #{exc.inspect}")
        end
      end
      Sapience.clear_tags!
    end
  end
end