hatchet 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -5,7 +5,8 @@ filters.
5
5
 
6
6
  This README provides a brief overview of Hatchet, [see the main site for more complete documentation and tutorials](http://gshutler.github.com/hatchet/).
7
7
 
8
- [![Build Status](https://secure.travis-ci.org/gshutler/hatchet.png?branch=master)](http://travis-ci.org/gshutler/hatchet)
8
+ [![Build Status](https://secure.travis-ci.org/gshutler/hatchet.png?branch=master)](http://travis-ci.org/gshutler/hatchet)
9
+ [![Code Climate](https://codeclimate.com/github/gshutler/hatchet.png)](https://codeclimate.com/github/gshutler/hatchet)
9
10
 
10
11
  ## Installation
11
12
 
@@ -16,6 +16,7 @@ module Hatchet
16
16
  # Creates the levels Hash with a default logging level of info.
17
17
  #
18
18
  def initialize
19
+ @formatter = nil
19
20
  reset!
20
21
  end
21
22
 
@@ -79,57 +79,194 @@ module Hatchet
79
79
  @ndc = ndc
80
80
  end
81
81
 
82
- [:debug, :info, :warn, :error, :fatal].each do |level|
83
-
84
- # Public: Logs a message at the given level.
85
- #
86
- # message - An already evaluated message, usually a String (default: nil).
87
- # error - An error which is associated with the message (default: nil).
88
- # block - An optional block which will provide a message when invoked.
89
- #
90
- # One of message or block must be provided. If both are provided then the
91
- # block is preferred as it is assumed to provide more detail.
92
- #
93
- # In general, you should use the block style for any message not related
94
- # to an error. This is because any unneccessary String interpolation is
95
- # avoided making unwritten debug calls, for example, less expensive.
96
- #
97
- # When logging errors it is advised that you include some details of the
98
- # error within the regular message, perhaps the error's message, but leave
99
- # the inclusion of the stack trace up to your appenders and their
100
- # formatters.
101
- #
102
- # Examples
103
- #
104
- # debug { "A fine grained message" }
105
- # info { "An interesting message" }
106
- # warn { "A message worth highlighting" }
107
- # error "A message relating to an exception", e
108
- # fatal "A message causing application failure", e
109
- #
110
- # Returns nothing.
111
- #
112
- define_method level do |message = nil, error = nil, &block|
113
- return unless message or block
114
- add level, Message.new(ndc: @ndc.context.clone, message: message, error: error, &block)
115
- end
82
+ # Public: Logs a message at debug level.
83
+ #
84
+ # message - An already evaluated message, usually a String (default: nil).
85
+ # error - An error which is associated with the message (default: nil).
86
+ # block - An optional block which will provide a message when invoked.
87
+ #
88
+ # One of message or block must be provided. If both are provided then the
89
+ # block is preferred as it is assumed to provide more detail.
90
+ #
91
+ # In general, you should use the block style for any message not related
92
+ # to an error. This is because any unneccessary String interpolation is
93
+ # avoided making unwritten debug calls, for example, less expensive.
94
+ #
95
+ # When logging errors it is advised that you include some details of the
96
+ # error within the regular message, perhaps the error's message, but leave
97
+ # the inclusion of the stack trace up to your appenders and their
98
+ # formatters.
99
+ #
100
+ # Examples
101
+ #
102
+ # debug { "A fine grained message" }
103
+ # debug "A message relating to an exception", e
104
+ #
105
+ # Returns nothing.
106
+ #
107
+ def debug(message = nil, error = nil, &block)
108
+ add(:debug, message, error, &block)
109
+ end
116
110
 
117
- # Public: Returns true if any of the appenders will log messages for the
118
- # current context, otherwise returns false.
119
- #
120
- # Writes messages to STDOUT if any appender fails to complete the check.
121
- #
122
- define_method "#{level}?" do
123
- @appenders.any? do |appender|
124
- begin
125
- appender.enabled? level, @context
126
- rescue => e
127
- puts "Failed to check if level #{level} enabled for #{context} with appender #{appender}\n"
128
- false
129
- end
130
- end
131
- end
111
+ # Public: Returns true if any of the appenders will log messages for the
112
+ # current context at debug level, otherwise returns false.
113
+ #
114
+ # Writes messages to STDOUT if any appender fails to complete the check.
115
+ #
116
+ def debug?
117
+ enabled? :debug
118
+ end
119
+
120
+ # Public: Logs a message at info level.
121
+ #
122
+ # message - An already evaluated message, usually a String (default: nil).
123
+ # error - An error which is associated with the message (default: nil).
124
+ # block - An optional block which will provide a message when invoked.
125
+ #
126
+ # One of message or block must be provided. If both are provided then the
127
+ # block is preferred as it is assumed to provide more detail.
128
+ #
129
+ # In general, you should use the block style for any message not related
130
+ # to an error. This is because any unneccessary String interpolation is
131
+ # avoided making unwritten info calls, for example, less expensive.
132
+ #
133
+ # When logging errors it is advised that you include some details of the
134
+ # error within the regular message, perhaps the error's message, but leave
135
+ # the inclusion of the stack trace up to your appenders and their
136
+ # formatters.
137
+ #
138
+ # Examples
139
+ #
140
+ # info { "A fine grained message" }
141
+ # info "A message relating to an exception", e
142
+ #
143
+ # Returns nothing.
144
+ #
145
+ def info(message = nil, error = nil, &block)
146
+ add(:info, message, error, &block)
147
+ end
148
+
149
+ # Public: Returns true if any of the appenders will log messages for the
150
+ # current context at info level, otherwise returns false.
151
+ #
152
+ # Writes messages to STDOUT if any appender fails to complete the check.
153
+ #
154
+ def info?
155
+ enabled? :info
156
+ end
157
+
158
+ # Public: Logs a message at warn level.
159
+ #
160
+ # message - An already evaluated message, usually a String (default: nil).
161
+ # error - An error which is associated with the message (default: nil).
162
+ # block - An optional block which will provide a message when invoked.
163
+ #
164
+ # One of message or block must be provided. If both are provided then the
165
+ # block is preferred as it is assumed to provide more detail.
166
+ #
167
+ # In general, you should use the block style for any message not related
168
+ # to an error. This is because any unneccessary String interpolation is
169
+ # avoided making unwritten warn calls, for example, less expensive.
170
+ #
171
+ # When logging errors it is advised that you include some details of the
172
+ # error within the regular message, perhaps the error's message, but leave
173
+ # the inclusion of the stack trace up to your appenders and their
174
+ # formatters.
175
+ #
176
+ # Examples
177
+ #
178
+ # warn { "A fine grained message" }
179
+ # warn "A message relating to an exception", e
180
+ #
181
+ # Returns nothing.
182
+ #
183
+ def warn(message = nil, error = nil, &block)
184
+ add(:warn, message, error, &block)
185
+ end
132
186
 
187
+ # Public: Returns true if any of the appenders will log messages for the
188
+ # current context at warn level, otherwise returns false.
189
+ #
190
+ # Writes messages to STDOUT if any appender fails to complete the check.
191
+ #
192
+ def warn?
193
+ enabled? :warn
194
+ end
195
+
196
+ # Public: Logs a message at error level.
197
+ #
198
+ # message - An already evaluated message, usually a String (default: nil).
199
+ # error - An error which is associated with the message (default: nil).
200
+ # block - An optional block which will provide a message when invoked.
201
+ #
202
+ # One of message or block must be provided. If both are provided then the
203
+ # block is preferred as it is assumed to provide more detail.
204
+ #
205
+ # In general, you should use the block style for any message not related
206
+ # to an error. This is because any unneccessary String interpolation is
207
+ # avoided making unwritten error calls, for example, less expensive.
208
+ #
209
+ # When logging errors it is advised that you include some details of the
210
+ # error within the regular message, perhaps the error's message, but leave
211
+ # the inclusion of the stack trace up to your appenders and their
212
+ # formatters.
213
+ #
214
+ # Examples
215
+ #
216
+ # error { "A fine grained message" }
217
+ # error "A message relating to an exception", e
218
+ #
219
+ # Returns nothing.
220
+ #
221
+ def error(message = nil, error = nil, &block)
222
+ add(:error, message, error, &block)
223
+ end
224
+
225
+ # Public: Returns true if any of the appenders will log messages for the
226
+ # current context at error level, otherwise returns false.
227
+ #
228
+ # Writes messages to STDOUT if any appender fails to complete the check.
229
+ #
230
+ def error?
231
+ enabled? :error
232
+ end
233
+
234
+ # Public: Logs a message at fatal level.
235
+ #
236
+ # message - An already evaluated message, usually a String (default: nil).
237
+ # error - An error which is associated with the message (default: nil).
238
+ # block - An optional block which will provide a message when invoked.
239
+ #
240
+ # One of message or block must be provided. If both are provided then the
241
+ # block is preferred as it is assumed to provide more detail.
242
+ #
243
+ # In general, you should use the block style for any message not related
244
+ # to an error. This is because any unneccessary String interpolation is
245
+ # avoided making unwritten fatal calls, for example, less expensive.
246
+ #
247
+ # When logging errors it is advised that you include some details of the
248
+ # error within the regular message, perhaps the error's message, but leave
249
+ # the inclusion of the stack trace up to your appenders and their
250
+ # formatters.
251
+ #
252
+ # Examples
253
+ #
254
+ # fatal { "A fine grained message" }
255
+ # fatal "A message relating to an exception", e
256
+ #
257
+ # Returns nothing.
258
+ #
259
+ def fatal(message = nil, error = nil, &block)
260
+ add(:fatal, message, error, &block)
261
+ end
262
+
263
+ # Public: Returns true if any of the appenders will log messages for the
264
+ # current context at fatal level, otherwise returns false.
265
+ #
266
+ # Writes messages to STDOUT if any appender fails to complete the check.
267
+ #
268
+ def fatal?
269
+ enabled? :fatal
133
270
  end
134
271
 
135
272
  # Public: Returns the default level of the logger's configuration.
@@ -173,19 +310,26 @@ module Hatchet
173
310
  #
174
311
  # message - The message that will be logged by an appender when it is
175
312
  # configured to log at the given level or lower.
313
+ # error - An error which is associated with the message.
314
+ # block - An optional block which will provide a message when invoked.
315
+ #
176
316
  #
177
317
  # Writes messages to STDOUT if any appender fails to complete the enabled
178
318
  # check or log the message.
179
319
  #
180
320
  # Returns nothing.
181
321
  #
182
- def add(level, message)
322
+ def add(level, message, error, &block)
323
+ return unless message or block
324
+
325
+ msg = Message.new(ndc: @ndc.context.clone, message: message, error: error, &block)
326
+
183
327
  @appenders.each do |appender|
184
328
  if appender.enabled?(level, @context)
185
329
  begin
186
- appender.add(level, @context, message)
330
+ appender.add(level, @context, msg)
187
331
  rescue => e
188
- puts "Failed to log message for #{@context} with appender #{appender} - #{level} - #{message}\n"
332
+ puts "Failed to log message for #{@context} with appender #{appender} - #{level} - #{msg}\n"
189
333
  puts "#{e}\n"
190
334
  end
191
335
  end
@@ -193,6 +337,31 @@ module Hatchet
193
337
  nil
194
338
  end
195
339
 
340
+ # Private: Returns true if any of the appenders will log messages for the
341
+ # current context at the given level, otherwise returns false.
342
+ #
343
+ # level - The level of the message. One of, in decreasing order of
344
+ # severity:
345
+ #
346
+ # * fatal
347
+ # * error
348
+ # * warn
349
+ # * info
350
+ # * debug
351
+ #
352
+ # Writes messages to STDOUT if any appender fails to complete the check.
353
+ #
354
+ def enabled?(level)
355
+ @appenders.any? do |appender|
356
+ begin
357
+ appender.enabled? level, @context
358
+ rescue => e
359
+ puts "Failed to check if level #{level} enabled for #{context} with appender #{appender}\n"
360
+ false
361
+ end
362
+ end
363
+ end
364
+
196
365
  # Private: Determines the contextual name of the host object.
197
366
  #
198
367
  # host - The object hosting this logger.
@@ -60,17 +60,12 @@ module Hatchet
60
60
  # level within the given context, otherwise returns false.
61
61
  #
62
62
  def enabled?(level, context)
63
- unless self.levels_cache.key? context
64
- lvl = self.levels_cache[nil]
65
- root = []
66
- context.to_s.split('::').each do |part|
67
- root << part
68
- path = root.join '::'
69
- lvl = self.levels_cache[path] if self.levels_cache.key? path
70
- end
71
- self.levels_cache[context] = lvl
72
- end
73
- LEVELS.index(level) >= LEVELS.index(self.levels_cache[context])
63
+ lvl = self.levels_cache[context]
64
+
65
+ # Return false if no level is configured.
66
+ return false unless lvl
67
+
68
+ LEVELS.index(level) >= LEVELS.index(lvl)
74
69
  end
75
70
 
76
71
  # Internal: Returns a lazily duplicated Hash from the levels Hash which is
@@ -78,7 +73,13 @@ module Hatchet
78
73
  # subsequent lookups more efficient.
79
74
  #
80
75
  def levels_cache
81
- @_levels_cache ||= self.levels.dup
76
+ @_levels_cache ||= begin
77
+ levels = Hash.new do |hash, key|
78
+ hash[key] = level_for_context(key)
79
+ end
80
+ self.levels.each { |k, v| levels[k] = v }
81
+ levels
82
+ end
82
83
  end
83
84
 
84
85
  # Internal: Removes the caching Hash so that it will be re-initialized.
@@ -90,6 +91,26 @@ module Hatchet
90
91
  @_levels_cache = nil
91
92
  end
92
93
 
94
+ private
95
+
96
+ # Private: Returns the minimum active logging level for the given context.
97
+ #
98
+ # context - The context of the logging call.
99
+ #
100
+ # Returns the minimum level that a message would be logged at for the given
101
+ # context.
102
+ #
103
+ def level_for_context(context)
104
+ lvl = self.levels_cache[nil]
105
+ root = []
106
+ context.to_s.split('::').each do |part|
107
+ root << part
108
+ path = root.join '::'
109
+ lvl = self.levels_cache[path] if self.levels_cache.key? path
110
+ end
111
+ lvl
112
+ end
113
+
93
114
  end
94
115
 
95
116
  end
@@ -10,6 +10,12 @@ module Hatchet
10
10
  class PlainFormatter
11
11
  include BacktraceFormatter
12
12
 
13
+ # Public: Initialize a new instance.
14
+ #
15
+ def initialize
16
+ @backtrace = true
17
+ end
18
+
13
19
  # Public: Returns the formatted message.
14
20
  #
15
21
  # level - The severity of the log message.
@@ -27,22 +27,71 @@ module Hatchet
27
27
  # collection on initialization.
28
28
  #
29
29
  initializer 'hatchet_railtie.replace_logger' do |app|
30
+ Railtie.wrap_rails_logger(app)
31
+ end
32
+
33
+ # Internal: Class method to encapsulate the replacement of the Rails logger
34
+ # with Hatchet.
35
+ #
36
+ def self.wrap_rails_logger(app)
37
+ initialize_hatchet(Rails.logger)
38
+ replace_rails_loggers(app)
39
+ end
40
+
41
+ private
30
42
 
31
- # Keep a handle to the original logger.
43
+ def self.replace_rails_loggers(app)
44
+ # Replace the Rails.logger with the application's Hatchet logger.
45
+ #
46
+ Rails.logger = app.logger
47
+ app.logger.debug { 'Replaced Rails logger with Hatchet' }
48
+
49
+ # Replace the logger of every subscriber in the
50
+ # ActiveSupport::LogSubscriber.log_subscribers collection by extending
51
+ # them with Hatchet.
52
+ #
53
+ ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
54
+ app.logger.debug { "Replacing #{subscriber.class} logger with Hatchet" }
55
+ subscriber.extend Hatchet
56
+ end
57
+
58
+ # Replace the Rails.application.assets.logger with a logger that lives
59
+ # in a module beneath the application. This allows you to target the
60
+ # asset logger messages directly when managing levels.
61
+ #
62
+ # As you can guess by the description this is probably the riskiest so
63
+ # we do it last.
32
64
  #
33
- logger = Rails.logger
65
+ app.logger.debug { 'Replacing Rails asset logger with Hatchet' }
34
66
 
67
+ wrap_asset_logging(app)
68
+ rescue
69
+ # If anything goes wrong along the way log it and let the application
70
+ # continue.
71
+ #
72
+ Rails.logger.error { 'Failed to replace logger with Hatchet' }
73
+ Rails.logger.error { $! }
74
+ end
75
+
76
+ def self.wrap_asset_logging(app)
77
+ # Initially replace it with the application logger as it's better for
78
+ # this to be done if the next part fails.
79
+ #
80
+ Rails.application.assets.logger = app.logger
81
+
82
+ # Create the <Application>::Assets module and extend it with Hatchet so
83
+ # that it can replace the assets logger.
84
+ #
85
+ assets = Module.new
86
+ app.class.const_set 'Assets', assets
87
+ assets.extend Hatchet
88
+ Rails.application.assets.logger = assets.logger
89
+ end
90
+
91
+ def self.initialize_hatchet(logger)
35
92
  # Map the level of the logger so Hatchet uses the same.
36
93
  #
37
- current_level =
38
- case logger.level
39
- when Logger::DEBUG then :debug
40
- when Logger::INFO then :info
41
- when Logger::WARN then :warn
42
- when Logger::ERROR then :error
43
- when Logger::FATAL then :fatal
44
- else nil # If not recognized use Hatchet's default
45
- end
94
+ current_level = logger_level(logger)
46
95
 
47
96
  # Add an appender that delegates to the current Rails.logger to Hatchet's
48
97
  # configuration.
@@ -55,52 +104,19 @@ module Hatchet
55
104
  # Extend the application with Hatchet.
56
105
  #
57
106
  app.extend Hatchet
107
+ end
58
108
 
59
- begin
60
- # Replace the Rails.logger with the application's Hatchet logger.
61
- #
62
- Rails.logger = app.logger
63
- app.logger.debug { 'Replaced Rails logger with Hatchet' }
64
-
65
- # Replace the logger of every subscriber in the
66
- # ActiveSupport::LogSubscriber.log_subscribers collection by extending
67
- # them with Hatchet.
68
- #
69
- ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
70
- app.logger.debug { "Replacing #{subscriber.class} logger with Hatchet" }
71
- subscriber.extend Hatchet
72
- end
73
-
74
- # Replace the Rails.application.assets.logger with a logger that lives
75
- # in a module beneath the application. This allows you to target the
76
- # asset logger messages directly when managing levels.
77
- #
78
- # As you can guess by the description this is probably the riskiest so
79
- # we do it last.
80
- #
81
- app.logger.debug { 'Replacing Rails asset logger with Hatchet' }
82
-
83
- # Initially replace it with the application logger as it's better for
84
- # this to be done if the next part fails.
85
- #
86
- Rails.application.assets.logger = app.logger
87
-
88
- # Create the <Application>::Assets module and extend it with Hatchet so
89
- # that it can replace the assets logger.
90
- #
91
- assets = Module.new
92
- app.class.const_set 'Assets', assets
93
- assets.extend Hatchet
94
- Rails.application.assets.logger = assets.logger
95
-
96
- rescue
97
- # If anything goes wrong along the way log it and let the application
98
- # continue.
99
- #
100
- logger.error { 'Failed to replace logger with Hatchet' }
101
- logger.error { $! }
109
+ def self.logger_level(logger)
110
+ case logger.level
111
+ when Logger::DEBUG then :debug
112
+ when Logger::INFO then :info
113
+ when Logger::WARN then :warn
114
+ when Logger::ERROR then :error
115
+ when Logger::FATAL then :fatal
116
+ else nil # If not recognized use Hatchet's default
102
117
  end
103
118
  end
119
+
104
120
  end
105
121
 
106
122
  end
@@ -14,6 +14,12 @@ module Hatchet
14
14
  #
15
15
  attr_accessor :thread_context
16
16
 
17
+ # Public: Initialize a new instance.
18
+ #
19
+ def initialize
20
+ @backtrace = true
21
+ end
22
+
17
23
  # Public: Returns the formatted message.
18
24
  #
19
25
  # level - The severity of the log message.
@@ -11,7 +11,9 @@ module Hatchet
11
11
  # Public: Creates a new instance.
12
12
  #
13
13
  def initialize
14
+ @backtrace = true
14
15
  @secs = 0
16
+ @millis = -1
15
17
  @level_cache = {}
16
18
  end
17
19
 
@@ -4,6 +4,6 @@ module Hatchet
4
4
 
5
5
  # Public: The version of Hatchet.
6
6
  #
7
- VERSION = '0.2.1'
7
+ VERSION = '0.2.2'
8
8
 
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hatchet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-14 00:00:00.000000000 Z
12
+ date: 2013-03-28 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Logging library that provides the ability to add class/module specific
15
15
  filters
@@ -66,15 +66,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
66
  - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ segments:
70
+ - 0
71
+ hash: -3583664298557571275
69
72
  required_rubygems_version: !ruby/object:Gem::Requirement
70
73
  none: false
71
74
  requirements:
72
75
  - - ! '>='
73
76
  - !ruby/object:Gem::Version
74
77
  version: '0'
78
+ segments:
79
+ - 0
80
+ hash: -3583664298557571275
75
81
  requirements: []
76
82
  rubyforge_project:
77
- rubygems_version: 1.8.17
83
+ rubygems_version: 1.8.25
78
84
  signing_key:
79
85
  specification_version: 3
80
86
  summary: Logging library that provides the ability to add class/module specific filters