semantic_logger 0.8.1 → 0.9.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/README.md CHANGED
@@ -725,15 +725,16 @@ Basic outline for an Appender:
725
725
  ```ruby
726
726
  require 'semantic_logger'
727
727
 
728
- class SimpleAppender < SemanticLogger::Base
728
+ class SimpleAppender < SemanticLogger::Appender::Base
729
729
  def initialize(level=nil, &block)
730
730
  # Set the log level and formatter if supplied
731
731
  super(level, &block)
732
732
  end
733
733
 
734
- # Just display the log struct
734
+ # Display the log struct and the text formatted output
735
735
  def log(log)
736
736
  p log
737
+ puts @formatter.call(log)
737
738
  end
738
739
 
739
740
  # Optional
@@ -3,6 +3,7 @@ module SemanticLogger
3
3
  autoload :Logger, 'semantic_logger/logger'
4
4
 
5
5
  module Appender
6
+ autoload :Base, 'semantic_logger/appender/base'
6
7
  autoload :File, 'semantic_logger/appender/file'
7
8
  autoload :Wrapper, 'semantic_logger/appender/wrapper'
8
9
  autoload :MongoDB, 'semantic_logger/appender/mongodb'
@@ -0,0 +1,83 @@
1
+ # Base appender
2
+ #
3
+ # Abstract base class for appenders
4
+ #
5
+ # Implements common behavior such as default text formatter etc
6
+ #
7
+ # Note: Do not create instances of this class directly
8
+ #
9
+ module SemanticLogger
10
+ module Appender
11
+ class Base < SemanticLogger::Base
12
+ attr_accessor :formatter
13
+
14
+ # Default log formatter
15
+ # Replace this formatter by supplying a Block to the initializer
16
+ # Generates logs of the form:
17
+ # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
18
+ def default_formatter
19
+ Proc.new do |log|
20
+ message = log.message.to_s
21
+ tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
22
+
23
+ if log.payload
24
+ if log.payload.is_a?(Exception)
25
+ exception = log.payload
26
+ message << " -- " << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
27
+ else
28
+ message << " -- " << self.class.inspect_payload(log.payload)
29
+ end
30
+ end
31
+
32
+ duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
33
+
34
+ "#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
35
+ end
36
+ end
37
+
38
+ ############################################################################
39
+ protected
40
+
41
+ # By default the appender should log everything that is sent to it by
42
+ # the loggers. That way the loggers control the log level
43
+ # By setting the log level to a higher value the appender can be setup
44
+ # to log for example only :warn or higher while other appenders
45
+ # are able to log lower level information
46
+ def initialize(level, &block)
47
+ # Set the formatter to the supplied block
48
+ @formatter = block || default_formatter
49
+
50
+ # Appenders don't take a class name, so use this class name if an appender
51
+ # is logged to directly
52
+ super(self.class, level || :trace)
53
+ end
54
+
55
+ # For JRuby include the Thread name rather than its id
56
+ if defined? Java
57
+ # Return the Time as a formatted string
58
+ # JRuby only supports time in ms
59
+ def self.formatted_time(time)
60
+ "#{time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%03d" % (time.usec/1000)}"
61
+ end
62
+ else
63
+ # Return the Time as a formatted string
64
+ # Ruby MRI supports micro seconds
65
+ def self.formatted_time(time)
66
+ "#{time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%06d" % (time.usec)}"
67
+ end
68
+ end
69
+
70
+ if RUBY_VERSION.to_f >= 1.9
71
+ # With Ruby 1.9 calling .to_s on a hash now returns { 'a' => 1 }
72
+ def self.inspect_payload(payload)
73
+ payload.to_s
74
+ end
75
+ else
76
+ def self.inspect_payload(payload)
77
+ payload.inspect
78
+ end
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -4,7 +4,7 @@
4
4
  #
5
5
  module SemanticLogger
6
6
  module Appender
7
- class File < SemanticLogger::Base
7
+ class File < SemanticLogger::Appender::Base
8
8
 
9
9
  # Create a File Logger appender instance
10
10
  #
@@ -42,7 +42,7 @@ module SemanticLogger
42
42
  # params: Hash
43
43
  #
44
44
  # tracking_number: 'user defined tracking number'
45
- class MongoDB < SemanticLogger::Base
45
+ class MongoDB < SemanticLogger::Appender::Base
46
46
  attr_reader :db, :collection_name
47
47
  attr_accessor :host_name, :safe, :application
48
48
 
@@ -4,7 +4,7 @@
4
4
  #
5
5
  module SemanticLogger
6
6
  module Appender
7
- class Wrapper < SemanticLogger::Base
7
+ class Wrapper < SemanticLogger::Appender::Base
8
8
  attr_reader :logger
9
9
 
10
10
  # Create a Logger or Rails Logger appender instance
@@ -36,8 +36,6 @@ module SemanticLogger
36
36
  super(:trace, &block)
37
37
  end
38
38
 
39
- # TODO Compatible calls to #level and #level= against the underlying Rails/Ruby logger
40
-
41
39
  # Pass log calls to the underlying Rails, log4j or Ruby logger
42
40
  # trace entries are mapped to debug since :trace is not supported by the
43
41
  # Ruby or Rails Loggers
@@ -1,6 +1,6 @@
1
- # Base appender
1
+ # Base logger
2
2
  #
3
- # Abstract base class for appenders
3
+ # Abstract base class for loggers
4
4
  #
5
5
  # Implements common behavior such as log level, default text formatter etc
6
6
  #
@@ -8,47 +8,12 @@
8
8
  #
9
9
  module SemanticLogger
10
10
  class Base
11
- attr_accessor :formatter
12
- attr_reader :level
11
+ # Class name to be logged
12
+ attr_accessor :name
13
13
 
14
- def initialize(level, &block)
15
- # Set the formatter to the supplied block
16
- @formatter = block || default_formatter
14
+ attr_reader :level
17
15
 
18
- # Log everything that comes to the appender by default
19
- self.level = level || :trace
20
- end
21
-
22
- # Default log formatter
23
- # Replace this formatter by supplying a Block to the initializer
24
- # Generates logs of the form:
25
- # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
26
- def default_formatter
27
- Proc.new do |log|
28
- message = log.message.to_s
29
- tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
30
-
31
- if log.payload
32
- if log.payload.is_a?(Exception)
33
- exception = log.payload
34
- message << " -- " << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
35
- else
36
- message << " -- " << self.class.inspect_payload(log.payload)
37
- end
38
- end
39
-
40
- duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
41
-
42
- "#{SemanticLogger::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
43
- end
44
- end
45
-
46
- # Write log data to underlying data storage
47
- def log(log_)
48
- raise "Logging Appender must implement #log(log)"
49
- end
50
-
51
- # Set the logging level for this appender
16
+ # Set the logging level for this logger
52
17
  #
53
18
  # Note: This level is only for this particular appender. It does not override
54
19
  # the log level in any logging instance or the default log level
@@ -209,9 +174,34 @@ module SemanticLogger
209
174
 
210
175
  # #TODO implement a thread safe #silence method
211
176
 
177
+ # Initial default Level for all new instances of SemanticLogger::Logger
178
+ @@default_level = :info
179
+
180
+ # Allow for setting the global default log level
181
+ # This change only applies to _new_ loggers, existing logger levels
182
+ # will not be changed in any way
183
+ def self.default_level=(level)
184
+ @@default_level = level
185
+ end
186
+
187
+ # Returns the global default log level for new Logger instances
188
+ def self.default_level
189
+ @@default_level
190
+ end
191
+
212
192
  ############################################################################
213
193
  protected
214
194
 
195
+ def initialize(klass, level=nil)
196
+ @name = klass.is_a?(String) ? klass : klass.name
197
+ self.level = level || self.class.default_level
198
+ end
199
+
200
+ # Write log data to underlying data storage
201
+ def log(log_)
202
+ raise "Logging Appender must implement #log(log)"
203
+ end
204
+
215
205
  # Return the level index for fast comparisons
216
206
  attr_reader :level_index
217
207
 
@@ -252,33 +242,10 @@ module SemanticLogger
252
242
  def self.thread_name
253
243
  Java::java.lang::Thread.current_thread.name
254
244
  end
255
-
256
- # Return the Time as a formatted string
257
- # JRuby only supports time in ms
258
- def self.formatted_time(time)
259
- "#{time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%03d" % (time.usec/1000)}"
260
- end
261
245
  else
262
246
  def self.thread_name
263
247
  Thread.current.object_id
264
248
  end
265
-
266
- # Return the Time as a formatted string
267
- # Ruby MRI supports micro seconds
268
- def self.formatted_time(time)
269
- "#{time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%06d" % (time.usec)}"
270
- end
271
- end
272
-
273
- if RUBY_VERSION.to_f >= 1.9
274
- # With Ruby 1.9 calling .to_s on a hash now returns { 'a' => 1 }
275
- def self.inspect_payload(payload)
276
- payload.to_s
277
- end
278
- else
279
- def self.inspect_payload(payload)
280
- payload.inspect
281
- end
282
249
  end
283
250
 
284
251
  # Internal method to return the log level as an internal index
@@ -304,11 +271,5 @@ module SemanticLogger
304
271
  index
305
272
  end
306
273
 
307
- # Appenders don't take a class name, so use this class name if an appender
308
- # is logged to directly
309
- def name
310
- self.class.name
311
- end
312
-
313
274
  end
314
275
  end
@@ -47,24 +47,6 @@ module SemanticLogger
47
47
  ThreadSafe::Array.new
48
48
  end
49
49
 
50
- # Initial default Level for all new instances of SemanticLogger::Logger
51
- @@default_level = :info
52
- @@appender_thread = nil
53
-
54
- # Allow for setting the global default log level
55
- # This change only applies to _new_ loggers, existing logger levels
56
- # will not be changed in any way
57
- def self.default_level=(level)
58
- @@default_level = level
59
- end
60
-
61
- # Returns the global default log level for new Logger instances
62
- def self.default_level
63
- @@default_level
64
- end
65
-
66
- attr_reader :name
67
-
68
50
  # Returns a Logger instance
69
51
  #
70
52
  # Return the logger for a specific class, supports class specific log levels
@@ -93,15 +75,22 @@ module SemanticLogger
93
75
  # able to write to the appenders fast enough. Either reduce the amount of
94
76
  # logging, increase the log level, reduce the number of appenders, or
95
77
  # look into speeding up the appenders themselves
96
- def self.cache_count
78
+ def self.queue_size
97
79
  queue.size
98
80
  end
99
81
 
82
+ # DEPRECATED: Please use queue_size instead.
83
+ def self.cache_count
84
+ warn "[DEPRECATION] 'SemanticLogger::Logger.cache_count' is deprecated. Please use 'SemanticLogger::Logger.queue_size' instead."
85
+ queue_size
86
+ end
87
+
100
88
  # Flush all queued log entries disk, database, etc.
101
89
  # All queued log messages are written and then each appender is flushed in turn
102
90
  def self.flush
103
91
  return false unless started? && @@appender_thread && @@appender_thread.alive?
104
92
 
93
+ logger.debug "SemanticLogger::Logger Flushing appenders with #{queue_size} log messages on the queue"
105
94
  reply_queue = Queue.new
106
95
  queue << { :command => :flush, :reply_queue => reply_queue }
107
96
  reply_queue.pop
@@ -140,6 +129,7 @@ module SemanticLogger
140
129
  ############################################################################
141
130
  protected
142
131
 
132
+ @@appender_thread = nil
143
133
  @@queue = Queue.new
144
134
 
145
135
  # Queue to hold messages that need to be logged to the various appenders
@@ -190,7 +180,7 @@ module SemanticLogger
190
180
  # Check every few log messages whether this appender thread is falling behind
191
181
  if count > lag_check_interval
192
182
  if (diff = Time.now - message.time) > lag_threshold_s
193
- logger.warn "SemanticLogger::Logger Appender thread has fallen behind by #{diff} seconds with #{cache_count} messages queued up. Consider reducing the log level or changing the appenders"
183
+ logger.warn "SemanticLogger::Logger Appender thread has fallen behind by #{diff} seconds with #{queue_size} messages queued up. Consider reducing the log level or changing the appenders"
194
184
  end
195
185
  count = 0
196
186
  end
@@ -226,11 +216,5 @@ module SemanticLogger
226
216
  end
227
217
  end
228
218
 
229
- # Formatting does not occur within this thread, it is done by each appender
230
- # in the appender thread
231
- def default_formatter
232
- nil
233
- end
234
-
235
219
  end
236
220
  end
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger #:nodoc
2
- VERSION = "0.8.1"
2
+ VERSION = "0.9.0"
3
3
  end
Binary file
@@ -30,7 +30,7 @@ class AppenderMongoDBTest < Test::Unit::TestCase
30
30
  context "format logs into documents" do
31
31
 
32
32
  should "handle nil name, message and hash" do
33
- @appender.log SemanticLogger::Logger::Log.new(:debug)
33
+ @appender.log SemanticLogger::Base::Log.new(:debug)
34
34
  document = @appender.collection.find_one
35
35
  assert_equal :debug, document['level']
36
36
  assert_equal nil, document['message']
@@ -43,7 +43,7 @@ class AppenderMongoDBTest < Test::Unit::TestCase
43
43
  end
44
44
 
45
45
  should "handle nil message and payload" do
46
- log = SemanticLogger::Logger::Log.new(:debug)
46
+ log = SemanticLogger::Base::Log.new(:debug)
47
47
  log.payload = @hash
48
48
  @appender.log(log)
49
49
 
@@ -59,7 +59,7 @@ class AppenderMongoDBTest < Test::Unit::TestCase
59
59
  end
60
60
 
61
61
  should "handle message and payload" do
62
- log = SemanticLogger::Logger::Log.new(:debug)
62
+ log = SemanticLogger::Base::Log.new(:debug)
63
63
  log.message = 'hello world'
64
64
  log.payload = @hash
65
65
  log.thread_name = 'thread'
@@ -78,7 +78,7 @@ class AppenderMongoDBTest < Test::Unit::TestCase
78
78
  end
79
79
 
80
80
  should "handle message without payload" do
81
- log = SemanticLogger::Logger::Log.new(:debug)
81
+ log = SemanticLogger::Base::Log.new(:debug)
82
82
  log.message = 'hello world'
83
83
  log.thread_name = 'thread'
84
84
  log.time = @time
@@ -100,7 +100,7 @@ class AppenderMongoDBTest < Test::Unit::TestCase
100
100
  # Ensure that any log level can be logged
101
101
  SemanticLogger::LEVELS.each do |level|
102
102
  should "log #{level} information" do
103
- @appender.log SemanticLogger::Logger::Log.new(level, 'thread', 'my_class', 'hello world -- Calculations', @hash, @time)
103
+ @appender.log SemanticLogger::Base::Log.new(level, 'thread', 'my_class', 'hello world -- Calculations', @hash, @time)
104
104
  document = @appender.collection.find_one
105
105
  assert_equal level, document['level']
106
106
  assert_equal 'hello world -- Calculations', document['message']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
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: 2012-10-19 00:00:00.000000000 Z
12
+ date: 2012-10-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sync_attr
@@ -72,6 +72,7 @@ files:
72
72
  - Gemfile
73
73
  - Gemfile.lock
74
74
  - init.txt
75
+ - lib/semantic_logger/appender/base.rb
75
76
  - lib/semantic_logger/appender/file.rb
76
77
  - lib/semantic_logger/appender/mongodb.rb
77
78
  - lib/semantic_logger/appender/wrapper.rb
@@ -92,6 +93,7 @@ files:
92
93
  - semantic_logger-0.7.0.gem
93
94
  - semantic_logger-0.7.1.gem
94
95
  - semantic_logger-0.8.0.gem
96
+ - semantic_logger-0.8.1.gem
95
97
  - test/appender_file_test.rb
96
98
  - test/appender_mongodb_test.rb
97
99
  - test/appender_wrapper_test.rb
@@ -111,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
113
  version: '0'
112
114
  segments:
113
115
  - 0
114
- hash: -3615546680742578594
116
+ hash: 3745819161206359497
115
117
  required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  none: false
117
119
  requirements: