Back to blog

Engineering

Structured Logging for Ruby and Rails

Jeff Dwyer·September 19, 2023

Structured logging is great. It works just like you'd expect it to. I got into a ton of detail about Tagged vs Structured Logging last week, but the short version is that structured logging is fabulous for searching and analyzing your logs.

Here's what that looks like. In our controller we can:

class CalculatorController < ApplicationController
  def index
    @results = logic(height, weight)

    # OLD
    logger.debug "😞😞😞 finished calc results height=#{height} weight=#{weight} results=#{@results.size} "

    # NEW
    logger.debug "🍏🍏🍏 finished calc results", height: height, weight: weight, results: @results.size
  end
end

Even with co-pilot assistance, this is so much nicer than the old way of string formatting log output.

Running the server locally, we get the following output:

DEBUG  2023-09-19 14:30:18 -0400: app.controllers.calculator_controller.index 🍏🍏🍏 finished calc results height=19.0 results=6 weight=0.0

If you're using a JSON log formatter then you'll get JSON output instead.

{
    "severity":"DEBUG",
    "datetime":"2023-09-19T14:42:51.723-04:00",
    "path":"app.controllers.calculator_controller.index",
    "message":"🍏🍏🍏 finished calc results",
    "height":19.0,
    "weight":0.0,
    "results":6
}

Of course the real reason to do this is to make it easier to search and analyze your logs. So I'll deploy and then change the log level for our controller to debug to make sure we see our output.

Dogs in the right boxes

Now we can see how nicely these show up in Datadog:

Dogs in the right boxes

Structured logging is great, and you're just a few minutes away from having it in your app. Learn more about dynamic logging. Happy logging!

Want to try it?

Quonfig stores your config in git. Feature flags, dynamic config, log levels, and secrets — all as files you own.