forked from rails/rails
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- ### Context The Tagged Logging functionality has been a source of a few issues over the years, especially when combined with the broadcasting feature. Initializating a Tagged Logger wasn't very intuitive: ```ruby logger = Logger.new(STDOUT) tagged_logger = ActiveSupport::TaggedLogging.new(logger) # Would expect the `tagged_logger` to be an instance of `AS::TaggedLogging` # but it's a clone of the `logger`. tagged_logger.formatter = ->(_, _, _, message) do { message: message } end # Modifies the formatter to output JSON formatted logs. # This breaks tagged logging. ``` I believe the main reason of those issues is because tagged logging is implemented at the wrong level. ### Solution I made a proposal on the Ruby logger upstream in ruby/logger#90 to help solve this but it hasn't been reviewed yet. So I thought about adding it here for now. The TL;DR is to decouple formatting and adding extra information to logs (which is what tagged logging does). ### Deprecation Since TaggedLogging will no longer access the formatter, there is a few things I'd like to deprecate (such as setting a default formatter https://github.com/rails/rails/blob/d68e43922bc11829c52ad9f736ad5549fc97631b/activesupport/lib/active_support/tagged_logging.rb#L124) but doing so in this PR would increase the size of the diff significantly and would maybe distract for PR reviews. Another thing that I believe should be deprecated is `ActiveSupport::TaggedLogging.new`. Adding tagging functionality to a logger should be done using a more ruby approach such as `logger.extend(AS::TaggedLogging)`. Fix rails#49757 Fix rails#49745 Fix rails#46084 Fix rails#44668 I made a propose on the Ruby logger upstream in ruby/logger#90, but it hasn't been reviewed it.
- Loading branch information
1 parent
ca5132b
commit 0f6da08
Showing
8 changed files
with
310 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# frozen_string_literal: true | ||
|
||
module ActiveSupport | ||
module LogProcessor # :nodoc: | ||
attr_accessor :processors | ||
|
||
def self.extended(base) | ||
base.processors = [] | ||
end | ||
|
||
def initialize(*args, **kwargs) | ||
super | ||
|
||
self.processors = [] | ||
end | ||
|
||
private | ||
def format_message(severity, datetime, progname, msg) | ||
processors.flatten.reverse_each do |processor| | ||
msg = processor.call(msg, self) | ||
end | ||
|
||
super(severity, datetime, progname, msg) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "abstract_unit" | ||
|
||
class LogBroadcastAndTaggingTest < ActiveSupport::TestCase | ||
setup do | ||
@sink1 = StringIO.new | ||
@sink2 = StringIO.new | ||
@logger1 = Logger.new(@sink1, formatter: ActiveSupport::Logger::SimpleFormatter.new) | ||
@logger2 = Logger.new(@sink2, formatter: ActiveSupport::Logger::SimpleFormatter.new) | ||
|
||
@broadcast = ActiveSupport::BroadcastLogger.new | ||
@broadcast.broadcast_to(@logger1, @logger2) | ||
end | ||
|
||
test "tag logs for the whole broadcast with a block" do | ||
@broadcast.tagged("BMX") { @broadcast.info("Hello") } | ||
|
||
assert_equal("[BMX] Hello\n", @sink1.string) | ||
assert_equal("[BMX] Hello\n", @sink2.string) | ||
end | ||
|
||
test "tag logs for the whole broadcast without a block" do | ||
@broadcast.tagged("BMX").info("Hello") | ||
|
||
assert_equal("[BMX] Hello\n", @sink1.string) | ||
assert_equal("[BMX] Hello\n", @sink2.string) | ||
|
||
@sink1.reopen | ||
@sink2.reopen | ||
@broadcast.info("Hello") | ||
|
||
assert_equal("Hello\n", @sink1.string) | ||
assert_equal("Hello\n", @sink2.string) | ||
end | ||
|
||
test "tag logs only for one sink" do | ||
@logger1.extend(ActiveSupport::TaggedLogging) | ||
@logger1.push_tags("BMX") | ||
|
||
@broadcast.info { "Hello" } | ||
|
||
assert_equal("[BMX] Hello\n", @sink1.string) | ||
assert_equal("Hello\n", @sink2.string) | ||
end | ||
|
||
test "tag logs for multiple sinks" do | ||
@logger1.extend(ActiveSupport::TaggedLogging) | ||
@logger1.push_tags("BMX") | ||
|
||
@logger2.extend(ActiveSupport::TaggedLogging) | ||
@logger2.push_tags("APP") | ||
|
||
@broadcast.info { "Hello" } | ||
|
||
assert_equal("[BMX] Hello\n", @sink1.string) | ||
assert_equal("[APP] Hello\n", @sink2.string) | ||
end | ||
|
||
test "tag logs for the whole broadcast and extra tags are added to one sink (block version)" do | ||
@logger1.extend(ActiveSupport::TaggedLogging) | ||
@logger1.push_tags("APP1") | ||
|
||
@logger2.extend(ActiveSupport::TaggedLogging) | ||
@logger2.push_tags("APP2") | ||
|
||
@broadcast.tagged("BMX") { @broadcast.info("Hello") } | ||
|
||
assert_equal("[BMX] [APP1] Hello\n", @sink1.string) | ||
assert_equal("[BMX] [APP2] Hello\n", @sink2.string) | ||
end | ||
|
||
test "tag logs for the whole broadcast and extra tags are added to one sink (non-block version)" do | ||
@logger1.extend(ActiveSupport::TaggedLogging) | ||
@logger1.push_tags("APP1") | ||
|
||
@logger2.extend(ActiveSupport::TaggedLogging) | ||
@logger2.push_tags("APP2") | ||
|
||
@broadcast.tagged("BMX").info("Hello") | ||
|
||
assert_equal("[BMX] [APP1] Hello\n", @sink1.string) | ||
assert_equal("[BMX] [APP2] Hello\n", @sink2.string) | ||
|
||
@sink1.reopen | ||
@sink2.reopen | ||
@broadcast.info("Hello") | ||
|
||
assert_equal("[APP1] Hello\n", @sink1.string) | ||
assert_equal("[APP2] Hello\n", @sink2.string) | ||
end | ||
|
||
test "can broadcast to another broadcast logger with tagging functionalities" do | ||
@sink3 = StringIO.new | ||
@sink4 = StringIO.new | ||
@logger3 = Logger.new(@sink3, formatter: ActiveSupport::Logger::SimpleFormatter.new) | ||
@logger4 = Logger.new(@sink4, formatter: ActiveSupport::Logger::SimpleFormatter.new) | ||
@broadcast2 = ActiveSupport::BroadcastLogger.new | ||
|
||
@broadcast2.broadcast_to(@logger3, @logger4) | ||
@broadcast.broadcast_to(@broadcast2) | ||
|
||
@broadcast2.push_tags("BROADCAST2") | ||
|
||
@broadcast.tagged("BMX") { @broadcast.info("Hello") } | ||
|
||
assert_equal("[BMX] Hello\n", @sink1.string) | ||
assert_equal("[BMX] Hello\n", @sink2.string) | ||
assert_equal("[BMX] [BROADCAST2] Hello\n", @sink3.string) | ||
assert_equal("[BMX] [BROADCAST2] Hello\n", @sink4.string) | ||
end | ||
|
||
test "#silence works while broadcasting to tagged loggers" do | ||
my_logger = Class.new(::Logger) do | ||
include ActiveSupport::LoggerSilence | ||
end | ||
|
||
logger1_io = StringIO.new | ||
logger2_io = StringIO.new | ||
|
||
logger1 = my_logger.new(logger1_io).extend(ActiveSupport::TaggedLogging) | ||
logger2 = my_logger.new(logger2_io).extend(ActiveSupport::TaggedLogging) | ||
|
||
broadcast = ActiveSupport::BroadcastLogger.new(logger1, logger2) | ||
|
||
broadcast.tagged("TEST") do | ||
broadcast.silence do | ||
broadcast.info("Silenced") | ||
end | ||
|
||
broadcast.info("Not silenced") | ||
end | ||
|
||
assert_equal("[TEST] Not silenced\n", logger1_io.string) | ||
assert_equal("[TEST] Not silenced\n", logger2_io.string) | ||
end | ||
end |
Oops, something went wrong.