/usr/lib/ruby/vendor_ruby/celluloid/logging/incident_logger.rb is in ruby-celluloid 0.16.0-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | require 'logger'
module Celluloid
# A logger that holds all messages in circular buffers, then flushes the buffers
# when an event occurs at a configurable severity threshold.
#
# Unlike ruby's Logger, this class only supports a single progname.
class IncidentLogger
module Severity
include ::Logger::Severity
TRACE = -1
def severity_to_string(severity)
case severity
when TRACE then 'TRACE'
when DEBUG then 'DEBUG'
when INFO then 'INFO'
when WARN then 'WARN'
when ERROR then 'ERROR'
when FATAL then 'FATAL'
when UNKNOWN then 'UNKNOWN'
end
end
end
include Severity
# The progname (facility) for this instance.
attr_accessor :progname
# The logging level. Messages below this severity will not be logged at all.
attr_accessor :level
# The incident threshold. Messages at or above this severity will generate an
# incident and be published to incident reporters.
attr_accessor :threshold
# The buffer size limit. Each log level will retain this number of messages
# at maximum.
attr_accessor :sizelimit
attr_accessor :buffers
# Create a new IncidentLogger.
def initialize(progname=nil, options={})
@progname = progname || "default"
@level = options[:level] || DEBUG
@threshold = options[:threshold] || ERROR
@sizelimit = options[:sizelimit] || 100
@buffer_mutex = Mutex.new
@buffers = Hash.new do |progname_hash, _progname|
@buffer_mutex.synchronize do
progname_hash[_progname] = Hash.new do |severity_hash, severity|
severity_hash[severity] = RingBuffer.new(@sizelimit)
end
end
end
# When the IncidentLogger itself encounters an error, it falls back to logging to stderr
@fallback_logger = ::Logger.new(STDERR)
@fallback_logger.progname = "FALLBACK"
end
# add an event.
def add(severity, message=nil, progname=nil, &block)
progname ||= @progname
severity ||= UNKNOWN
if severity < @level
return event.id
end
if message.nil? && !block_given?
message = progname
progname = @progname
end
event = LogEvent.new(severity, message, progname, &block)
@buffers[progname][severity] << event
if severity >= @threshold
begin
Celluloid::Notifications.notifier.async.publish(incident_topic, create_incident(event))
rescue => ex
@fallback_logger.error(ex)
end
end
event.id
end
alias :log :add
# See docs for Logger#info
def trace (progname=nil, &block); add(TRACE, nil, progname, &block); end
def debug (progname=nil, &block); add(DEBUG, nil, progname, &block); end
def info (progname=nil, &block); add(INFO, nil, progname, &block); end
def warn (progname=nil, &block); add(WARN, nil, progname, &block); end
def error (progname=nil, &block); add(ERROR, nil, progname, &block); end
def fatal (progname=nil, &block); add(FATAL, nil, progname, &block); end
def unknown (progname=nil, &block); add(UNKNOWN, nil, progname, &block); end
def flush
messages = []
@buffer_mutex.synchronize do
@buffers.each do |progname, severities|
severities.each do |severity, buffer|
messages += buffer.flush
end
end
end
messages.sort
end
def clear
@buffer_mutex.synchronize do
@buffers.each { |buffer| buffer.clear }
end
end
def create_incident(event=nil)
Incident.new(flush, event)
end
def incident_topic
"log.incident.#{@progname}"
end
end
end
|