semantic_logger 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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: