Customize Ruby log formatting

Use a Logger formatter for readable text or newline-delimited JSON, with explicit timestamps and deliberate exception handling.

Best practices
Illustration of monitoring and troubleshooting application behavior

Assign a callable to logger.formatter to control each emitted record. It receives the severity, a Time object, the program name, and the message, and returns the formatted string. Include a newline yourself when each event should occupy one line.

Format readable text

require 'logger'
require 'time'

logger = Logger.new('application.log')
logger.level = Logger::INFO
logger.formatter = proc do |severity, time, progname, message|
  "#{time.utc.iso8601(3)} [#{severity}] #{progname}: #{message}\n"
end
logger.progname = 'billing'
logger.debug('Filtered debug message')
logger.info('Invoice created')
logger.error('Payment failed')
Argument Meaning
severity Severity name, including UNKNOWN
time The event's Time object
progname Program name, which may be absent
message The supplied message object

A custom formatter replaces the default formatting behavior. If messages can be exceptions or structured objects, handle those types explicitly instead of assuming interpolation preserves all useful details.

Emit one JSON object per line

require 'json'

logger.formatter = proc do |severity, time, progname, message|
  data = {
    time: time.utc.iso8601(3),
    level: severity,
    program: progname
  }
  if message.is_a?(Exception)
    data[:message] = message.message
    data[:error_class] = message.class.name
    data[:backtrace] = message.backtrace
  else
    data[:message] = message
  end
  JSON.generate(data) + "\n"
end

Use messages that your JSON encoder can serialize predictably. JSON escapes embedded newlines in strings, keeping each serialized event on one physical line. Redact sensitive fields before encoding.

When collecting with DataKit, file log collection supports json_as_fields for extracting top-level JSON fields. Check the received timestamp, level, and original message; nested values and field renaming may need additional parsing.

Other logging choices

For console and file output, configure two Logger instances or a suitable broadcasting logger. They can use different formats.

For rotation, Logger.new('app.log', 'daily') rotates by period. Logger.new('app.log', 10, 100 * 1024 * 1024) uses a size threshold in bytes. The Rails helper 100.megabytes is not part of plain Ruby.

Rails provides config.log_formatter; a custom config.logger must be wired to use the formatter you want. Libraries such as Lograge change request logging behavior and should be configured according to their own documentation.

References: Ruby Logger and Rails logging configuration.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting