Module: RailsSemanticLogger

Defined in:
lib/rails_semantic_logger/active_job/log_subscriber.rb,
lib/rails_semantic_logger.rb,
lib/rails_semantic_logger/engine.rb,
lib/rails_semantic_logger/options.rb,
lib/rails_semantic_logger/version.rb,
lib/rails_semantic_logger/appenders.rb,
lib/rails_semantic_logger/rack/logger.rb,
lib/rails_semantic_logger/sidekiq/defaults.rb,
lib/rails_semantic_logger/sidekiq/loggable.rb,
lib/rails_semantic_logger/sidekiq/job_logger.rb,
lib/rails_semantic_logger/action_view/log_subscriber.rb,
lib/rails_semantic_logger/solid_queue/log_subscriber.rb,
lib/rails_semantic_logger/action_mailer/log_subscriber.rb,
lib/rails_semantic_logger/active_record/log_subscriber.rb,
lib/rails_semantic_logger/action_controller/log_subscriber.rb

Overview

This subscriber is a reimplementation of Rails' own ActionController::LogSubscriber that emits structured (message + payload) log entries instead of formatted text. When Rails changes its subscriber, those changes must be brought across here. Compare against the upstream source for each supported Rails version:

Rails 8.1: https://github.com/rails/rails/blob/8-1-stable/actionpack/lib/action_controller/log_subscriber.rb
Rails 8.0: https://github.com/rails/rails/blob/8-0-stable/actionpack/lib/action_controller/log_subscriber.rb
Rails 7.2: https://github.com/rails/rails/blob/7-2-stable/actionpack/lib/action_controller/log_subscriber.rb

Defined Under Namespace

Modules: ActionController, ActionMailer, ActionView, ActiveJob, ActiveRecord, Rack, Sidekiq, SolidQueue Classes: Appenders, Engine, Options

Constant Summary collapse

VERSION =
"5.0.0".freeze

Class Method Summary collapse

Class Method Details

.add_appenders(appenders) ⇒ Object

Create each appender declared via config.rails_semantic_logger.appenders. The first file appender (if any) becomes the internal logger, so that any failures writing to other appenders are still recorded somewhere durable.



108
109
110
111
112
113
114
115
# File 'lib/rails_semantic_logger.rb', line 108

def self.add_appenders(appenders)
  internal_logger = nil
  appenders.each do |args, block|
    appender = SemanticLogger.add_appender(**args, &block)
    internal_logger ||= appender if appender.is_a?(SemanticLogger::Appender::File)
  end
  SemanticLogger::Processor.logger = internal_logger if internal_logger
end

.add_console_appendersObject

Console (REPL) counterpart of .add_server_appenders, used by the rails console hook. When the application declared its own appenders, its add_console declarations apply; otherwise the deprecated console_logger toggle decides whether the default stderr console appender is added.



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/rails_semantic_logger.rb', line 93

def self.add_console_appenders
  options = Rails.application.config.rails_semantic_logger
  # Backward compatibility: honor the deprecated console_logger toggle.
  if !options.appenders? && options.console_logger && !SemanticLogger.appenders.console_output?
    SemanticLogger.add_appender(io: $stderr, formatter: :color)
  end

  options.appenders.console.each do |args, block|
    SemanticLogger.add_appender(**args, &block)
  end
end

.add_server_appendersObject

Create the appenders declared via config.rails_semantic_logger.appenders with add_server (or the default console appender when the application declared no appenders of its own).

Called automatically for the server contexts that have a first-party hook (rails server, Sidekiq in server mode). App servers without such a hook (bare puma, rackup, Passenger, Unicorn) cannot be detected reliably, so call this from the server's own definitive boot hook instead of relying on a guess. Example, in config/puma.rb:

on_booted { RailsSemanticLogger.add_server_appenders }


77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rails_semantic_logger.rb', line 77

def self.add_server_appenders
  options = Rails.application.config.rails_semantic_logger
  # Backward compatibility
  if !options.appenders? && options.console_logger && !SemanticLogger.appenders.console_output?
    SemanticLogger.add_appender(io: $stdout, formatter: :color)
  end

  options.appenders.server.each do |args, block|
    SemanticLogger.add_appender(**args, &block)
  end
end

.deprecatorObject

Deprecator used for options that are being phased out in favor of declaring appenders directly (see RailsSemanticLogger::Appenders).



45
46
47
# File 'lib/rails_semantic_logger.rb', line 45

def self.deprecator
  @deprecator ||= ActiveSupport::Deprecation.new("6.0", "rails_semantic_logger")
end

.swap_subscriber(old_class, new_class, notifier) ⇒ Object

Swap an existing subscriber with a new one



118
119
120
121
122
123
# File 'lib/rails_semantic_logger.rb', line 118

def self.swap_subscriber(old_class, new_class, notifier)
  subscribers = ActiveSupport::LogSubscriber.subscribers.select { |s| s.is_a?(old_class) }
  subscribers.each { |subscriber| unattach(subscriber) }

  new_class.attach_to(notifier)
end

.warn_initialized_too_late(setting, config_initializers_too_late: true) ⇒ Object

Warn that a setting was changed too late to take effect, so the change has no effect. When config_initializers_too_late is true (the default), the setting is consumed while the logger is built, before config/initializers/* is loaded, so that location is called out as too late. When false, the setting is consumed at the end of initialization (config/initializers/* still works) and only a change after the application has booted is too late.



55
56
57
58
59
60
61
62
63
64
# File 'lib/rails_semantic_logger.rb', line 55

def self.warn_initialized_too_late(setting, config_initializers_too_late: true)
  env       = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : "<env>"
  locations = "`config/application.rb` or `config/environments/#{env}.rb`"
  locations += " (or a `config/initializers/*` file)" unless config_initializers_too_late
  suffix    = config_initializers_too_late ? "; `config/initializers/*` is loaded too late." : "."
  warn(
    "[rails_semantic_logger] `config.rails_semantic_logger.#{setting}` was set too late to take " \
    "effect, so it has no effect. Set it in #{locations}#{suffix}"
  )
end