How to properly create dedicated loggers for desired Ruby on Rails classes, in a nice, compact and generic way?

124 Views Asked by At

Everything is in the title but for the sake of it:

The company I work for has a really big Ruby On Rails app. After years of development we realized it lacked of logging. Production incidents were sometimes really hard to track and consequently to resolve.

So there was that issue in our backlog to improve the whole logging system.

I started added custom loggers for classes here and there, when really required but it seemed kind of dumb to copy / paste that piece of logic everywhere.

So i wondered: How to properly create dedicated loggers for desired Ruby on Rails classes, in a nice, compact and generic way ?

1

There are 1 best solutions below

0
Slth On

The answer for me was the use of ActiveSupport::Concern.

The code is easily understandable and commented so I think just pasting it here will make the best of explanations:

# frozen_string_literal: true

# This concern can be included in any class to add a dedicated logger
# This will have the effect of creating a custom logger for the class
# The logger will be accessible through the `logger` class method and
# will create a log file in the `log` directory with the name of the class
# in snake case

# Example of use:
# class SampleClass
#   include DedicatedLoggerConcern
# end
#
# SampleClass.logger.info('Hello world')
#
# # Will write to log/sample_class.log
# :nocov:
module DedicatedLoggerConcern
  extend ActiveSupport::Concern

  included do
    @logger = Logger.new(Rails.root.join('log', "#{name.underscore}.log"))
  end

  class_methods do
    attr_reader :logger
  end
end

The code comments say it all. Nothing groundbreaking here but I also think that is a really good example of a proper use of ActiveSupport::Concern. I often see it used as a way to split models/controllers that get too big into different logical bricks (which may not be wrong neither) but i feel this kind of generic way to add a possibility to any class is more like it's meant to be used (or am I wrong ?).

Feel free to debate, hope this helps :)