From a140eb0629b99aba07ce07c2d303b5623a87fa84 Mon Sep 17 00:00:00 2001 From: Dan Willoughby Date: Mon, 23 Sep 2024 07:30:22 -0600 Subject: [PATCH] feat: support broadcast logger for rails 7.1 (#23522) --- .../lib/google/cloud/logging/logger.rb | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/google-cloud-logging/lib/google/cloud/logging/logger.rb b/google-cloud-logging/lib/google/cloud/logging/logger.rb index dbe7a1009ce2..cf216a795ed0 100644 --- a/google-cloud-logging/lib/google/cloud/logging/logger.rb +++ b/google-cloud-logging/lib/google/cloud/logging/logger.rb @@ -96,7 +96,7 @@ class Logger ## # This logger does not use a formatter, but it provides a default # Logger::Formatter for API compatibility with the standard Logger. - attr_accessor :formatter + attr_reader :formatter ## # This logger does not use a formatter, but it implements this @@ -108,6 +108,11 @@ class Logger # used to set the trace field of log entries. attr_accessor :project + ## + + attr_reader :broadcasts + + ## # This logger treats progname as an alias for log_name. def progname= name @@ -178,12 +183,38 @@ def initialize writer, log_name, resource, labels = nil @formatter = ::Logger::Formatter.new @datetime_format = "" @silencer = true + @broadcasts = [] # The writer is usually a Project or AsyncWriter. logging = @writer.respond_to?(:logging) ? @writer.logging : @writer @project = logging.project if logging.respond_to? :project end + # Add logger(s) to the broadcast. + # + # broadcast_logger = ActiveSupport::BroadcastLogger.new + # broadcast_logger.broadcast_to(Logger.new(STDOUT), Logger.new(STDERR)) + def broadcast_to(*loggers) + @broadcasts.concat loggers + end + + # Remove a logger from the broadcast. When a logger is removed, messages sent to + # the broadcast will no longer be written to its sink. + # + # sink = Logger.new(STDOUT) + # broadcast_logger = ActiveSupport::BroadcastLogger.new + # + # broadcast_logger.stop_broadcasting_to(sink) + def stop_broadcasting_to logger + @broadcasts.delete logger + end + + def formatter= formatter + dispatch { |logger| logger.formatter = formatter } + + @formatter = formatter + end + ## # Log a `DEBUG` entry. # @@ -307,7 +338,7 @@ def unknown message = nil, &block # to create potentially expensive logging messages that are only # called when the logger is configured to show them. # - def add severity, message = nil, progname = nil + def add severity, message = nil, progname = nil, &block return if @closed severity = derive_severity(severity) || ::Logger::UNKNOWN @@ -317,6 +348,7 @@ def add severity, message = nil, progname = nil # TODO: Figure out what to do with the progname write_entry severity, message unless @closed + dispatch { |logger| logger.add(severity, message, progname, &block) } true end alias log add @@ -335,6 +367,8 @@ def << msg # Returns `true` if the current severity level allows for sending # `DEBUG` messages. def debug? + @broadcasts.any?(&:debug?) + @level <= ::Logger::DEBUG end @@ -342,6 +376,7 @@ def debug? # Returns `true` if the current severity level allows for sending `INFO` # messages. def info? + @broadcasts.any?(&:info?) @level <= ::Logger::INFO end @@ -349,6 +384,7 @@ def info? # Returns `true` if the current severity level allows for sending `WARN` # messages. def warn? + @broadcasts.any?(&:warn?) @level <= ::Logger::WARN end @@ -356,6 +392,7 @@ def warn? # Returns `true` if the current severity level allows for sending # `ERROR` messages. def error? + @broadcasts.any?(&:error?) @level <= ::Logger::ERROR end @@ -363,6 +400,7 @@ def error? # Returns `true` if the current severity level allows for sending # `FATAL` messages. def fatal? + @broadcasts.any?(&:fatal?) @level <= ::Logger::FATAL end @@ -370,6 +408,7 @@ def fatal? # Returns `true` if the current severity level allows for sending # `UNKNOWN` messages. def unknown? + @broadcasts.any?(&:unknown?) @level <= ::Logger::UNKNOWN end @@ -398,10 +437,21 @@ def level= severity if new_level.nil? raise ArgumentError, "invalid log level: #{severity}" end + dispatch { |logger| logger.level = new_level } @level = new_level end alias sev_threshold= level= - alias local_level= level= + + def local_level= severity + new_level = derive_severity severity + if new_level.nil? + raise ArgumentError, "invalid log level: #{severity}" + end + dispatch do |logger| + logger.local_level = new_level if logger.respond_to? :local_level= + end + @level = new_level + end ## # Close the logging "device". This effectively disables logging from @@ -409,6 +459,8 @@ def level= severity # logger may be re-enabled by calling #reopen. # def close + dispatch(&:close) + @closed = true self end @@ -601,6 +653,11 @@ def current_thread_id private + def dispatch &block + @broadcasts.each { |logger| block.call logger } + true + end + ## # @private Compute values for labels def compute_labels request_env