# frozen_string_literal: true require 'getaround_utils/ougai/json_formatter' require 'request_store' require 'rails/railtie' require 'ougai' module GetaroundUtils; end module GetaroundUtils::Railties; end # Rails-compatible Ougai Logger # https://github.com/tilfin/ougai/wiki/Use-as-Rails-logger#define-a-custom-logger class OugaiRailsLogger < Ougai::Logger include ActiveSupport::LoggerThreadSafeLevel include Rails::VERSION::MAJOR < 6 ? LoggerSilence : ActiveSupport::LoggerSilence end # Patch for ActiveSupport::TaggedLogging # https://github.com/tilfin/ougai/wiki/Use-as-Rails-logger#with-activesupporttaggedlogging module OugaiTaggedLoggingFormatter def call(severity, time, progname, data) if is_a?(Ougai::Formatters::Base) data = { msg: data.to_s } unless data.is_a?(Hash) data[:tags] = current_tags if current_tags.any? _call(severity, time, progname, data) else super end end end # Custom middleware to persist request metadatas # https://github.com/tilfin/ougai/issues/73#issuecomment-475866224 # https://github.com/tilfin/ougai/issues/107#issuecomment-636050223 class OugaiRequestStoreMiddleware def initialize(app) @app = app end def call(env) RequestStore.store[:ougai] = { http: { request_id: env['action_dispatch.request_id'] } } @app.call(env) end end class GetaroundUtils::Railties::Ougai < Rails::Railtie config.ougai_logger = OugaiRailsLogger.new($stdout) config.ougai_logger.after_initialize if Rails::VERSION::MAJOR < 6 config.ougai_logger.formatter = GetaroundUtils::Ougai::JsonFormatter.new config.ougai_logger.before_log = lambda do |data| request_store = RequestStore.store[:ougai] || {} data.deep_merge!(request_store) if request_store&.any? sidekiq_context = Thread.current[:sidekiq_context] || {} data.merge!(sidekiq: sidekiq_context) if sidekiq_context&.any? end initializer :getaround_utils_ougai, before: :initialize_logger do |app| app.config.logger = config.ougai_logger end initializer :getaround_utils_ougai_middleware do |app| app.config.app_middleware.insert_after ActionDispatch::RequestId, OugaiRequestStoreMiddleware end initializer :getaround_utils_ougai_activesupport do ActiveSupport::TaggedLogging::Formatter.prepend OugaiTaggedLoggingFormatter end initializer :getaround_utils_ougai_lograge do |app| next unless defined?(Lograge) app.config.lograge.logger = app.config.logger app.config.lograge.formatter = Lograge::Formatters::Raw.new end initializer :getaround_utils_ougai_sidekiq do next unless defined?(Sidekiq) # https://github.com/tilfin/ougai/wiki/Customize-Sidekiq-logger Sidekiq.logger = config.ougai_logger Sidekiq.configure_server do |config| original_handler = config.error_handlers.shift config.error_handlers << lambda do |ex, ctx| if Sidekiq.logger.is_a?(Ougai::Logger) Sidekiq.logger.warn(ex, job: ctx[:job]) else original_handler.call(ex, ctx) end end end end end