From 6c126015a676c376f1646713fbb739049a783238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:26:56 +0200 Subject: Ensure TaggegLogging is thread safe. --- activesupport/lib/active_support/tagged_logging.rb | 35 ++++++++++++++-------- activesupport/test/tagged_logging_test.rb | 30 ++++++++++++++++++- 2 files changed, 51 insertions(+), 14 deletions(-) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb index 0cabb528ef..aff416a9eb 100644 --- a/activesupport/lib/active_support/tagged_logging.rb +++ b/activesupport/lib/active_support/tagged_logging.rb @@ -13,20 +13,20 @@ module ActiveSupport class TaggedLogging def initialize(logger) @logger = logger - @tags = [] + @tags = Hash.new { |h,k| h[k] = [] } end - def tagged(*tags) - new_tags = Array.wrap(tags).flatten - @tags += new_tags + def tagged(*new_tags) + tags = current_tags + new_tags = Array.wrap(new_tags).flatten + tags.concat new_tags yield ensure - new_tags.size.times { @tags.pop } + new_tags.size.times { tags.pop } end - def add(severity, message = nil, progname = nil, &block) - @logger.add(severity, "#{tags}#{message}", progname, &block) + @logger.add(severity, "#{tags_text}#{message}", progname, &block) end %w( fatal error warn info debug unkown ).each do |severity| @@ -37,17 +37,26 @@ module ActiveSupport EOM end + def flush(*args) + @tags.delete(Thread.current) + @logger.flush(*args) if @logger.respond_to?(:flush) + end def method_missing(method, *args) @logger.send(method, *args) end - - private - def tags - if @tags.any? - @tags.collect { |tag| "[#{tag}]" }.join(" ") + " " - end + protected + + def tags_text + tags = current_tags + if tags.any? + tags.collect { |tag| "[#{tag}]" }.join(" ") + " " end + end + + def current_tags + @tags[Thread.current] + end end end diff --git a/activesupport/test/tagged_logging_test.rb b/activesupport/test/tagged_logging_test.rb index a1504c6ce4..b12b12f32c 100644 --- a/activesupport/test/tagged_logging_test.rb +++ b/activesupport/test/tagged_logging_test.rb @@ -3,9 +3,15 @@ require 'active_support/core_ext/logger' require 'active_support/tagged_logging' class TaggedLoggingTest < ActiveSupport::TestCase + class MyLogger < ::Logger + def flush(*) + info "[FLUSHED]" + end + end + setup do @output = StringIO.new - @logger = ActiveSupport::TaggedLogging.new(Logger.new(@output)) + @logger = ActiveSupport::TaggedLogging.new(MyLogger.new(@output)) end test "tagged once" do @@ -23,6 +29,28 @@ class TaggedLoggingTest < ActiveSupport::TestCase assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string end + test "keeps each tag in their own thread" do + @logger.tagged("BCX") do + Thread.new do + @logger.tagged("OMG") { @logger.info "Cool story bro" } + end.join + @logger.info "Funky time" + end + assert_equal "[OMG] Cool story bro\n[BCX] Funky time\n", @output.string + end + + test "cleans up the taggings on flush" do + @logger.tagged("BCX") do + Thread.new do + @logger.tagged("OMG") do + @logger.flush + @logger.info "Cool story bro" + end + end.join + end + assert_equal "[FLUSHED]\nCool story bro\n", @output.string + end + test "mixed levels of tagging" do @logger.tagged("BCX") do @logger.tagged("Jason") { @logger.info "Funky time" } -- cgit v1.2.3