Class: Celluloid::IncidentLogger

Inherits:
Object
  • Object
show all
Includes:
Severity
Defined in:
lib/celluloid/logging/incident_logger.rb

Overview

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.

Defined Under Namespace

Modules: Severity

Constant Summary

Constants included from Severity

Severity::TRACE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Severity

#severity_to_string

Constructor Details

#initialize(progname = nil, options = {}) ⇒ IncidentLogger

Create a new IncidentLogger.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/celluloid/logging/incident_logger.rb', line 44

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

Instance Attribute Details

#buffersObject

Returns the value of attribute buffers.



41
42
43
# File 'lib/celluloid/logging/incident_logger.rb', line 41

def buffers
  @buffers
end

#levelObject

The logging level. Messages below this severity will not be logged at all.



31
32
33
# File 'lib/celluloid/logging/incident_logger.rb', line 31

def level
  @level
end

#prognameObject

The progname (facility) for this instance.



28
29
30
# File 'lib/celluloid/logging/incident_logger.rb', line 28

def progname
  @progname
end

#sizelimitObject

The buffer size limit. Each log level will retain this number of messages at maximum.



39
40
41
# File 'lib/celluloid/logging/incident_logger.rb', line 39

def sizelimit
  @sizelimit
end

#thresholdObject

The incident threshold. Messages at or above this severity will generate an incident and be published to incident reporters.



35
36
37
# File 'lib/celluloid/logging/incident_logger.rb', line 35

def threshold
  @threshold
end

Instance Method Details

#add(severity, message = nil, progname = nil, &block) ⇒ Object Also known as: log

add an event.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/celluloid/logging/incident_logger.rb', line 65

def add(severity, message=nil, progname=nil, &block)
  progname ||= @progname
  severity ||= UNKNOWN

  return event.id if severity < @level

  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

#clearObject



132
133
134
135
136
# File 'lib/celluloid/logging/incident_logger.rb', line 132

def clear
  @buffer_mutex.synchronize do
    @buffers.each(&:clear)
  end
end

#create_incident(event = nil) ⇒ Object



138
139
140
# File 'lib/celluloid/logging/incident_logger.rb', line 138

def create_incident(event=nil)
  Incident.new(flush, event)
end

#debug(progname = nil, &block) ⇒ Object



96
97
98
# File 'lib/celluloid/logging/incident_logger.rb', line 96

def debug(progname=nil, &block)
  add(DEBUG,   nil, progname, &block)
end

#error(progname = nil, &block) ⇒ Object



108
109
110
# File 'lib/celluloid/logging/incident_logger.rb', line 108

def error(progname=nil, &block)
  add(ERROR,   nil, progname, &block)
end

#fatal(progname = nil, &block) ⇒ Object



112
113
114
# File 'lib/celluloid/logging/incident_logger.rb', line 112

def fatal(progname=nil, &block)
  add(FATAL,   nil, progname, &block)
end

#flushObject



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

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

#incident_topicObject



142
143
144
# File 'lib/celluloid/logging/incident_logger.rb', line 142

def incident_topic
  "log.incident.#{@progname}"
end

#info(progname = nil, &block) ⇒ Object



100
101
102
# File 'lib/celluloid/logging/incident_logger.rb', line 100

def info(progname=nil, &block)
  add(INFO,    nil, progname, &block)
end

#trace(progname = nil, &block) ⇒ Object

See docs for Logger#info



92
93
94
# File 'lib/celluloid/logging/incident_logger.rb', line 92

def trace(progname=nil, &block)
  add(TRACE,   nil, progname, &block)
end

#unknown(progname = nil, &block) ⇒ Object



116
117
118
# File 'lib/celluloid/logging/incident_logger.rb', line 116

def unknown(progname=nil, &block)
  add(UNKNOWN, nil, progname, &block)
end

#warn(progname = nil, &block) ⇒ Object



104
105
106
# File 'lib/celluloid/logging/incident_logger.rb', line 104

def warn(progname=nil, &block)
  add(WARN,    nil, progname, &block)
end