diff --git a/lib/gelf/logger.rb b/lib/gelf/logger.rb index 7025dc2..02e8801 100644 --- a/lib/gelf/logger.rb +++ b/lib/gelf/logger.rb @@ -2,7 +2,7 @@ module GELF # Methods for compatibility with Ruby Logger. module LoggerCompatibility - attr_accessor :formatter + attr_accessor :formatter, :log_tags # Use it like Logger#add... or better not to use at all. def add(level, message = nil, progname = nil, &block) @@ -32,6 +32,11 @@ def add(level, message = nil, progname = nil, &block) message_hash.merge!(self.class.extract_hash_from_exception(message)) end + # Include tags in message hash + Array(log_tags).each_with_index do |tag_name, index| + message_hash.merge!("_#{tag_name}" => current_tags[index]) if current_tags[index] + end + notify_with_level(level, message_hash) end @@ -51,12 +56,35 @@ def #{const.downcase}? # def debug? def <<(message) notify_with_level(GELF::UNKNOWN, 'short_message' => message) end + + def tagged(*tags) + new_tags = push_tags(*tags) + yield self + ensure + current_tags.pop(new_tags.size) + end + + def push_tags(*tags) + tags.flatten.reject{ |t| t.respond_to?(:empty?) ? !!t.empty? : !t }.tap do |new_tags| + current_tags.concat new_tags + end + end + + def current_tags + Thread.current[:gelf_tagged_logging_tags] ||= [] + end end # Graylog2 notifier, compatible with Ruby Logger. # You can use it with Rails like this: # config.logger = GELF::Logger.new("localhost", 12201, "WAN", { :facility => "appname" }) # config.colorize_logging = false + # + # Tagged logging (with tags from rack middleware) (order of tags is important) + # Adds custom gelf messages: { '_uuid_name' => , '_remote_ip_name' => } + # config.logger = GELF::Logger.new("localhost", 12201, "LAN", { :facility => "appname" }) + # config.log_tags = [:uuid, :remote_ip] + # config.logger.log_tags = [:uuid_name, :remote_ip_name] # Same order as config.log_tags class Logger < Notifier include LoggerCompatibility end diff --git a/test/test_logger.rb b/test/test_logger.rb index b4b793e..cd703b1 100644 --- a/test/test_logger.rb +++ b/test/test_logger.rb @@ -210,6 +210,38 @@ class TestLogger < Test::Unit::TestCase @logger.formatter end + context "#tagged" do + # logger.tagged("TAG") { logger.info "Message" } + should "support tagged method" do + @logger.expects(:notify_with_level!).with do |level, hash| + level == GELF::INFO && + hash['short_message'] == 'Message' && + hash['facility'] == 'gelf-rb' + end + + str = "TAG" + str.stubs(:blank?).returns(true) + + @logger.tagged(str) { @logger.info "Message" } + end + + should "set custom gelf message with tag name and tag content" do + # I want the first tag with name 'test_tag' + @logger.log_tags = [:test_tag] + + @logger.expects(:notify_with_level!).with do |level, hash| + level == GELF::INFO && + hash['short_message'] == 'Message' && + hash['facility'] == 'gelf-rb' && + hash['_test_tag'] == 'TAG' # TAG should be in the hash + end + + str = "TAG" + str.stubs(:blank?).returns(false) + + @logger.tagged(str) { @logger.info "Message" } + end + end context "close" do should "close socket" do