semantic_logger 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1332704e0667fa360e4b9a632e861fa75966f3e0
4
- data.tar.gz: ad079a8ed4ce5fb1802594e845f38a523c0a1a09
3
+ metadata.gz: fc98e41e370bc6257e0399ae04f886147944e227
4
+ data.tar.gz: b09cc78d0efae6377959ee8db77d4b93a5d81c9d
5
5
  SHA512:
6
- metadata.gz: 1c33e421728430664dba299821ceb31816dda9068c94f1cefbaecd3ce64b9b4cd9be16f6109bbd9ac52fbac38e935e46d4935f09088c7a1e508c4625704ad4da
7
- data.tar.gz: c8199f834fdeee217a50ff07c682e3954c7b42bc2d48514af3f9fbbee698358eb59e5fd834d34b57f521437c8a6c785a575333abb4640a0814f043bdd386574b
6
+ metadata.gz: dcfe55e29af7219b978c73f1d9f3a5123f49cd0eafb69ebdfc859372f6adbc30636c3b02320fa739cfe68df7cafd6ad805866441b1873bfc72b0a2cbe43eb06c
7
+ data.tar.gz: 3c95e43452d9e018b629845ca29c5d445c0cf1518a53b8170cdf82975b19c48ea60cf796ef8d169cc47c14142e2e555c2c2793225be2715af8d87a526dfa7bea
data/README.md CHANGED
@@ -38,10 +38,8 @@ instead of Semantic Logger directly since it will automatically replace the Rail
38
38
  ## Supports
39
39
 
40
40
  Semantic Logger is tested and supported on the following Ruby platforms:
41
- - Ruby 2.1 and above
42
- - JRuby 1.7 and above
43
- - JRuby 9.0 and above
44
- - Rubinius 2.5 and above
41
+ - Ruby 2.1, 2.2, 2.3, and above
42
+ - JRuby 1.7.23, 9.0.5 and above
45
43
 
46
44
  The following gems are only required when their corresponding appenders are being used,
47
45
  and are therefore not automatically included by this gem:
@@ -31,6 +31,7 @@ module SemanticLogger
31
31
  autoload :File, 'semantic_logger/appender/file'
32
32
  autoload :Graylog, 'semantic_logger/appender/graylog'
33
33
  autoload :Honeybadger, 'semantic_logger/appender/honeybadger'
34
+ autoload :Sentry, 'semantic_logger/appender/sentry'
34
35
  autoload :Http, 'semantic_logger/appender/http'
35
36
  autoload :MongoDB, 'semantic_logger/appender/mongodb'
36
37
  autoload :NewRelic, 'semantic_logger/appender/new_relic'
@@ -0,0 +1,72 @@
1
+ begin
2
+ require 'sentry-raven'
3
+ rescue LoadError
4
+ raise 'Gem sentry-raven is required for logging purposes. Please add the gem "sentry-raven" to your Gemfile.'
5
+ end
6
+
7
+ # Send log messages to sentry
8
+ #
9
+ # Example:
10
+ # SemanticLogger.add_appender(appender: :sentry)
11
+ #
12
+ class SemanticLogger::Appender::Sentry < SemanticLogger::Subscriber
13
+ # Create Appender
14
+ #
15
+ # Parameters
16
+ # level: [:trace | :debug | :info | :warn | :error | :fatal]
17
+ # Override the log level for this appender.
18
+ # Default: :error
19
+ #
20
+ # formatter: [Object|Proc|Symbol|Hash]
21
+ # An instance of a class that implements #call, or a Proc to be used to format
22
+ # the output from this appender
23
+ # Default: Use the built-in formatter (See: #call)
24
+ #
25
+ # filter: [Regexp|Proc]
26
+ # RegExp: Only include log messages where the class name matches the supplied.
27
+ # regular expression. All other messages will be ignored.
28
+ # Proc: Only include log messages where the supplied Proc returns true
29
+ # The Proc must return true or false.
30
+ #
31
+ # host: [String]
32
+ # Name of this host to appear in log messages.
33
+ # Default: SemanticLogger.host
34
+ #
35
+ # application: [String]
36
+ # Name of this application to appear in log messages.
37
+ # Default: SemanticLogger.application
38
+ def initialize(options = {}, &block)
39
+ options = options.is_a?(Hash) ? options.dup : {level: options}
40
+ options[:level] ||= :error
41
+
42
+ super(options, &block)
43
+ end
44
+
45
+ # Send an error notification to sentry
46
+ def log(log)
47
+ return false unless should_log?(log)
48
+
49
+ context = formatter.call(log, self)
50
+ if log.exception
51
+ context.delete(:exception)
52
+ Raven.capture_exception(log.exception, context)
53
+ else
54
+ message = {
55
+ error_class: context.delete(:name),
56
+ error_message: context.delete(:message),
57
+ extra: context
58
+ }
59
+ message[:backtrace] = log.backtrace if log.backtrace
60
+ Raven.capture_message(message[:error_message], message)
61
+ end
62
+ true
63
+ end
64
+
65
+ private
66
+
67
+ # Use Raw Formatter by default
68
+ def default_formatter
69
+ SemanticLogger::Formatters::Raw.new
70
+ end
71
+
72
+ end
@@ -14,6 +14,8 @@ module SemanticLogger
14
14
  alias_method :unknown?, :error? # :nodoc:
15
15
 
16
16
  alias_method :<<, :info # :nodoc:
17
+ # Active Record's Session Store calls silence_logger
18
+ alias_method :silence_logger, :silence # :nodoc:
17
19
 
18
20
  alias_method :progname, :name # :nodoc:
19
21
  alias_method :progname=, :name= # :nodoc:
@@ -232,6 +232,7 @@ module SemanticLogger
232
232
 
233
233
  # Metric
234
234
  h[:metric] = metric if metric
235
+ h[:metric_amount] = metric_amount if metric_amount
235
236
  h
236
237
  end
237
238
 
@@ -1,6 +1,6 @@
1
1
  module SemanticLogger
2
2
  module Metrics
3
- class NewRelic < Subscriber
3
+ class NewRelic
4
4
  attr_accessor :prefix
5
5
 
6
6
  # Parameters:
@@ -7,7 +7,7 @@ end
7
7
 
8
8
  module SemanticLogger
9
9
  module Metrics
10
- class Statsd < Subscriber
10
+ class Statsd
11
11
  # Create Statsd metrics subscriber
12
12
  #
13
13
  # Parameters:
@@ -18,10 +18,6 @@ module SemanticLogger
18
18
  # Example, send all metrics to a particular namespace:
19
19
  # udp://localhost:8125/namespace
20
20
  # Default: udp://localhost:8125
21
- #
22
- # Example:
23
- # subscriber = SemanticLogger::Metrics::Statsd.new(url: 'udp://localhost:8125')
24
- # SemanticLogger.on_metric(subscriber)
25
21
  def initialize(options = {})
26
22
  options = options.dup
27
23
  @url = options.delete(:url) || 'udp://localhost:8125'
@@ -463,11 +463,13 @@ module SemanticLogger
463
463
  end
464
464
 
465
465
  def self.constantize_symbol(symbol, namespace = 'SemanticLogger::Appender')
466
- symbol = symbol.to_s
467
- klass = symbol.respond_to?(:camelize) ? symbol.camelize : camelize(symbol)
468
- klass = "#{namespace}::#{klass}"
466
+ klass = "#{namespace}::#{camelize(symbol.to_s)}"
469
467
  begin
470
- symbol.respond_to?(:constantize) ? klass.constantize : eval(klass)
468
+ if RUBY_VERSION.to_i >= 2
469
+ Object.const_get(klass)
470
+ else
471
+ klass.split('::').inject(Object) { |o, name| o.const_get(name) }
472
+ end
471
473
  rescue NameError
472
474
  raise(ArgumentError, "Could not convert symbol: #{symbol} to a class in: #{namespace}. Looking for: #{klass}")
473
475
  end
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger #:nodoc
2
- VERSION = '3.3.0'
2
+ VERSION = '3.4.0'
3
3
  end
@@ -0,0 +1,46 @@
1
+ require_relative '../test_helper'
2
+
3
+ # Unit Test for SemanticLogger::Appender::Bugsnag
4
+ module Appender
5
+ class SentryTest < Minitest::Test
6
+ describe SemanticLogger::Appender::Sentry do
7
+ before do
8
+ @appender = SemanticLogger::Appender::Sentry.new(:trace)
9
+ @message = 'AppenderRavenTest log message'
10
+ SemanticLogger.backtrace_level = :error
11
+ end
12
+
13
+ SemanticLogger::LEVELS.each do |level|
14
+ it "sends #{level} message" do
15
+ error_message = hash = nil
16
+ Raven.stub(:capture_message, -> msg, h { error_message = msg; hash = h }) do
17
+ @appender.send(level, @message)
18
+ end
19
+ assert_equal @message, hash[:error_message]
20
+ assert_equal 'SemanticLogger::Appender::Sentry', hash[:error_class]
21
+
22
+ if [:error, :fatal].include?(level)
23
+ assert hash.has_key?(:backtrace)
24
+ else
25
+ refute hash.has_key?(:backtrace)
26
+ end
27
+ assert_equal true, hash.has_key?(:extra)
28
+ assert_equal level, hash[:extra][:level]
29
+ end
30
+
31
+ it "sends #{level} exceptions" do
32
+ error = RuntimeError.new('Oh no, Error.')
33
+ exception = hash = nil
34
+ Raven.stub(:capture_exception, -> exc, h { exception = exc; hash = h }) do
35
+ @appender.send(level, @message, error)
36
+ end
37
+
38
+ assert_equal error.class.to_s, exception.class.to_s
39
+ assert_equal error.message, exception.message
40
+ assert_equal @message, hash[:message], hash
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -48,6 +48,14 @@ class CompatibilityTest < Minitest::Test
48
48
  refute @logger.unknown?
49
49
  end
50
50
 
51
+ it '#silence_logger' do
52
+ @logger.silence_logger do
53
+ @logger.info 'hello world'
54
+ end
55
+ SemanticLogger.flush
56
+ refute @mock_logger.message
57
+ end
58
+
51
59
  it '#<< as info' do
52
60
  @logger << 'hello world'
53
61
  SemanticLogger.flush
@@ -65,28 +65,28 @@ class DebugAsTraceLoggerTest < Minitest::Test
65
65
 
66
66
  it 'not log trace when level is debug' do
67
67
  @logger.level = :debug
68
- @logger.trace('hello world', @hash) { "Calculations" }
68
+ @logger.trace('hello world', @hash) { 'Calculations' }
69
69
  SemanticLogger.flush
70
70
  assert_nil @mock_logger.message
71
71
  end
72
72
 
73
73
  it 'not log debug when level is debug' do
74
74
  @logger.level = :debug
75
- @logger.debug('hello world', @hash) { "Calculations" }
75
+ @logger.debug('hello world', @hash) { 'Calculations' }
76
76
  SemanticLogger.flush
77
77
  assert_nil @mock_logger.message
78
78
  end
79
79
 
80
80
  it 'map trace to debug' do
81
81
  @logger.level = :trace
82
- @logger.debug('hello world', @hash) { "Calculations" }
82
+ @logger.debug('hello world', @hash) { 'Calculations' }
83
83
  SemanticLogger.flush
84
84
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ T \[\d+:.+\] DebugAsTraceLoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
85
85
  end
86
86
 
87
87
  it 'log trace as trace' do
88
88
  @logger.level = :trace
89
- @logger.trace('hello world', @hash) { "Calculations" }
89
+ @logger.trace('hello world', @hash) { 'Calculations' }
90
90
  SemanticLogger.flush
91
91
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ T \[\d+:.+\] DebugAsTraceLoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
92
92
  end
data/test/logger_test.rb CHANGED
@@ -177,7 +177,7 @@ class LoggerTest < Minitest::Test
177
177
 
178
178
  it 'logs with backtrace and exception' do
179
179
  SemanticLogger.stub(:backtrace_level_index, 0) do
180
- exc = RuntimeError.new("Test")
180
+ exc = RuntimeError.new('Test')
181
181
  @logger.send(level, 'hello world', exc)
182
182
  SemanticLogger.flush
183
183
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] LoggerTest -- hello world -- Exception: RuntimeError: Test/, @mock_logger.message)
@@ -286,7 +286,7 @@ class LoggerTest < Minitest::Test
286
286
 
287
287
  describe '#with_payload' do
288
288
  it 'logs tagged payload' do
289
- hash = {tracking_number: "123456", even: 2, more: "data"}
289
+ hash = {tracking_number: '123456', even: 2, more: 'data'}
290
290
  hash_str = hash.inspect.sub("{", "\\{").sub("}", "\\}")
291
291
  @logger.with_payload(tracking_number: '123456') do
292
292
  @logger.with_payload(even: 2, more: 'data') do
@@ -354,7 +354,7 @@ class LoggerTest < Minitest::Test
354
354
 
355
355
  it "log #{level} info with an exception" do
356
356
  assert_raises RuntimeError do
357
- @logger.send("measure_#{level}", 'hello world', payload: @hash) { raise RuntimeError.new("Test") } # Measure duration of the supplied block
357
+ @logger.send("measure_#{level}", 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
358
358
  end
359
359
  SemanticLogger.flush
360
360
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
@@ -362,7 +362,7 @@ class LoggerTest < Minitest::Test
362
362
 
363
363
  it "change log #{level} info with an exception" do
364
364
  assert_raises RuntimeError do
365
- @logger.send("measure_#{level}", 'hello world', payload: @hash, on_exception_level: :fatal) { raise RuntimeError.new("Test") } # Measure duration of the supplied block
365
+ @logger.send("measure_#{level}", 'hello world', payload: @hash, on_exception_level: :fatal) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
366
366
  end
367
367
  SemanticLogger.flush
368
368
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ F \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-13 00:00:00.000000000 Z
11
+ date: 2016-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -45,6 +45,7 @@ files:
45
45
  - lib/semantic_logger/appender/http.rb
46
46
  - lib/semantic_logger/appender/mongodb.rb
47
47
  - lib/semantic_logger/appender/new_relic.rb
48
+ - lib/semantic_logger/appender/sentry.rb
48
49
  - lib/semantic_logger/appender/splunk.rb
49
50
  - lib/semantic_logger/appender/splunk_http.rb
50
51
  - lib/semantic_logger/appender/syslog.rb
@@ -67,7 +68,6 @@ files:
67
68
  - lib/semantic_logger/logger.rb
68
69
  - lib/semantic_logger/metrics/new_relic.rb
69
70
  - lib/semantic_logger/metrics/statsd.rb
70
- - lib/semantic_logger/metrics/udp.rb
71
71
  - lib/semantic_logger/semantic_logger.rb
72
72
  - lib/semantic_logger/subscriber.rb
73
73
  - lib/semantic_logger/version.rb
@@ -80,6 +80,7 @@ files:
80
80
  - test/appender/mongodb_test.rb
81
81
  - test/appender/new_relic_test.rb
82
82
  - test/appender/newrelic_rpm.rb
83
+ - test/appender/sentry_test.rb
83
84
  - test/appender/splunk_http_test.rb
84
85
  - test/appender/splunk_test.rb
85
86
  - test/appender/syslog_test.rb
@@ -112,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  version: '0'
113
114
  requirements: []
114
115
  rubyforge_project:
115
- rubygems_version: 2.4.8
116
+ rubygems_version: 2.5.1
116
117
  signing_key:
117
118
  specification_version: 4
118
119
  summary: Scalable, next generation enterprise logging for Ruby
@@ -126,6 +127,7 @@ test_files:
126
127
  - test/appender/mongodb_test.rb
127
128
  - test/appender/new_relic_test.rb
128
129
  - test/appender/newrelic_rpm.rb
130
+ - test/appender/sentry_test.rb
129
131
  - test/appender/splunk_http_test.rb
130
132
  - test/appender/splunk_test.rb
131
133
  - test/appender/syslog_test.rb
@@ -1,80 +0,0 @@
1
- require 'socket'
2
- module SemanticLogger
3
- module Metrics
4
- class Udp < Subscriber
5
- attr_accessor :server, :separator, :udp_flags
6
- attr_reader :socket
7
-
8
- # Write metrics to in JSON format to Udp
9
- #
10
- # Parameters:
11
- # server: [String]
12
- # Host name and port to write UDP messages to
13
- # Example:
14
- # localhost:8125
15
- #
16
- # udp_flags: [Integer]
17
- # Should be a bitwise OR of Socket::MSG_* constants.
18
- # Default: 0
19
- #
20
- # Limitations:
21
- # * UDP packet size is limited by the connected network and any routers etc
22
- # that the message has to traverse. See https://en.wikipedia.org/wiki/Maximum_transmission_unit
23
- #
24
- # Example:
25
- # subscriber = SemanticLogger::Metrics::Udp.new(server: 'localhost:8125')
26
- # SemanticLogger.on_metric(subscriber)
27
- def initialize(options = {}, &block)
28
- options = options.dup
29
- @server = options.delete(:server)
30
- @udp_flags = options.delete(:udp_flags) || 0
31
- raise(ArgumentError, 'Missing mandatory argument: :server') unless @server
32
-
33
- super(options, &block)
34
- reopen
35
- end
36
-
37
- # After forking an active process call #reopen to re-open
38
- # open the handles to resources
39
- def reopen
40
- close
41
- @socket = UDPSocket.new
42
- host, port = server.split(':')
43
- @socket.connect(host, port)
44
- end
45
-
46
- def call(log)
47
- metric = log.metric
48
- if duration = log.duration
49
- @statsd.timing(metric, duration)
50
- else
51
- amount = (log.metric_amount || 1).round
52
- if amount < 0
53
- amount.times { @statsd.decrement(metric) }
54
- else
55
- amount.times { @statsd.increment(metric) }
56
- end
57
- end
58
- @socket.send(data, udp_flags)
59
- end
60
-
61
- # Flush is called by the semantic_logger during shutdown.
62
- def flush
63
- @socket.flush if @socket
64
- end
65
-
66
- # Close is called during shutdown, or with reopen
67
- def close
68
- @socket.close if @socket
69
- end
70
-
71
- private
72
-
73
- # Returns [SemanticLogger::Formatters::Default] formatter default for this Appender
74
- def default_formatter
75
- SemanticLogger::Formatters::Json.new
76
- end
77
-
78
- end
79
- end
80
- end