Skip to main content

Rails Logger

Provide logging capabilities to Rails applications in the following areas:

  • application log: events related to the application runtime
  • access log: requests and responses
  • performance log: metrics

Levels

Represent the type and importante of the message

  • trace: Low level trace information such as data sent over a socket
  • debug: Debugging information to aid with problem determination
  • info: Informational message such as request received
  • warn: Warn about something in the system
  • error: An error occurred during processing
  • fatal: Unrecoverable system errors

Modes

The logger output (formatter) vary depending on the environment:

  • local: output optimized for the local environment and the rails console. It has a simple and prettified output.
  • production: JSON output with structured information which can be parsed by Datadog

?> Both of them go to STDOUT. In production, logs are collected from the container output

Log Event

Log events in production are formatted as JSON and contain structured data that can be easily parsed and queried. A log event will have common fields but custom fields (payload) can be added

?> Adding custom fields
A custom field should only be added if there's a requirement to query them or see it in a column in Datadog. For any other case, you can include the data in the standard message string

Common fields

  • time: The time at which the log entry was created.
  • name: Class name supplied to the logging instance
  • message: Text message to be logged.
  • payload: payload
  • etc... Check Log event for additional details

the name field already contains the class which generated the event, there's no need to add any type field or similar

Base payload fields

They payload will contain common fields like the user, arc-web version, etc. Check app/lib/api/logger_config.rb for additional details

Usage

The following Rails components have a reference to a logger instance: ActiveRecord ActiveJob, controllers, GraphQL resolvers and rake tasks. When the logger instance is not available, include the following SemanticLogger:Loggable module to access it.

API

log.info(message, payload_or_exception = nil, exception = nil, &block)
  • message: The text message to log. (Mandatory only if no block is supplied)
  • payload_or_exception: Optional, either a Ruby Exception object or a Hash
  • exception: Optional, Ruby Exception object.
  • block: The optional block is executed only if the corresponding log level is active.

Expensive calculations

When logging events that are expensive to calculate, you can provide a block, which is only evaluated when the log level meets or exceeds the supplied log level. This can be used to prevent the block from being evaluated in production environments:

logger.info { "A total of #{results.inject(0) {|sum, i| i+sum }} were processed" }

Check API documentation for additional details

Examples

logger.info("An event happened here")
logger.warn("Unexpected situation", chart_id: chart.id, message_id: message.id)
logger.error("An error ocurred", e)

ActiveJob

Log events generated during the job execution will include the following fields:

"job": {
"id": "151887a6-331b-4a10-9676-de813f2b2221",
"name": "SendScheduledMessagesJob"
}

!> Important Avoid messages like "Starting" or "Ending" since Resque already does that. Instead use a more meaningful message e.g."Processing #{count} charts", "Finished processed success: #{success_count} error: #{errors_count}"

Rake tasks

Log event will include:

"rake": {
"task_name": "SendScheduledMessagesJob"
}

Decisions