semantic_logger 0.11.4 → 1.0.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
@@ -204,12 +204,12 @@ logger.info?
204
204
  The following logging methods are available
205
205
 
206
206
  ```ruby
207
- trace(message, payload=nil, &block)
208
- debug(message, payload=nil, &block)
209
- info(message, payload=nil, &block)
210
- warn(message, payload=nil, &block)
211
- error(message, payload=nil, &block)
212
- fatal(message, payload=nil, &block)
207
+ trace(message, payload=nil, exception=nil, &block)
208
+ debug(message, payload=nil, exception=nil, &block)
209
+ info(message, payload=nil, exception=nil, &block)
210
+ warn(message, payload=nil, exception=nil, &block)
211
+ error(message, payload=nil, exception=nil, &block)
212
+ fatal(message, payload=nil, exception=nil, &block)
213
213
  ```
214
214
 
215
215
  Parameters
@@ -217,6 +217,7 @@ Parameters
217
217
  - message: The text message to log.
218
218
  Mandatory only if no block is supplied
219
219
  - payload: Optional, either a Ruby Exception object or a Hash
220
+ - exception: Optional, Ruby Exception object. Allows both an exception and a payload to be logged
220
221
  - block: The optional block is executed only if the corresponding log level
221
222
  is active. Can be used to prevent unnecessary calculations of debug data in
222
223
  production.
@@ -311,7 +312,10 @@ Parameters
311
312
  Default: 0.0
312
313
 
313
314
  :payload
314
- Optional, either a Ruby Exception object or a Hash
315
+ Optional, Hash payload
316
+
317
+ :exception
318
+ Optional, Ruby Exception object to log along with the duration of the supplied block
315
319
  ```
316
320
 
317
321
  #### Logging levels
@@ -578,21 +582,15 @@ Example: Replace the Rails log formatter, in the environment configuration file:
578
582
  config.after_initialize do
579
583
  # Since the Rails logger is already initialized, replace its default formatter
580
584
  config.semantic_logger.appenders.first.formatter = Proc.new do |log|
581
- message = log.message.to_s
582
585
  tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
583
586
 
584
- if log.payload
585
- if log.payload.is_a?(Exception)
586
- exception = log.payload
587
- message << " -- " << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
588
- else
589
- message << " -- " << log.payload.inspect
590
- end
591
- end
592
-
593
- str = "#{log.time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%06d" % log.time.usec} #{"%-05s" % log.level.to_s.upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}"
594
- str << " (#{'%.1f' % log.duration}ms)" if log.duration
595
- str
587
+ message = log.message.to_s
588
+ message << " -- " << log.payload.inspect if log.payload
589
+ message << " -- " << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
590
+
591
+ duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
592
+
593
+ "#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
596
594
  end
597
595
  end
598
596
  ```
@@ -614,24 +612,18 @@ Example: Replace the MongoDB formatter, in the environment configuration file:
614
612
  :thread_name => log.thread_name,
615
613
  :name => log.name,
616
614
  :level => log.level,
615
+ :level_index => log.level_index,
617
616
  }
618
617
  document[:application] = 'MyApplication'
619
618
  document[:message] = SemanticLogger::Appender::MongoDB.strip_colorizing(log.message) if log.message
620
619
  document[:duration] = log.duration if log.duration
621
620
  document[:tags] = log.tags if log.tags && (log.tags.size > 0)
622
-
623
- if log.payload
624
- if log.payload.is_a?(Exception)
625
- exception = log.payload
626
- document[:payload] = {
627
- :exception => exception.class.name,
628
- :message => exception.message,
629
- :backtrace => exception.backtrace
630
- }
631
- else
632
- document[:payload] = log.payload
633
- end
634
- end
621
+ document[:payload] = log.payload if log.payload
622
+ document[:exception] = {
623
+ :name => log.exception.class.name,
624
+ :message => log.exception.message,
625
+ :stack_trace => log.exception.backtrace
626
+ } if log.exception
635
627
  document
636
628
  end
637
629
  config.semantic_logger.appenders << mongodb_appender
@@ -17,17 +17,11 @@ module SemanticLogger
17
17
  # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
18
18
  def default_formatter
19
19
  Proc.new do |log|
20
- message = log.message.to_s
21
20
  tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
22
21
 
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
22
+ message = log.message.to_s
23
+ message << " -- " << log.payload.inspect if log.payload
24
+ message << " -- " << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
31
25
 
32
26
  duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
33
27
 
@@ -67,17 +61,6 @@ module SemanticLogger
67
61
  end
68
62
  end
69
63
 
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
64
  end
82
65
  end
83
66
  end
@@ -144,19 +144,12 @@ module SemanticLogger
144
144
  document[:message] = self.class.strip_colorizing(log.message) if log.message
145
145
  document[:duration] = log.duration if log.duration
146
146
  document[:tags] = log.tags if log.tags && (log.tags.size > 0)
147
-
148
- if log.payload
149
- if log.payload.is_a?(Exception)
150
- exception = log.payload
151
- document[:exception] = {
152
- :name => exception.class.name,
153
- :message => exception.message,
154
- :stack_trace => exception.backtrace
155
- }
156
- else
157
- document[:payload] = log.payload
158
- end
159
- end
147
+ document[:payload] = log.payload if log.payload
148
+ document[:exception] = {
149
+ :name => log.exception.class.name,
150
+ :message => log.exception.message,
151
+ :stack_trace => log.exception.backtrace
152
+ } if log.exception
160
153
  document
161
154
  end
162
155
  end
@@ -31,7 +31,23 @@ module SemanticLogger
31
31
  # Implement the log level query
32
32
  # logger.debug?
33
33
  #
34
- # Example:
34
+ # Parameters:
35
+ # message
36
+ # [String] text message to be logged
37
+ # Should always be supplied unless the result of the supplied block returns
38
+ # a string in which case it will become the logged message
39
+ # Default: nil
40
+ #
41
+ # payload
42
+ # [Hash|Exception] Optional hash payload or an exception to be logged
43
+ # Default: nil
44
+ #
45
+ # exception
46
+ # [Exception] Optional exception to be logged
47
+ # Allows both an exception and a payload to be logged
48
+ # Default: nil
49
+ #
50
+ # Examples:
35
51
  # require 'semantic_logger'
36
52
  #
37
53
  # # Enable trace level logging
@@ -54,20 +70,28 @@ module SemanticLogger
54
70
  #
55
71
  SemanticLogger::LEVELS.each_with_index do |level, index|
56
72
  class_eval <<-EOT, __FILE__, __LINE__
57
- def #{level}(message = nil, payload = nil)
73
+ def #{level}(message=nil, payload=nil, exception=nil)
58
74
  if @level_index <= #{index}
75
+ if exception.nil? && payload && payload.is_a?(Exception)
76
+ exception = payload
77
+ payload = nil
78
+ end
79
+
59
80
  if block_given? && (result = yield)
60
81
  if result.is_a?(String)
61
- message = message.nil? ? result : "\#{message} -- \#{result.to_s}"
82
+ message = message.nil? ? result : "\#{message} -- \#{result}"
83
+ elsif payload && payload.respond_to?(:merge)
84
+ payload.merge(result)
62
85
  else
63
- payload = payload.nil? ? result : payload.merge(result)
86
+ payload = result
64
87
  end
65
88
  end
89
+
66
90
  # Add scoped payload
67
91
  if self.payload
68
92
  payload = payload.nil? ? self.payload : self.payload.merge(payload)
69
93
  end
70
- log Log.new(:#{level}, self.class.thread_name, name, message, payload, Time.now, nil, tags, #{index})
94
+ log Log.new(:#{level}, self.class.thread_name, name, message, payload, Time.now, nil, tags, #{index}, exception)
71
95
  true
72
96
  else
73
97
  false
@@ -80,13 +104,17 @@ module SemanticLogger
80
104
 
81
105
  def benchmark_#{level}(message, params = nil)
82
106
  raise "Mandatory block missing" unless block_given?
83
- log_exception = params.nil? ? :full : params[:log_exception]
84
- min_duration = params.nil? ? 0.0 : (params[:min_duration] || 0.0)
85
- payload = params.nil? ? nil : params[:payload]
86
107
  if @level_index <= #{index}
87
- start = Time.now
108
+ log_exception = params.nil? ? :partial : (params[:log_exception] || :partial)
109
+ min_duration = params.nil? ? 0.0 : (params[:min_duration] || 0.0)
110
+ payload = params.nil? ? nil : params[:payload]
111
+ exception = params[:exception]
112
+ start = Time.now
88
113
  begin
89
- result = yield
114
+ yield
115
+ rescue Exception => exc
116
+ exception = exc
117
+ ensure
90
118
  end_time = Time.now
91
119
  duration = 1000.0 * (end_time - start)
92
120
 
@@ -96,16 +124,18 @@ module SemanticLogger
96
124
  if self.payload
97
125
  payload = payload.nil? ? self.payload : self.payload.merge(payload)
98
126
  end
99
- log Log.new(:#{level}, self.class.thread_name, name, message, payload, end_time, duration, tags, #{index})
100
- end
101
- result
102
- rescue Exception => exc
103
- if log_exception == :full
104
- log Log.new(:#{level}, self.class.thread_name, name, message, exc, Time.now, 1000.0 * (Time.now - start), tags, #{index})
105
- elsif log_exception == :partial
106
- log Log.new(:#{level}, self.class.thread_name, name, "\#{message} -- \#{exception.class}: \#{exception.message}", payload, end_time, 1000.0 * (end_time - start), tags, #{index})
127
+ if exception
128
+ case log_exception
129
+ when :full
130
+ log Log.new(:#{level}, self.class.thread_name, name, message, payload, end_time, duration, tags, #{index}, exception)
131
+ when :partial
132
+ log Log.new(:#{level}, self.class.thread_name, name, "\#{message} -- Exception: \#{exception.class}: \#{exception.message}", payload, end_time, duration, tags, #{index}, nil)
133
+ end
134
+ raise exception
135
+ else
136
+ log Log.new(:#{level}, self.class.thread_name, name, message, payload, end_time, duration, tags, #{index}, nil)
137
+ end
107
138
  end
108
- raise exc
109
139
  end
110
140
  else
111
141
  yield
@@ -234,7 +264,7 @@ module SemanticLogger
234
264
  #
235
265
  # level_index
236
266
  # Internal index of the log level
237
- Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index)
267
+ Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception)
238
268
 
239
269
  # For JRuby include the Thread name rather than its id
240
270
  if defined? Java
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger #:nodoc
2
- VERSION = "0.11.4"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -36,6 +36,11 @@ class AppenderFileTest < Test::Unit::TestCase
36
36
  @appender.debug 'hello world', @hash
37
37
  assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string
38
38
  end
39
+
40
+ should "handle message, payload, and exception" do
41
+ @appender.debug 'hello world', @hash, StandardError.new("StandardError")
42
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str} -- StandardError: StandardError\n\n/, @io.string
43
+ end
39
44
  end
40
45
 
41
46
  context "for each log level" do
@@ -51,21 +56,15 @@ class AppenderFileTest < Test::Unit::TestCase
51
56
  context "custom formatter" do
52
57
  setup do
53
58
  @appender = SemanticLogger::Appender::File.new(@io) do |log|
54
- message = log.message.to_s
55
59
  tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
56
60
 
57
- if log.payload
58
- if log.payload.is_a?(Exception)
59
- exception = log.payload
60
- message << " -- " << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
61
- else
62
- message << " -- " << log.payload.inspect
63
- end
64
- end
61
+ message = log.message.to_s
62
+ message << " -- " << log.payload.inspect if log.payload
63
+ message << " -- " << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
64
+
65
+ duration_str = log.duration ? " (#{'%.1f' % log.duration}ms)" : ''
65
66
 
66
- str = "#{log.time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%03d" % (log.time.usec/1000)} #{log.level.to_s.upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}"
67
- str << " (#{'%.1f' % log.duration}ms)" if log.duration
68
- str
67
+ "#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s.upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}#{duration_str}"
69
68
  end
70
69
  end
71
70
 
data/test/logger_test.rb CHANGED
@@ -10,104 +10,130 @@ require 'semantic_logger'
10
10
  # Unit Test for SemanticLogger::Logger
11
11
  class LoggerTest < Test::Unit::TestCase
12
12
  context SemanticLogger::Logger do
13
+ setup do
14
+ # Use a mock logger that just keeps the last logged entry in an instance
15
+ # variable
16
+ @mock_logger = MockLogger.new
17
+ @appender = SemanticLogger::Appender::Wrapper.new(@mock_logger)
18
+ SemanticLogger::Logger.appenders << @appender
19
+
20
+ # Use this test's class name as the application name in the log output
21
+ @logger = SemanticLogger::Logger.new(self.class, :trace)
22
+ @hash = { :session_id => 'HSSKLEU@JDK767', :tracking_number => 12345 }
23
+ @hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
24
+ end
13
25
 
14
- context "log to Ruby and Rails logger" do
15
- setup do
16
- # Use a mock logger that just keeps the last logged entry in an instance variable
17
- @mock_logger = MockLogger.new
18
- @appender = SemanticLogger::Appender::Wrapper.new(@mock_logger)
19
- SemanticLogger::Logger.appenders << @appender
20
-
21
- # Use this test's class name as the application name in the log output
22
- @logger = SemanticLogger::Logger.new('LoggerTest', :trace)
23
-
24
- @hash = { :session_id => 'HSSKLEU@JDK767', :tracking_number => 12345 }
25
- @hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
26
- end
26
+ teardown do
27
+ SemanticLogger::Logger.appenders.delete(@appender)
28
+ end
27
29
 
28
- teardown do
29
- SemanticLogger::Logger.appenders.delete(@appender)
30
+ # Ensure that any log level can be logged
31
+ SemanticLogger::LEVELS.each do |level|
32
+ should "log #{level} info" do
33
+ @logger.send(level, 'hello world', @hash) { "Calculations" }
34
+ SemanticLogger::Logger.flush
35
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message
30
36
  end
37
+ end
31
38
 
32
- # Ensure that any log level can be logged
33
- SemanticLogger::LEVELS.each do |level|
34
- should "log #{level} info" do
35
- @logger.send(level, 'hello world', @hash) { "Calculations" }
39
+ context "with_tags logging" do
40
+ should "add tags to log entries" do
41
+ @logger.with_tags('12345', 'DJHSFK') do
42
+ @logger.info('Hello world')
36
43
  SemanticLogger::Logger.flush
37
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message
44
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world/, @mock_logger.message
38
45
  end
39
46
  end
40
47
 
41
- context "with_tags logging" do
42
- should "add tags to log entries" do
43
- @logger.with_tags('12345', 'DJHSFK') do
48
+ should "add embedded tags to log entries" do
49
+ @logger.with_tags('First Level', 'tags') do
50
+ @logger.with_tags('Second Level') do
44
51
  @logger.info('Hello world')
45
52
  SemanticLogger::Logger.flush
46
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world/, @mock_logger.message
53
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \[First Level\] \[tags\] \[Second Level\] LoggerTest -- Hello world/, @mock_logger.message
47
54
  end
48
55
  end
56
+ end
49
57
 
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
- SemanticLogger::Logger.flush
55
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \[First Level\] \[tags\] \[Second Level\] LoggerTest -- Hello world/, @mock_logger.message
56
- end
58
+ should "add payload to log entries" do
59
+ hash = {:tracking_number=>"123456", :even=>2, :more=>"data"}
60
+ hash_str = hash.inspect.sub("{", "\\{").sub("}", "\\}")
61
+ @logger.with_payload(:tracking_number => '123456') do
62
+ @logger.with_payload(:even => 2, :more => 'data') do
63
+ @logger.info('Hello world')
64
+ SemanticLogger::Logger.flush
65
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message
57
66
  end
58
67
  end
68
+ end
59
69
 
60
- should "add payload to log entries" do
61
- hash = {:tracking_number=>"123456", :even=>2, :more=>"data"}
62
- hash_str = hash.inspect.sub("{", "\\{").sub("}", "\\}")
63
- @logger.with_payload(:tracking_number => '123456') do
64
- @logger.with_payload(:even => 2, :more => 'data') do
65
- @logger.info('Hello world')
66
- SemanticLogger::Logger.flush
67
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message
70
+ context "Ruby Logger" do
71
+ # Ensure that any log level can be logged
72
+ Logger::Severity.constants.each do |level|
73
+ should "log Ruby logger #{level} info" do
74
+ @logger.level = Logger::Severity.const_get(level)
75
+ if level.to_s == 'UNKNOWN'
76
+ assert_equal Logger::Severity.const_get('ERROR')+1, @logger.send(:level_index)
77
+ else
78
+ assert_equal Logger::Severity.const_get(level)+1, @logger.send(:level_index)
68
79
  end
69
80
  end
70
81
  end
82
+ end
71
83
 
72
- context "Ruby Logger" do
73
- # Ensure that any log level can be logged
74
- Logger::Severity.constants.each do |level|
75
- should "log Ruby logger #{level} info" do
76
- @logger.level = Logger::Severity.const_get(level)
77
- if level.to_s == 'UNKNOWN'
78
- assert_equal Logger::Severity.const_get('ERROR')+1, @logger.send(:level_index)
79
- else
80
- assert_equal Logger::Severity.const_get(level)+1, @logger.send(:level_index)
81
- end
82
- end
84
+ context "benchmark" do
85
+ # Ensure that any log level can be benchmarked and logged
86
+ SemanticLogger::LEVELS.each do |level|
87
+ should "log #{level} info" do
88
+ assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world') { "result" } # Measure duration of the supplied block
89
+ SemanticLogger::Logger.flush
90
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
83
91
  end
84
- end
85
92
 
86
- context "benchmark" do
87
- # Ensure that any log level can be benchmarked and logged
88
- SemanticLogger::LEVELS.each do |level|
89
- should "log #{level} info" do
90
- assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world') { "result" }
91
- SemanticLogger::Logger.flush
92
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
93
- end
93
+ should "log #{level} info with payload" do
94
+ assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world', :payload => @hash) { "result" } # Measure duration of the supplied block
95
+ SemanticLogger::Logger.flush
96
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
97
+ end
94
98
 
95
- should "log #{level} info with payload" do
96
- assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world', :payload => @hash) { "result" }
97
- SemanticLogger::Logger.flush
98
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
99
- end
99
+ should "not log #{level} info when block is faster than :min_duration" do
100
+ assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world', :min_duration => 0.5) { "result" } # Measure duration of the supplied block
101
+ SemanticLogger::Logger.flush
102
+ assert_nil @mock_logger.message
103
+ end
104
+
105
+ should "log #{level} info when block duration exceeds :min_duration" do
106
+ assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world', :min_duration => 0.2, :payload => @hash) { sleep 0.5; "result" } # Measure duration of the supplied block
107
+ SemanticLogger::Logger.flush
108
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
109
+ end
100
110
 
101
- should "not log #{level} info when block is faster than :min_duration" do
102
- assert_equal "result", @logger.send("benchmark_#{level}".to_sym, 'hello world', :min_duration => 0.5) { "result" }
103
- SemanticLogger::Logger.flush
104
- assert_nil @mock_logger.message
111
+ should "log #{level} info with an exception" do
112
+ assert_raise RuntimeError do
113
+ @logger.send("benchmark_#{level}", 'hello world', :payload => @hash) { raise RuntimeError.new("Test") } # Measure duration of the supplied block
105
114
  end
115
+ SemanticLogger::Logger.flush
116
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
106
117
  end
107
118
  end
108
119
 
120
+ should "log when the block performs a return" do
121
+ assert_equal "Good", function_with_return(@logger)
122
+ SemanticLogger::Logger.flush
123
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
124
+ end
109
125
  end
126
+
110
127
  end
128
+ end
111
129
 
130
+ # Make sure that benchmark still logs when a block uses return to return from
131
+ # a function
132
+ def function_with_return(logger)
133
+ logger.benchmark_info('hello world', :payload => @hash) do
134
+ return "Good"
135
+ end
136
+ "Bad"
112
137
  end
138
+
113
139
  end
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.11.4
4
+ version: 1.0.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-11-02 00:00:00.000000000 Z
12
+ date: 2012-12-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sync_attr
@@ -108,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
108
  version: '0'
109
109
  segments:
110
110
  - 0
111
- hash: 3605629782528849560
111
+ hash: -2573404344883398043
112
112
  required_rubygems_version: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements: