semantic_logger 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/FUTURE.rb
CHANGED
@@ -1,9 +1,4 @@
|
|
1
1
|
|
2
|
-
# Return the logger for a specific class, supports class specific log levels
|
3
|
-
# Clarity::Logger.logger(MyClass)
|
4
|
-
# # OR
|
5
|
-
# Clarity::Logger.logger('MyClass')
|
6
|
-
#
|
7
2
|
# # Switch to slf4j as the underlying implementation
|
8
3
|
# Clarity::Logger.impl = slf4j
|
9
4
|
#
|
@@ -14,13 +9,6 @@
|
|
14
9
|
#
|
15
10
|
#
|
16
11
|
#
|
17
|
-
# # Thread specific context information to be logged with every log entry
|
18
|
-
# #
|
19
|
-
# # Add metadata information within a block to all log calls on This Thread
|
20
|
-
# logger.with_metadata(:tracking_number=>12345) do
|
21
|
-
# # Any log entries within this block will have this metadata added to it
|
22
|
-
# logger.debug('Hello World', :result => 'blah')
|
23
|
-
# end
|
24
12
|
#
|
25
13
|
# # If a block cannot be used to set the scope of context
|
26
14
|
# # Set global metadata for every log entry on this machine
|
@@ -41,6 +41,8 @@ module SemanticLogger
|
|
41
41
|
def default_formatter
|
42
42
|
Proc.new do |log|
|
43
43
|
message = log.message.to_s
|
44
|
+
tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
|
45
|
+
|
44
46
|
if log.payload
|
45
47
|
if log.payload.is_a?(Exception)
|
46
48
|
exception = log.payload
|
@@ -50,8 +52,9 @@ module SemanticLogger
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
str = "#{log.time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%03d" % (log.time.usec/1000)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{log.name} -- #{message}
|
55
|
+
str = "#{log.time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%03d" % (log.time.usec/1000)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}"
|
54
56
|
str << " (#{'%.1f' % log.duration}ms)" if log.duration
|
57
|
+
str << "\n"
|
55
58
|
str
|
56
59
|
end
|
57
60
|
end
|
@@ -12,8 +12,8 @@ module SemanticLogger
|
|
12
12
|
# level : 'trace|debug|warn|info|error',
|
13
13
|
# message : "blah blah",
|
14
14
|
# duration : ms, # Set by Logger#benchmark
|
15
|
-
#
|
16
|
-
#
|
15
|
+
# tags : "Some tracking id" | ["id1", "id2"]
|
16
|
+
# payload : {
|
17
17
|
# Optional. Any user supplied data, including any thread specific context variables
|
18
18
|
# values supplied on a per log entry will override any thread context values
|
19
19
|
# }
|
@@ -53,7 +53,13 @@ module SemanticLogger
|
|
53
53
|
|
54
54
|
@@default_level = :info
|
55
55
|
|
56
|
-
#
|
56
|
+
# Returns a Logger instance
|
57
|
+
#
|
58
|
+
# Return the logger for a specific class, supports class specific log levels
|
59
|
+
# logger = SemanticLogger::Logger.new(self)
|
60
|
+
# OR
|
61
|
+
# logger = SemanticLogger::Logger.new('MyClass')
|
62
|
+
#
|
57
63
|
# Parameters:
|
58
64
|
# application: A class, module or a string with the application/class name
|
59
65
|
# to be used in the logger
|
@@ -94,10 +100,14 @@ module SemanticLogger
|
|
94
100
|
if result.is_a?(String)
|
95
101
|
message = message.nil? ? result : "\#{message} -- \#{result.to_s}"
|
96
102
|
else
|
97
|
-
payload = payload.nil? ?
|
103
|
+
payload = payload.nil? ? result : payload.merge(result)
|
98
104
|
end
|
99
105
|
end
|
100
|
-
|
106
|
+
# Add scoped payload
|
107
|
+
if self.payload
|
108
|
+
payload = payload.nil? ? self.payload : self.payload.merge(payload)
|
109
|
+
end
|
110
|
+
self.class.queue << Log.new(:#{level}, self.class.thread_name, name, message, payload, Time.now, nil, tags)
|
101
111
|
true
|
102
112
|
else
|
103
113
|
false
|
@@ -117,10 +127,15 @@ module SemanticLogger
|
|
117
127
|
start = Time.now
|
118
128
|
begin
|
119
129
|
result = yield
|
120
|
-
|
130
|
+
# Add scoped payload
|
131
|
+
if self.payload
|
132
|
+
payload = payload.nil? ? self.payload : self.payload.merge(payload)
|
133
|
+
end
|
134
|
+
self.class.queue << Log.new(:#{level}, self.class.thread_name, name, message, payload, start, Time.now - start, tags)
|
121
135
|
result
|
122
136
|
rescue Exception => exc
|
123
|
-
|
137
|
+
# TODO Need to be able to have both an exception and a Payload
|
138
|
+
self.class.queue << Log.new(:#{level}, self.class.thread_name, name, message, exc, start, Time.now - start, tags)
|
124
139
|
raise exc
|
125
140
|
end
|
126
141
|
else
|
@@ -130,6 +145,55 @@ module SemanticLogger
|
|
130
145
|
EOT
|
131
146
|
end
|
132
147
|
|
148
|
+
# Add the supplied tags to the list of tags to log for this thread whilst
|
149
|
+
# the supplied block is active
|
150
|
+
# Returns nil if no tags are currently set
|
151
|
+
def with_tags(*tags)
|
152
|
+
current_tags = self.tags
|
153
|
+
# Check for nil tags
|
154
|
+
if tags
|
155
|
+
Thread.current[:semantic_logger_tags] = current_tags ? current_tags + tags : tags
|
156
|
+
end
|
157
|
+
yield
|
158
|
+
ensure
|
159
|
+
Thread.current[:semantic_logger_tags] = current_tags
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns [Array] of [String] tags currently active for this thread
|
163
|
+
# Returns nil if no tags are set
|
164
|
+
def tags
|
165
|
+
Thread.current[:semantic_logger_tags]
|
166
|
+
end
|
167
|
+
|
168
|
+
# Thread specific context information to be logged with every log entry
|
169
|
+
#
|
170
|
+
# Add a payload to all log calls on This Thread within the supplied block
|
171
|
+
#
|
172
|
+
# logger.with_payload(:tracking_number=>12345) do
|
173
|
+
# logger.debug('Hello World')
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
# If a log call already includes a pyload, this payload will be merged with
|
177
|
+
# the supplied payload, with the supplied payload taking precedence
|
178
|
+
#
|
179
|
+
# logger.with_payload(:tracking_number=>12345) do
|
180
|
+
# logger.debug('Hello World', :result => 'blah')
|
181
|
+
# end
|
182
|
+
def with_payload(payload)
|
183
|
+
current_payload = self.payload
|
184
|
+
Thread.current[:semantic_logger_payload] = current_payload ? current_payload.merge(payload) : payload
|
185
|
+
yield
|
186
|
+
ensure
|
187
|
+
Thread.current[:semantic_logger_payload] = current_payload
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns [Hash] payload to be added to every log entry in the current scope
|
191
|
+
# on this thread.
|
192
|
+
# Returns nil if no payload is currently set
|
193
|
+
def payload
|
194
|
+
Thread.current[:semantic_logger_payload]
|
195
|
+
end
|
196
|
+
|
133
197
|
# Semantic Logging does not support :unknown level since these
|
134
198
|
# are not understood by the majority of the logging providers
|
135
199
|
# Map it to :error
|
@@ -187,7 +251,7 @@ module SemanticLogger
|
|
187
251
|
Queue.new
|
188
252
|
end
|
189
253
|
|
190
|
-
Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration)
|
254
|
+
Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags)
|
191
255
|
|
192
256
|
# For JRuby include the Thread name rather than its id
|
193
257
|
if defined? Java
|
@@ -23,15 +23,31 @@ module SemanticLogger #:nodoc:
|
|
23
23
|
#
|
24
24
|
# Loaded after Rails logging is initialized since SemanticLogger will continue
|
25
25
|
# to forward logging to the Rails Logger
|
26
|
-
initializer :initialize_semantic_logger, :
|
26
|
+
initializer :initialize_semantic_logger, :before => :initialize_logger do
|
27
27
|
config = Rails.application.config
|
28
28
|
|
29
|
-
|
29
|
+
logger = Rails.logger || config.logger || begin
|
30
|
+
path = config.paths.log.to_a.first
|
31
|
+
logger = ActiveSupport::BufferedLogger.new(path)
|
32
|
+
logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
|
33
|
+
logger.auto_flushing = false if Rails.env.production?
|
34
|
+
logger
|
35
|
+
rescue StandardError => e
|
36
|
+
logger = ActiveSupport::BufferedLogger.new(STDERR)
|
37
|
+
logger.level = ActiveSupport::BufferedLogger::WARN
|
38
|
+
logger.warn(
|
39
|
+
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
|
40
|
+
"The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
|
41
|
+
)
|
42
|
+
logger
|
43
|
+
end
|
44
|
+
|
45
|
+
# First set the internal logger to the default file one used by Rails in case something goes wrong
|
30
46
|
# with an appender
|
31
|
-
SemanticLogger::Logger.logger =
|
47
|
+
SemanticLogger::Logger.logger = logger
|
32
48
|
|
33
49
|
# Add the Rails Logger to the list of appenders
|
34
|
-
SemanticLogger::Logger.appenders << SemanticLogger::Appender::Logger.new(
|
50
|
+
SemanticLogger::Logger.appenders << SemanticLogger::Appender::Logger.new(logger)
|
35
51
|
|
36
52
|
# Set the default log level based on the Rails config
|
37
53
|
SemanticLogger::Logger.default_level = Rails.configuration.log_level
|
@@ -41,6 +57,10 @@ module SemanticLogger #:nodoc:
|
|
41
57
|
if defined?(ActiveRecord)
|
42
58
|
ActiveRecord::Base.logger = SemanticLogger::Logger.new(ActiveRecord)
|
43
59
|
end
|
60
|
+
if defined?(ActionController)
|
61
|
+
ActionController::Base.logger = SemanticLogger::Logger.new(ActionController)
|
62
|
+
end
|
63
|
+
SemanticLogger::Logger.logger.info "SemanticLogger initialized"
|
44
64
|
end
|
45
65
|
|
46
66
|
end
|
data/test/logger_test.rb
CHANGED
@@ -9,7 +9,6 @@ require 'semantic_logger'
|
|
9
9
|
require 'test/mock_logger'
|
10
10
|
|
11
11
|
# Unit Test for SemanticLogger::Logger
|
12
|
-
#
|
13
12
|
class LoggerTest < Test::Unit::TestCase
|
14
13
|
context SemanticLogger::Logger do
|
15
14
|
|
@@ -39,6 +38,36 @@ class LoggerTest < Test::Unit::TestCase
|
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
41
|
+
context "with_tags logging" do
|
42
|
+
should "add tags to log entries" do
|
43
|
+
@logger.with_tags('12345', 'DJHSFK') do
|
44
|
+
@logger.info('Hello world')
|
45
|
+
@logger.flush
|
46
|
+
assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world\n/, @mock_logger.message
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
should "add embedded tags to log entries" do
|
51
|
+
@logger.with_tags('First Level', 'tags') do
|
52
|
+
@logger.with_tags('Second Level') do
|
53
|
+
@logger.info('Hello world')
|
54
|
+
@logger.flush
|
55
|
+
assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \[First Level\] \[tags\] \[Second Level\] LoggerTest -- Hello world\n/, @mock_logger.message
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
should "add payload to log entries" do
|
61
|
+
@logger.with_payload(:tracking_number => '123456') do
|
62
|
+
@logger.with_payload(:more => 'data', :even => 2) do
|
63
|
+
@logger.info('Hello world')
|
64
|
+
@logger.flush
|
65
|
+
assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] LoggerTest -- Hello world -- \{:more=>\"data\", :even=>2, :tracking_number=>\"123456\"\}\n/, @mock_logger.message
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
42
71
|
end
|
43
72
|
|
44
73
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Reid Morrison
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-08-
|
17
|
+
date: 2012-08-21 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|