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
89
90
# File 'lib/celluloid/logging/incident_logger.rb', line 65

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

#clearObject


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

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

#create_incident(event = nil) ⇒ Object


120
121
122
# File 'lib/celluloid/logging/incident_logger.rb', line 120

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

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


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

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

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


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

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

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


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

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

#flushObject


102
103
104
105
106
107
108
109
110
111
112
# File 'lib/celluloid/logging/incident_logger.rb', line 102

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


124
125
126
# File 'lib/celluloid/logging/incident_logger.rb', line 124

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

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


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

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

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

See docs for Logger#info


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

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

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


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

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

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


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

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