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"
}