Module: SemanticLogger

Defined in:
lib/semantic_logger/base.rb,
lib/semantic_logger.rb,
lib/semantic_logger/logger.rb,
lib/semantic_logger/version.rb,
lib/semantic_logger/loggable.rb,
lib/semantic_logger/appender/base.rb,
lib/semantic_logger/appender/file.rb,
lib/semantic_logger/appender/syslog.rb,
lib/semantic_logger/semantic_logger.rb,
lib/semantic_logger/appender/mongodb.rb,
lib/semantic_logger/appender/wrapper.rb

Overview

Wrapper appender

Wraps the Rails log, log4r, or Ruby Logger with the SemanticLogger API's

Defined Under Namespace

Modules: Appender, Loggable Classes: Base, Logger

Constant Summary collapse

VERSION =
"2.9.2"
LEVELS =

Logging levels in order of most detailed to most severe

[:trace, :debug, :info, :warn, :error, :fatal]

Class Method Summary collapse

Class Method Details

.[](klass) ⇒ Object

Return a logger for the supplied class or class_name



7
8
9
# File 'lib/semantic_logger/semantic_logger.rb', line 7

def self.[](klass)
  SemanticLogger::Logger.new(klass)
end

.add_appender(appender, level = nil, &block) ⇒ Object

Add a new logging appender as a new destination for all log messages emitted from Semantic Logger

Appenders will be written to in the order that they are added

If a block is supplied then it will be used to customize the format of the messages sent to that appender. See SemanticLogger::Logger.new for more information on custom formatters

Parameters

appender [String|IO|SemanticLogger::Appender::Base|::Logger]
  Filename to write log messages to
     Or,
  STDOUT, STDERR, or any IO stream to write log messages to
     Or,
  Any SemanticLogger::Appender instance such as
    SemanticLogger::Appender::File
    SemanticLogger::Appender::Wrapper
    SemanticLogger::Appender::Mongodb
     Or,
  A custom appender derived from SemanticLogger::Appender::Base
     Or,
  Ruby built-in Logger, or any logger that implements the following methods:
    :debug, :info, :warn, :error, :fatal

level [Symbol]
  Optional
  By setting the level higher than the SemanticLogger::default_level
  this appender can exclude lower level log messages
  Any one of SemanticLogger::LEVELS. For example: :trace, :debug, :info, :warn, :error, :fatal

Examples:

# Send all logging output to Standard Out (Screen)
SemanticLogger.add_appender(STDOUT)

# Send all logging output to a file
SemanticLogger.add_appender('logfile.log')

# Send all logging output to a file and only :info and above to standard output
SemanticLogger.add_appender('logfile.log')
SemanticLogger.add_appender(STDOUT, :info)

Log to an existing logger:

# Send Semantic logging output to an existing logger
require 'logger'
require 'semantic_logger'

# Built-in Ruby logger
log = Logger.new(STDOUT)
log.level = Logger::DEBUG

SemanticLogger.default_level = :debug
SemanticLogger.add_appender(log)

logger = SemanticLogger['Example']
logger.info "Hello World"
logger.debug("Login time", :user => 'Joe', :duration => 100, :ip_address=>'127.0.0.1')


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/semantic_logger/semantic_logger.rb', line 85

def self.add_appender(appender, level=nil, &block)
  appender_instance = if appender.is_a?(String) || appender.is_a?(IO)
    # $stderr, STDOUT, other IO, or a filename
    SemanticLogger::Appender::File.new(appender, level, &block)
  elsif appender.is_a? Appender::Base
    # Already an instance of an appender
    appender.level = level if level
    appender.formatter = block if block
    appender
  else
    # Check if the custom appender responds to all the log levels. For example Ruby ::Logger
    if does_not_implement = LEVELS[1..-1].find{|i| !appender.respond_to?(i)}
      raise "Supplied appender does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}"
    end

    raise "Change the log level to #{level}, update the log level directly against the supplied appender" if level
    SemanticLogger::Appender::Wrapper.new(appender, &block)
  end
  @@appenders << appender_instance

  # Start appender thread if it is not already running
  SemanticLogger::Logger.start_appender_thread

  appender_instance
end

.add_signal_handler(signal = 'USR2') ⇒ Object

Add a signal handler so that the log level can be changed externally without restarting the process

When the signal is raised on this process, the global default log level rotates through the following log levels in the following order, starting from the current global default level:

:warn, :info, :debug, :trace

If the current level is :trace it wraps around back to :warn



164
165
166
167
168
169
170
171
172
# File 'lib/semantic_logger/semantic_logger.rb', line 164

def self.add_signal_handler(signal='USR2')
  Signal.trap(signal) do
    index = (default_level == :trace) ? LEVELS.find_index(:error) : LEVELS.find_index(default_level)
    new_level = LEVELS[index-1]
    self['SemanticLogger'].warn "Changed global default log level to #{new_level.inspect}"
    self.default_level = new_level
  end
  signal
end

.appendersObject

Returns [SemanticLogger::Appender::Base] a copy of the list of active appenders for debugging etc. Use SemanticLogger.add_appender and SemanticLogger.remove_appender to manipulate the active appenders list



121
122
123
# File 'lib/semantic_logger/semantic_logger.rb', line 121

def self.appenders
  @@appenders.clone
end

.default_levelObject

Returns the global default log level for new Logger instances



21
22
23
# File 'lib/semantic_logger/semantic_logger.rb', line 21

def self.default_level
  @@default_level
end

.default_level=(level) ⇒ Object

Allow for setting the global default log level This change only applies to new loggers, existing logger levels will not be changed in any way



14
15
16
17
18
# File 'lib/semantic_logger/semantic_logger.rb', line 14

def self.default_level=(level)
  @@default_level = level
  # For performance reasons pre-calculate the level index
  @@default_level_index = level_to_index(level)
end

.flushObject

Wait until all queued log messages have been written and flush all active appenders



127
128
129
# File 'lib/semantic_logger/semantic_logger.rb', line 127

def self.flush
  SemanticLogger::Logger.flush
end

.on_metric(&block) ⇒ Object

Supply a block to be called whenever a metric is seen during benchmark logging

Parameters
  block
    The block to be called

Example:

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


151
152
153
# File 'lib/semantic_logger/semantic_logger.rb', line 151

def self.on_metric(&block)
  SemanticLogger::Logger.on_metric(&block)
end

.remove_appender(appender) ⇒ Object

Remove an existing appender Currently only supports appender instances



113
114
115
# File 'lib/semantic_logger/semantic_logger.rb', line 113

def self.remove_appender(appender)
  @@appenders.delete(appender)
end

.reopenObject

After forking an active process call SemanticLogger.reopen to re-open any open file handles etc to resources

Note: Only appenders that implement the reopen method will be called



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

def self.reopen
  @@appenders.each {|appender| appender.reopen if appender.respond_to?(:reopen)}
  # After a fork the appender thread is not running, start it if it is not running
  SemanticLogger::Logger.start_appender_thread
end