Skip to content
This repository was archived by the owner on Jan 29, 2025. It is now read-only.

Commit d7f194c

Browse files
dsawamarkglennmilgnerMeat-Chopper
authored
Feature/tagged logging (#1) (#2)
* Add tagged logging support Implement tagged logging similar to ActiveSupport::TaggedLogging. * Use log_tags attribute on logger Don't use the default_options to pass the tags into the logger. This causes the tags field to be sent over to graylog as an array. Instead pass the tag names into an attribute called log_tags that matches with the Rails standard of config.log_tags. * Replace Thread#[] with Thread#thread_variable_get/set * Skip log tags tests for Ruby 1.9 * Fix CI for JRuby Co-authored-by: Mark Glenn <[email protected]> Co-authored-by: Marcus Ilgner <[email protected]> Co-authored-by: Vladimir Kitaev <[email protected]> Co-authored-by: Mark Glenn <[email protected]> Co-authored-by: Marcus Ilgner <[email protected]> Co-authored-by: Vladimir Kitaev <[email protected]>
1 parent eb2d31c commit d7f194c

File tree

3 files changed

+69
-6
lines changed

3 files changed

+69
-6
lines changed

Gemfile.lock

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,3 @@ DEPENDENCIES
6969
rack (< 2.0)
7070
shoulda (~> 2.11.3)
7171
test-unit (~> 3.2.0)
72-
73-
BUNDLED WITH
74-
1.14.6

lib/gelf/logger.rb

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module GELF
22
# Methods for compatibility with Ruby Logger.
33
module LoggerCompatibility
44

5-
attr_accessor :formatter
5+
attr_accessor :formatter, :log_tags
66

77
# Use it like Logger#add... or better not to use at all.
88
def add(level, message = nil, progname = nil, &block)
@@ -28,9 +28,14 @@ def add(level, message = nil, progname = nil, &block)
2828
message_hash.merge!(self.class.extract_hash_from_exception(message))
2929
end
3030

31-
if message_hash.key?('short_message') && !message_hash['short_message'].empty?
32-
notify_with_level(level, message_hash)
31+
return if !message_hash.key?('short_message') || message_hash['short_message'].empty?
32+
33+
# Include tags in message hash
34+
Array(log_tags).each_with_index do |tag_name, index|
35+
message_hash.merge!("_#{tag_name}" => current_tags[index]) if current_tags[index]
3336
end
37+
38+
notify_with_level(level, message_hash)
3439
end
3540

3641
# Redefines methods in +Notifier+.
@@ -51,12 +56,37 @@ def add(level, message = nil, progname = nil, &block)
5156
def <<(message)
5257
notify_with_level(GELF::UNKNOWN, 'short_message' => message)
5358
end
59+
60+
def tagged(*tags)
61+
new_tags = push_tags(*tags)
62+
yield self
63+
ensure
64+
current_tags.pop(new_tags.size)
65+
end
66+
67+
def push_tags(*tags)
68+
tags.flatten.reject{ |t| t.respond_to?(:empty?) ? !!t.empty? : !t }.tap do |new_tags|
69+
current_tags.concat new_tags
70+
end
71+
end
72+
73+
def current_tags
74+
val = Thread.current.thread_variable_get(:gelf_tagged_logging_tags)
75+
return val unless val.nil?
76+
Thread.current.thread_variable_set(:gelf_tagged_logging_tags, [])
77+
end
5478
end
5579

5680
# Graylog2 notifier, compatible with Ruby Logger.
5781
# You can use it with Rails like this:
5882
# config.logger = GELF::Logger.new("localhost", 12201, "WAN", { :facility => "appname" })
5983
# config.colorize_logging = false
84+
#
85+
# Tagged logging (with tags from rack middleware) (order of tags is important)
86+
# Adds custom gelf messages: { '_uuid_name' => <uuid>, '_remote_ip_name' => <remote_ip> }
87+
# config.logger = GELF::Logger.new("localhost", 12201, "LAN", { :facility => "appname" })
88+
# config.log_tags = [:uuid, :remote_ip]
89+
# config.logger.log_tags = [:uuid_name, :remote_ip_name] # Same order as config.log_tags
6090
class Logger < Notifier
6191
include LoggerCompatibility
6292
end

test/test_logger.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,42 @@ class TestLogger < Test::Unit::TestCase
237237
@logger.formatter
238238
end
239239

240+
# Supports only Ruby 2.0 or higher
241+
if RUBY_VERSION[0, 1].to_i >= 2
242+
context "#tagged" do
243+
# logger.tagged("TAG") { logger.info "Message" }
244+
should "support tagged method" do
245+
@logger.expects(:notify_with_level!).with do |level, hash|
246+
level == GELF::INFO &&
247+
hash['short_message'] == 'Message' &&
248+
hash['facility'] == 'gelf-rb'
249+
end
250+
251+
str = "TAG"
252+
str.stubs(:blank?).returns(true)
253+
254+
@logger.tagged(str) { @logger.info "Message" }
255+
end
256+
257+
should "set custom gelf message with tag name and tag content" do
258+
# I want the first tag with name 'test_tag'
259+
@logger.log_tags = [:test_tag]
260+
261+
@logger.expects(:notify_with_level!).with do |level, hash|
262+
level == GELF::INFO &&
263+
hash['short_message'] == 'Message' &&
264+
hash['facility'] == 'gelf-rb' &&
265+
hash['_test_tag'] == 'TAG' # TAG should be in the hash
266+
end
267+
268+
str = "TAG"
269+
str.stubs(:blank?).returns(false)
270+
271+
@logger.tagged(str) { @logger.info "Message" }
272+
end
273+
end
274+
end
275+
240276
context "close" do
241277
should "close socket" do
242278
@sender.expects(:close).once

0 commit comments

Comments
 (0)