Class: Sapience::Appender::File

Inherits:
Subscriber show all
Defined in:
lib/sapience/appender/file.rb

Instance Attribute Summary

Attributes inherited from Subscriber

#application, #formatter, #host

Attributes inherited from Base

#filter, #name

Instance Method Summary collapse

Methods inherited from Subscriber

#close, #default_formatter, #level

Methods inherited from Base

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

Constructor Details

#initialize(options = {}, deprecated_level = nil, deprecated_filter = nil, &block) ⇒ File

Create a File Logger appender instance.

Parameters

:file_name [String|IO]
  Name of file to write to.
  Or, an IO stream to which to write the log message to.

:level [:trace | :debug | :info | :warn | :error | :fatal]
  Override the log level for this appender.
  Default: Sapience.config.default_level

:formatter: [Object|Proc]
  An instance of a class that implements #call, or a Proc to be used to format
  the output from this appender
  Default: Use the built-in formatter (See: #call)

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

Example

require 'sapience'

# Enable trace level logging
Sapience.config.default_level = :info

# Log to screen
Sapience.add_appender(:file, io: STDOUT, formatter: :color)

# And log to a file at the same time
Sapience::Logger.add_appender(:file, file_name: 'application.log', formatter: :color)

logger = Sapience['test']
logger.info 'Hello World'

Example 2. To log all levels to file and only :info and above to screen:

require 'sapience'

# Enable trace level logging
Sapience.config.default_level = :trace

# Log to screen but only display :info and above
Sapience.add_appender(:file, io: STDOUT, level: :info)

# And log to a file at the same time, including all :trace level data
Sapience.add_appender(:file, file_name: 'application.log')

logger =  Sapience['test']
logger.info 'Hello World'


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sapience/appender/file.rb', line 61

def initialize(options = {}, deprecated_level = nil, deprecated_filter = nil, &block)
  # Old style arguments: (file_name, level=nil, filter=nil, &block)
  options =
    if options.is_a?(Hash)
      options.dup
    else
      file_name = options
      opts      = {}
      if file_name.respond_to?(:write) && file_name.respond_to?(:close)
        opts[:io] = file_name
      else
        opts[:file_name] = file_name
      end
      opts[:level]  = deprecated_level if deprecated_level
      opts[:filter] = deprecated_filter if deprecated_filter
      opts
    end

  if io = options.delete(:io)
    @log = io
  else
    @file_name = options.delete(:file_name)
    fail "Sapience::Appender::File missing mandatory parameter :file_name or :io" unless @file_name
    reopen
  end

  # Set the log level and formatter if supplied
  super(options, &block)
end

Instance Method Details

#ensure_folder_existObject



109
110
111
112
113
114
115
# File 'lib/sapience/appender/file.rb', line 109

def ensure_folder_exist
  return if ::File.exist?(@file_name)

  dir_name = ::File.dirname(@file_name)

  FileUtils.mkdir_p(dir_name)
end

#flushObject

Flush all pending logs to disk.

Waits for all sent documents to be writted to disk


132
133
134
# File 'lib/sapience/appender/file.rb', line 132

def flush
  @log.flush if @log.respond_to?(:flush)
end

#log(log) ⇒ Object

Pass log calls to the underlying Rails, log4j or Ruby logger

trace entries are mapped to debug since :trace is not supported by the
Ruby or Rails Loggers


120
121
122
123
124
125
126
127
128
# File 'lib/sapience/appender/file.rb', line 120

def log(log)
  return false unless should_log?(log)

  # Since only one appender thread will be writing to the file at a time
  # it is not necessary to protect access to the file with a semaphore
  # Allow this logger to filter out log levels lower than it's own
  @log.write(formatter.call(log, self) << "\n")
  true
end

#reopenObject

After forking an active process call #reopen to re-open open the file handles etc to resources

Note: This method will only work if :file_name was supplied

on the initializer.
If :io was supplied, it will need to be re-opened manually.


97
98
99
100
101
102
103
104
105
106
107
# File 'lib/sapience/appender/file.rb', line 97

def reopen
  return unless @file_name
  ensure_folder_exist

  @log      = open(@file_name, (::File::WRONLY | ::File::APPEND | ::File::CREAT))
  # Force all log entries to write immediately without buffering
  # Allows multiple processes to write to the same log file simultaneously
  @log.sync = true
  @log.set_encoding(Encoding::BINARY) if @log.respond_to?(:set_encoding)
  @log
end