Class: Appsignal::Logger

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

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)


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

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)


203
204
205
206
# File 'lib/appsignal/logger.rb', line 203

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:

“‘ruby 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:



285
286
287
# File 'lib/appsignal/logger.rb', line 285

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



161
162
163
# File 'lib/appsignal/logger.rb', line 161

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



185
186
187
# File 'lib/appsignal/logger.rb', line 185

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



193
194
195
# File 'lib/appsignal/logger.rb', line 193

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)


94
95
96
97
98
99
# File 'lib/appsignal/logger.rb', line 94

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



169
170
171
# File 'lib/appsignal/logger.rb', line 169

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.



220
221
222
223
224
225
226
227
228
# File 'lib/appsignal/logger.rb', line 220

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



177
178
179
# File 'lib/appsignal/logger.rb', line 177

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