Class: Appsignal::Logger

Inherits:
Logger
  • Object
show all
Defined in:
lib/appsignal/logger.rb,
sig/appsignal.rbs

Overview

Logger that flushes logs to the AppSignal logging service.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group, level: INFO, format: AUTODETECT, attributes: {}) ⇒ void

Create a new logger instance

Parameters:

  • group (String)

    Name of the group for this logger.

  • level (Integer) (defaults to: INFO)

    Minimum log level to report. Log lines below this level will be ignored.

  • format (Integer) (defaults to: AUTODETECT)

    Format to use to parse log line attributes.

  • attributes (Hash<String, String>) (defaults to: {})

    Default attributes for all log lines.

Raises:

  • (TypeError)


80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/appsignal/logger.rb', line 80

def initialize(group, level: INFO, format: AUTODETECT, attributes: {})
  raise TypeError, "group must be a string" unless group.is_a? String

  @group = group
  @level = level
  @silenced = false
  @format = format
  @mutex = Mutex.new
  @default_attributes = attributes
  @appsignal_attributes = attributes
  @loggers = []
end

Instance Attribute Details

#levelInteger (readonly)

Logging severity threshold

Returns:

  • (Integer)


68
69
70
# File 'lib/appsignal/logger.rb', line 68

def level
  @level
end

Instance Method Details

#<<(message) ⇒ Integer

Log an info level message

Returns the number of characters written.

Parameters:

  • message (String)

    Message to log

Returns:

  • (Integer)


206
207
208
209
# File 'lib/appsignal/logger.rb', line 206

def <<(message)
  info(message)
  message.length
end

#broadcast_to(logger) ⇒ Array<Logger>

Adds a logger to broadcast log messages to.

This implementation of the broadcasting logic exists here in the AppSignal Ruby gem, because it doesn't work in Rails using tagged logging. It would log a log line as many times as there are Rails.logger.tagged calls wrapping it.

For example, this setup with one log line:

appsignal_logger = Appsignal::Logger.new("rails")
Rails.logger.broadcast_to(appsignal_logger)

Rails.logger.tagged("my tag") do
  Rails.logger.tagged("my nested tag") do
    Rails.logger.info("Nested log")
  end
end

Is logged as the following to the AppSignal logger. Each combination of tags is sent separately.

Nested log
[my nested tag] Nested log
[my tag] Nested log
[my tag] [my nested tag] Nested log

Once it's fixed in Rails, it can be removed here.

Related issues and PRs:

Another issue was that the Rails .broadcast_to implementation in ActiveSupport::BroadcastLogger will run the block passed to .tagged as many times as there are loggers. Very early in the Rails execution stack, a middleware runs logger.tagged(...) { @app.call(env) }. This would cause the request handler to run twice, and it also causes the Rack response to be an array of Rack responses instead, which breaks the app entirely.

Related issues:

Parameters:

  • logger (Logger)

    The logger to add to the broadcast list.

Returns:



288
289
290
# File 'lib/appsignal/logger.rb', line 288

def broadcast_to(logger)
  @loggers << logger
end

#debug(message = nil, attributes = {}, &block) ⇒ void

This method returns an undefined value.

Log a debug level message

Parameters:

  • message (String) (defaults to: nil)

    Message to log

  • attributes (Hash<String, Object>) (defaults to: {})

    Attributes to tag the log with



164
165
166
# File 'lib/appsignal/logger.rb', line 164

def debug(message = nil, attributes = {}, &block)
  add_with_attributes(DEBUG, message, @group, attributes, &block)
end

#error(message = nil, attributes = {}, &block) ⇒ void

This method returns an undefined value.

Log an error level message

Parameters:

  • message (String, Exception) (defaults to: nil)

    Message to log

  • attributes (Hash<String, Object>) (defaults to: {})

    Attributes to tag the log with



188
189
190
# File 'lib/appsignal/logger.rb', line 188

def error(message = nil, attributes = {}, &block)
  add_with_attributes(ERROR, message, @group, attributes, &block)
end

#fatal(message = nil, attributes = {}, &block) ⇒ void

This method returns an undefined value.

Log a fatal level message

Parameters:

  • message (String, Exception) (defaults to: nil)

    Message to log

  • attributes (Hash<String, Object>) (defaults to: {})

    Attributes to tag the log with



196
197
198
# File 'lib/appsignal/logger.rb', line 196

def fatal(message = nil, attributes = {}, &block)
  add_with_attributes(FATAL, message, @group, attributes, &block)
end

#formatter=(formatter) ⇒ Proc

Sets the formatter for this logger and all broadcasted loggers.

Parameters:

  • formatter (Proc)

    The formatter to use for log messages.

Returns:

  • (Proc)


97
98
99
100
101
102
# File 'lib/appsignal/logger.rb', line 97

def formatter=(formatter)
  super
  @loggers.each do |logger|
    logger.formatter = formatter if logger.respond_to?(:formatter=)
  end
end

#info(message = nil, attributes = {}, &block) ⇒ void

This method returns an undefined value.

Log an info level message

Parameters:

  • message (String) (defaults to: nil)

    Message to log

  • attributes (Hash<String, Object>) (defaults to: {})

    Attributes to tag the log with



172
173
174
# File 'lib/appsignal/logger.rb', line 172

def info(message = nil, attributes = {}, &block)
  add_with_attributes(INFO, message, @group, attributes, &block)
end

#silence(severity = ERROR, &block) ⇒ Object

Temporarily silences the logger to a specified level while executing a block.

When using ActiveSupport::TaggedLogging without the broadcast feature, the passed logger is required to respond to the silence method.

Reference links:

Parameters:

  • severity (Integer) (defaults to: ERROR)

    The minimum severity level to log during the block.

Returns:

  • (Object)

    The return value of the block.



223
224
225
226
227
228
229
230
231
# File 'lib/appsignal/logger.rb', line 223

def silence(severity = ERROR, &block)
  previous_level = @level
  @level = severity
  @silenced = true
  block.call(self)
ensure
  @level = previous_level
  @silenced = false
end

#warn(message = nil, attributes = {}, &block) ⇒ void

This method returns an undefined value.

Log a warn level message

Parameters:

  • message (String) (defaults to: nil)

    Message to log

  • attributes (Hash<String, Object>) (defaults to: {})

    Attributes to tag the log with



180
181
182
# File 'lib/appsignal/logger.rb', line 180

def warn(message = nil, attributes = {}, &block)
  add_with_attributes(WARN, message, @group, attributes, &block)
end