semantic_logger 2.13.1 → 2.14.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: 4d1b60df19e53352219ff825835d2d5c804c1733
4
- data.tar.gz: 936f580069648c8b91d5f3c589671649da3fc726
3
+ metadata.gz: 3a000244f5570ff32c8dcc923f066a131abd7cb0
4
+ data.tar.gz: a9471ed620e7408a195a9292f41730c68ea54e98
5
5
  SHA512:
6
- metadata.gz: b10df7ef8e1561f90f7f07c3f427cd63b90be885fe1b45f5d01c4a78b01dadda2040e416bd7dfc77d409815505ee0394ee2f47e9a1c4fbfaed495b9c9b3b835c
7
- data.tar.gz: 10444abc156d65cd7cab0a788bc5f311b0e1751ec8bf96761ce89d759d9521f91f17b12ea0332f98fd7e247560afba7435fdbf7a9ffaae9461484ebacaef3406
6
+ metadata.gz: 0667f6ef71190a16d66849493630a43f7dce3e8ae2786b38972f84b992cf3f2081995eb4e01c0d72ee47e0b378b49d844dd5883b561db40831f28d20abbff053
7
+ data.tar.gz: d81cddd57a426da87b14b4df0b2b212926e0c5b8405be8d103aa518348d4f65f0d8689bf066b6cf189d85e704b77c9929e874fbe6be9318579e6f6651ee85159
@@ -16,6 +16,7 @@ module SemanticLogger
16
16
  autoload :Syslog, 'semantic_logger/appender/syslog'
17
17
  autoload :NewRelic, 'semantic_logger/appender/new_relic'
18
18
  autoload :Splunk, 'semantic_logger/appender/splunk'
19
+ autoload :Bugsnag, 'semantic_logger/appender/bugsnag'
19
20
  end
20
21
 
21
22
  if defined?(JRuby)
@@ -0,0 +1,81 @@
1
+ =begin
2
+ Bugsnag appender for SemanticLogger
3
+
4
+ Skips the fatal log level because unrescued exceptions get logged as fatal and will be reported automatically by Bugsnag.
5
+
6
+ Note: Payload information is not filtered, so take care not to push any sensitive information when logging with tags or a payload.
7
+
8
+ Example 1
9
+
10
+ Adding the Bugsnag appender will send :error log entries to Bugsnag with the error severity.
11
+
12
+ For a Rails application already configured to use SemanticLogger and Bugsnag, create a file called <Rails Root>/config/initializers/bugsnag_appender.rb with the following contents and restart the application:
13
+
14
+ # Send :error and log messages to Bugsnag
15
+ SemanticLogger.add_appender(SemanticLogger::Appender::Bugsnag.new)
16
+ Rails.logger.info 'SemanticLogger Bugsnag Appender added.'
17
+
18
+ Example 2
19
+
20
+ For a non-Rails application, send :info and more severe log entries to a file called application.log and also send :error log entries to Bugsnag.
21
+
22
+ require 'semantic_logger'
23
+ require 'bugsnag'
24
+
25
+ # Bugsnag setup
26
+ Bugsnag.configure do |config|
27
+ config.api_key = 'abc123'
28
+ end
29
+
30
+ # SemanticLogger setup
31
+ SemanticLogger.default_level = :info
32
+ SemanticLogger.add_appender('application.log')
33
+ SemanticLogger.add_appender(SemanticLogger::Appender::Bugsnag.new)
34
+ logger = SemanticLogger['Example']
35
+
36
+ # Log some messages
37
+ logger.info 'This is only written to application.log'
38
+ logger.error 'This is written to application.log and will also be sent to Bugsnag as an error event'
39
+
40
+ # The appender will send payloads to Bugsnag
41
+ logger.error 'Something bad happened', info: 'Related information'
42
+ =end
43
+
44
+ require 'bugsnag'
45
+
46
+ class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
47
+ # Allow the level for this appender to be overwritten
48
+ # Default: :error
49
+ # Note: Not recommended to set the log level to :info, :debug, or :trace as that would flood Bugsnag with Error notices
50
+ def initialize(level = :error, &block)
51
+ super(level, &block)
52
+ end
53
+
54
+ # Returns [Hash] of parameters to send to Bugsnag.
55
+ def default_formatter
56
+ proc do |log|
57
+ { :severity => log_level(log), tags: log.tags }.merge(log.payload || {})
58
+ end
59
+ end
60
+
61
+ # Send an error notification to Bugsnag
62
+ def log(log)
63
+ # Only log if level is warn, or error.
64
+ # We don't want to send fatal as those are already captured by Bugsnag.
65
+ return false if (level_index > (log.level_index || 0)) || !include_message?(log)
66
+ return false if log.level == :fatal
67
+ # Ignore logs coming from Bugsnag itself
68
+ return false if log.message.to_s.include?(Bugsnag::LOG_PREFIX)
69
+
70
+ # For more documentation on the Bugsnag.notify method see:
71
+ # https://bugsnag.com/docs/notifiers/ruby#sending-handled-exceptions
72
+ Bugsnag.notify(log.exception || log.message, formatter.call(log))
73
+ true
74
+ end
75
+
76
+ private
77
+
78
+ def log_level(log)
79
+ log.level.to_s.gsub('warn', 'warning')
80
+ end
81
+ end
@@ -31,9 +31,7 @@ module SemanticLogger
31
31
 
32
32
  def self.included(base)
33
33
  base.class_eval do
34
- # Thread safe class variable initialization
35
- include SyncAttr
36
-
34
+ # Thread safe logger class variable initializer
37
35
  sync_cattr_reader :logger do
38
36
  SemanticLogger[self]
39
37
  end
@@ -196,10 +196,17 @@ module SemanticLogger
196
196
  end if log_level_signal
197
197
 
198
198
  Signal.trap(thread_dump_signal) do
199
- logger = SemanticLogger['Ruby Thread Dump']
199
+ logger = SemanticLogger['Thread Dump']
200
200
  Thread.list.each do |thread|
201
- backtrace = thread.backtrace ? thread.backtrace.join("\n") : ''
202
- logger.warn "#{thread.name}\n#{backtrace}"
201
+ next if thread == Thread.current
202
+ message = thread.name
203
+ if backtrace = thread.backtrace
204
+ message += "\n"
205
+ message << backtrace.join("\n")
206
+ end
207
+ tags = thread[:semantic_logger_tags]
208
+ tags = tags.nil? ? [] : tags.clone
209
+ logger.tagged(tags) { logger.warn(message) }
203
210
  end
204
211
  end if thread_dump_signal
205
212
 
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger #:nodoc
2
- VERSION = "2.13.1"
2
+ VERSION = "2.14.0"
3
3
  end
@@ -0,0 +1,61 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+ require 'test_helper'
3
+
4
+ # Unit Test for SemanticLogger::Appender::Bugsnag
5
+ #
6
+ class AppenderBugsnagTest < Minitest::Test
7
+ context SemanticLogger::Appender::Bugsnag do
8
+ setup do
9
+ @appender = SemanticLogger::Appender::Bugsnag.new(:warn)
10
+ @message = 'AppenderBugsnagTest log message'
11
+ end
12
+
13
+ (SemanticLogger::LEVELS - [:warn, :error]).each do |level|
14
+ should "not send :#{level} notifications to Bugsnag" do
15
+ message = hash = nil
16
+ Bugsnag.stub(:notify, -> msg, h { message = msg; hash = h }) do
17
+ @appender.send(level, "AppenderBugsnagTest #{level.to_s} message")
18
+ end
19
+ assert_nil message
20
+ assert_nil hash
21
+ end
22
+ end
23
+
24
+ should "send error notifications to Bugsnag with severity" do
25
+ message = hash = nil
26
+ Bugsnag.stub(:notify, -> msg, h { message = msg; hash = h }) do
27
+ @appender.error @message
28
+ end
29
+ assert_equal @message, message
30
+ assert_equal 'error', hash[:severity]
31
+ end
32
+
33
+ should 'send warn notifications to Bugsnag replace warn severity with warning' do
34
+ message = hash = nil
35
+ Bugsnag.stub(:notify, -> msg, h { message = msg; hash = h }) do
36
+ @appender.warn @message
37
+ end
38
+ assert_equal @message, message
39
+ assert_equal 'warning', hash[:severity]
40
+ end
41
+
42
+ should 'send notification to Bugsnag with custom attributes' do
43
+ message = hash = nil
44
+ Bugsnag.stub(:notify, -> msg, h { message = msg; hash = h }) do
45
+ @appender.error @message, {:key1 => 1, :key2 => 'a'}
46
+ end
47
+ assert_equal @message, message
48
+ assert_equal(1, hash[:key1], hash)
49
+ assert_equal('a', hash[:key2], hash)
50
+ end
51
+
52
+ should 'send notification to Bugsnag with exception' do
53
+ message = hash = nil
54
+ error = RuntimeError
55
+ Bugsnag.stub(:notify, -> msg, h { message = msg; hash = h }) do
56
+ @appender.error error
57
+ end
58
+ assert_equal error, message
59
+ end
60
+ end
61
+ end
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: 2.13.1
4
+ version: 2.14.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: 2015-02-13 00:00:00.000000000 Z
11
+ date: 2015-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sync_attr
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: thread_safe
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.1'
41
41
  description: Next generation logging system for Ruby to support highly concurrent,
42
- high throughput, low latency systems
42
+ high throughput, low latency enterprise systems
43
43
  email:
44
44
  - reidmo@gmail.com
45
45
  executables: []
@@ -49,10 +49,9 @@ files:
49
49
  - LICENSE.txt
50
50
  - README.md
51
51
  - Rakefile
52
- - lib/LogGC.java
53
- - lib/LogGC_1.java
54
52
  - lib/semantic_logger.rb
55
53
  - lib/semantic_logger/appender/base.rb
54
+ - lib/semantic_logger/appender/bugsnag.rb
56
55
  - lib/semantic_logger/appender/file.rb
57
56
  - lib/semantic_logger/appender/mongodb.rb
58
57
  - lib/semantic_logger/appender/new_relic.rb
@@ -67,6 +66,7 @@ files:
67
66
  - lib/semantic_logger/logger.rb
68
67
  - lib/semantic_logger/semantic_logger.rb
69
68
  - lib/semantic_logger/version.rb
69
+ - test/appender_bugsnag_test.rb
70
70
  - test/appender_file_test.rb
71
71
  - test/appender_mongodb_test.rb
72
72
  - test/appender_new_relic_test.rb
@@ -99,11 +99,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  version: '0'
100
100
  requirements: []
101
101
  rubyforge_project:
102
- rubygems_version: 2.4.5
102
+ rubygems_version: 2.4.6
103
103
  signing_key:
104
104
  specification_version: 4
105
- summary: Scalable, next generation logging for Ruby
105
+ summary: Scalable, next generation enterprise logging for Ruby
106
106
  test_files:
107
+ - test/appender_bugsnag_test.rb
107
108
  - test/appender_file_test.rb
108
109
  - test/appender_mongodb_test.rb
109
110
  - test/appender_new_relic_test.rb
data/lib/LogGC.java DELETED
@@ -1,26 +0,0 @@
1
- //get all the info and pretty print it
2
- duration =
3
- //System.out.println("GcInfo CompositeType: " + info.getGcInfo().getCompositeType());
4
- //System.out.println("GcInfo MemoryUsageAfterGc: " + info.getGcInfo().getMemoryUsageAfterGc());
5
- //System.out.println("GcInfo MemoryUsageBeforeGc: " + info.getGcInfo().getMemoryUsageBeforeGc());
6
-
7
- //Get the information about each memory space, and pretty print it
8
- Map<String, MemoryUsage> membefore = info.getGcInfo().getMemoryUsageBeforeGc();
9
- Map<String, MemoryUsage> mem = info.getGcInfo().getMemoryUsageAfterGc();
10
- for (Entry<String, MemoryUsage> entry : mem.entrySet()) {
11
- String name = entry.getKey();
12
- MemoryUsage memdetail = entry.getValue();
13
- long memInit = memdetail.getInit();
14
- long memCommitted = memdetail.getCommitted();
15
- long memMax = memdetail.getMax();
16
- long memUsed = memdetail.getUsed();
17
- MemoryUsage before = membefore.get(name);
18
- long beforepercent = ((before.getUsed() * 1000L) / before.getCommitted());
19
- long percent = ((memUsed * 1000L) / before.getCommitted()); //>100% when it gets expanded
20
-
21
- System.out.print(name + (memCommitted == memMax ? "(fully expanded)" : "(still expandable)") + "used: " + (beforepercent / 10) + "." + (beforepercent % 10) + "%->" + (percent / 10) + "." + (percent % 10) + "%(" + ((memUsed / 1048576) + 1) + "MB) / ");
22
- }
23
- System.out.println();
24
- totalGcDuration += info.getGcInfo().getDuration();
25
- long percent = totalGcDuration * 1000L / info.getGcInfo().getEndTime();
26
- System.out.println("GC cumulated overhead " + (percent / 10) + "." + (percent % 10) + "%");
data/lib/LogGC_1.java DELETED
@@ -1,68 +0,0 @@
1
- //
2
- // http://docs.oracle.com/javase/7/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html
3
- public class LogGC {
4
-
5
- public static void installGCMonitoring() {
6
- //get all the GarbageCollectorMXBeans - there's one for each heap generation
7
- //so probably two - the old generation and young generation
8
- List<GarbageCollectorMXBean> gcbeans = java.lang.management.ManagementFactory.getGarbageCollectorMXBeans();
9
- //Install a notifcation handler for each bean
10
- for (GarbageCollectorMXBean gcbean : gcbeans) {
11
- System.out.println(gcbean);
12
- NotificationEmitter emitter = (NotificationEmitter) gcbean;
13
- //use an anonymously generated listener for this example
14
- // - proper code should really use a named class
15
- NotificationListener listener = new NotificationListener() {
16
- //keep a count of the total time spent in GCs
17
- long totalGcDuration = 0;
18
-
19
- //implement the notifier callback handler
20
- @Override
21
- public void handleNotification(Notification notification, Object handback) {
22
- //we only handle GARBAGE_COLLECTION_NOTIFICATION notifications here
23
- if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
24
- //get the information associated with this notification
25
- GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
26
- //get all the info and pretty print it
27
- long duration = info.getGcInfo().getDuration();
28
- String gctype = info.getGcAction();
29
- if ("end of minor GC".equals(gctype)) {
30
- gctype = "Young Gen GC";
31
- } else if ("end of major GC".equals(gctype)) {
32
- gctype = "Old Gen GC";
33
- }
34
- System.out.println();
35
- System.out.println(gctype + ": - " + info.getGcInfo().getId() + " " + info.getGcName() + " (from " + info.getGcCause() + ") " + duration + " microseconds; start-end times " + info.getGcInfo().getStartTime() + "-" + info.getGcInfo().getEndTime());
36
- //System.out.println("GcInfo CompositeType: " + info.getGcInfo().getCompositeType());
37
- //System.out.println("GcInfo MemoryUsageAfterGc: " + info.getGcInfo().getMemoryUsageAfterGc());
38
- //System.out.println("GcInfo MemoryUsageBeforeGc: " + info.getGcInfo().getMemoryUsageBeforeGc());
39
-
40
- //Get the information about each memory space, and pretty print it
41
- Map<String, MemoryUsage> membefore = info.getGcInfo().getMemoryUsageBeforeGc();
42
- Map<String, MemoryUsage> mem = info.getGcInfo().getMemoryUsageAfterGc();
43
- for (Entry<String, MemoryUsage> entry : mem.entrySet()) {
44
- String name = entry.getKey();
45
- MemoryUsage memdetail = entry.getValue();
46
- long memInit = memdetail.getInit();
47
- long memCommitted = memdetail.getCommitted();
48
- long memMax = memdetail.getMax();
49
- long memUsed = memdetail.getUsed();
50
- MemoryUsage before = membefore.get(name);
51
- long beforepercent = ((before.getUsed() * 1000L) / before.getCommitted());
52
- long percent = ((memUsed * 1000L) / before.getCommitted()); //>100% when it gets expanded
53
-
54
- System.out.print(name + (memCommitted == memMax ? "(fully expanded)" : "(still expandable)") + "used: " + (beforepercent / 10) + "." + (beforepercent % 10) + "%->" + (percent / 10) + "." + (percent % 10) + "%(" + ((memUsed / 1048576) + 1) + "MB) / ");
55
- }
56
- System.out.println();
57
- totalGcDuration += info.getGcInfo().getDuration();
58
- long percent = totalGcDuration * 1000L / info.getGcInfo().getEndTime();
59
- System.out.println("GC cumulated overhead " + (percent / 10) + "." + (percent % 10) + "%");
60
- }
61
- }
62
- };
63
-
64
- //Add the listener
65
- emitter.addNotificationListener(listener, null, null);
66
- }
67
- }
68
- }