lib/temporalio/scoped_logger.rb
# frozen_string_literal: true require 'delegate' require 'logger' module Temporalio # Implementation via delegator to {::Logger} that puts scoped values on the log message and appends them to the log # message. class ScopedLogger < SimpleDelegator # @!attribute scoped_values_getter # @return [Proc, nil] Proc to call to get scoped values when needed. attr_accessor :scoped_values_getter # @!attribute scoped_values_getter # @return [Boolean] Whether the scoped value appending is disabled. attr_accessor :disable_scoped_values # @see Logger.add def add(severity, message = nil, progname = nil) return true if (severity || Logger::Unknown) < level return super if scoped_values_getter.nil? || @disable_scoped_values scoped_values = scoped_values_getter.call return super if scoped_values.nil? if message.nil? if block_given? message = yield else message = progname progname = nil end end # For exceptions we need to dup and append here, for everything else we # need to delegate to a log message new_message = if message.is_a?(Exception) message.exception("#{message.message} #{scoped_values}") else LogMessage.new(message, scoped_values) end super(severity, new_message, progname) end alias log add # @see Logger.debug def debug(progname = nil, &) add(Logger::DEBUG, nil, progname, &) end # @see Logger.info def info(progname = nil, &) add(Logger::INFO, nil, progname, &) end # @see Logger.warn def warn(progname = nil, &) add(Logger::WARN, nil, progname, &) end # @see Logger.error def error(progname = nil, &) add(Logger::ERROR, nil, progname, &) end # @see Logger.fatal def fatal(progname = nil, &) add(Logger::FATAL, nil, progname, &) end # @see Logger.unknown def unknown(progname = nil, &) add(Logger::UNKNOWN, nil, progname, &) end # Scoped log message wrapping original log message. class LogMessage # @return [Object] Original log message. attr_reader :message # @return [Object] Scoped values. attr_reader :scoped_values # @!visibility private def initialize(message, scoped_values) @message = message @scoped_values = scoped_values end # @return [String] Message with scoped values appended. def inspect message_str = message.is_a?(String) ? message : message.inspect "#{message_str} #{scoped_values}" end end end end