Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tagged logging support #35

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion lib/gelf/logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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] ||= []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience it's slightly safer to use thread_variable_set / thread_variable_get.

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' => <uuid>, '_remote_ip_name' => <remote_ip> }
# 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
Expand Down
32 changes: 32 additions & 0 deletions test/test_logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down