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.



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

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, pn|
    @buffer_mutex.synchronize do
      progname_hash[pn] = 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.



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

def buffers
  @buffers
end

#levelObject

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



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

def level
  @level
end

#prognameObject

The progname (facility) for this instance.



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

def progname
  @progname
end

#sizelimitObject

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



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

def sizelimit
  @sizelimit
end

#thresholdObject

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



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

def threshold
  @threshold
end

Instance Method Details

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

add an event.



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/celluloid/logging/incident_logger.rb', line 66

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



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

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

#create_incident(event = nil) ⇒ Object



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

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

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



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

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

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



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

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

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



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

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

#flushObject



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

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



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

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

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



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

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

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

See docs for Logger#info



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

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

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



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

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

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



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

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