Skip to content

Commit 003b97c

Browse files
authored
Merge pull request reidmorrison#280 from trvsdnn/add-honeybadger-events
Add honeybadger_events appender
2 parents 94641b3 + f57d58b commit 003b97c

File tree

5 files changed

+148
-30
lines changed

5 files changed

+148
-30
lines changed

CHANGELOG.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [4.16.0]
99

10+
- Add appender for Honeybadger Insights using the events API
1011
- Add support for Ruby 3.3.
1112
- Allow SyncProcessor to be called from appenders.
1213
- Fix incorrect metrics usage examples in documentation.
@@ -24,7 +25,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2425
## [4.13.0]
2526

2627
- Replace `autoload` with `require` for most requires since Ruby does not allow a require
27-
during a signal trap for the extreme use case where the logger is called from the signal
28+
during a signal trap for the extreme use case where the logger is called from the signal
2829
trap before the application has made any logging calls.
2930

3031
- Move `newrelic_rpm.rb` mock to the `test/mocks` directory
@@ -58,7 +59,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5859
- Updated RuboCop's target version to Ruby 2.7.5.
5960
- Updated minimum Ruby version to 2.7.5 as earlier versions are
6061
end-of-life.
61-
- Add mutexes to `SemanticLogger.sync!` in case some users are still using it in a
62+
- Add mutexes to `SemanticLogger.sync!` in case some users are still using it in a
6263
multi-threaded environment.
6364

6465
## [4.11.0]

README.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Semantic Logger
22
[![Gem Version](https://img.shields.io/gem/v/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![Build Status](https://github.com/reidmorrison/semantic_logger/workflows/build/badge.svg)](https://github.com/reidmorrison/semantic_logger/actions?query=workflow%3Abuild) [![Downloads](https://img.shields.io/gem/dt/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg)
33

4-
Semantic Logger is a feature rich logging framework, and replacement for existing Ruby & Rails loggers.
4+
Semantic Logger is a feature rich logging framework, and replacement for existing Ruby & Rails loggers.
55

66
* https://logger.rocketjob.io/
77

@@ -21,7 +21,7 @@ Logging to the following destinations are all supported "out-of-the-box":
2121
* NewRelic
2222
* Splunk
2323
* MongoDB
24-
* Honeybadger
24+
* Honeybadger (exceptions and events)
2525
* Sentry (both with legacy `sentry-raven` and modern `sentry-ruby` gem)
2626
* HTTP
2727
* TCP
@@ -54,6 +54,8 @@ The following gems are only required when their corresponding appenders are bein
5454
and are therefore not automatically included by this gem:
5555
- Bugsnag Appender: gem 'bugsnag'
5656
- MongoDB Appender: gem 'mongo' 1.9.2 or above
57+
- Honeybadger Appender: gem 'honeybadger'
58+
- HoneybadgerInsights Appender: gem 'honeybadger'
5759
- NewRelic Appender: gem 'newrelic_rpm'
5860
- NewRelicLogs Appender: gem 'newrelic_rpm'
5961
- Syslog Appender: gem 'syslog_protocol' 0.9.2 or above
@@ -129,16 +131,16 @@ logger.debug payload: {foo: 'foo', bar: 'bar'}
129131
Similarly, for measure blocks:
130132

131133
~~~ruby
132-
logger.measure_info('How long is the sleep', foo: 'foo', bar: 'bar') { sleep 1 }
134+
logger.measure_info('How long is the sleep', foo: 'foo', bar: 'bar') { sleep 1 }
133135
~~~
134136

135137
Must be replaced with the following in v4:
136138

137139
~~~ruby
138-
logger.measure_info('How long is the sleep', payload: {foo: 'foo', bar: 'bar'}) { sleep 1 }
140+
logger.measure_info('How long is the sleep', payload: {foo: 'foo', bar: 'bar'}) { sleep 1 }
139141
~~~
140142

141-
The common log call has not changed, and the payload is still logged directly:
143+
The common log call has not changed, and the payload is still logged directly:
142144

143145
~~~ruby
144146
logger.debug('log this', foo: 'foo', bar: 'bar')

lib/semantic_logger/appender.rb

+24-23
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
module SemanticLogger
22
module Appender
33
# @formatter:off
4-
autoload :Async, "semantic_logger/appender/async"
5-
autoload :AsyncBatch, "semantic_logger/appender/async_batch"
6-
autoload :Bugsnag, "semantic_logger/appender/bugsnag"
7-
autoload :Elasticsearch, "semantic_logger/appender/elasticsearch"
8-
autoload :ElasticsearchHttp, "semantic_logger/appender/elasticsearch_http"
9-
autoload :File, "semantic_logger/appender/file"
10-
autoload :Graylog, "semantic_logger/appender/graylog"
11-
autoload :Honeybadger, "semantic_logger/appender/honeybadger"
12-
autoload :IO, "semantic_logger/appender/io"
13-
autoload :Kafka, "semantic_logger/appender/kafka"
14-
autoload :Sentry, "semantic_logger/appender/sentry"
15-
autoload :Http, "semantic_logger/appender/http"
16-
autoload :MongoDB, "semantic_logger/appender/mongodb"
17-
autoload :NewRelic, "semantic_logger/appender/new_relic"
18-
autoload :NewRelicLogs, "semantic_logger/appender/new_relic_logs"
19-
autoload :Rabbitmq, "semantic_logger/appender/rabbitmq"
20-
autoload :Splunk, "semantic_logger/appender/splunk"
21-
autoload :SplunkHttp, "semantic_logger/appender/splunk_http"
22-
autoload :Syslog, "semantic_logger/appender/syslog"
23-
autoload :Tcp, "semantic_logger/appender/tcp"
24-
autoload :Udp, "semantic_logger/appender/udp"
25-
autoload :Wrapper, "semantic_logger/appender/wrapper"
26-
autoload :SentryRuby, "semantic_logger/appender/sentry_ruby"
4+
autoload :Async, "semantic_logger/appender/async"
5+
autoload :AsyncBatch, "semantic_logger/appender/async_batch"
6+
autoload :Bugsnag, "semantic_logger/appender/bugsnag"
7+
autoload :Elasticsearch, "semantic_logger/appender/elasticsearch"
8+
autoload :ElasticsearchHttp, "semantic_logger/appender/elasticsearch_http"
9+
autoload :File, "semantic_logger/appender/file"
10+
autoload :Graylog, "semantic_logger/appender/graylog"
11+
autoload :Honeybadger, "semantic_logger/appender/honeybadger"
12+
autoload :HoneybadgerInsights, "semantic_logger/appender/honeybadger_insights"
13+
autoload :IO, "semantic_logger/appender/io"
14+
autoload :Kafka, "semantic_logger/appender/kafka"
15+
autoload :Sentry, "semantic_logger/appender/sentry"
16+
autoload :Http, "semantic_logger/appender/http"
17+
autoload :MongoDB, "semantic_logger/appender/mongodb"
18+
autoload :NewRelic, "semantic_logger/appender/new_relic"
19+
autoload :NewRelicLogs, "semantic_logger/appender/new_relic_logs"
20+
autoload :Rabbitmq, "semantic_logger/appender/rabbitmq"
21+
autoload :Splunk, "semantic_logger/appender/splunk"
22+
autoload :SplunkHttp, "semantic_logger/appender/splunk_http"
23+
autoload :Syslog, "semantic_logger/appender/syslog"
24+
autoload :Tcp, "semantic_logger/appender/tcp"
25+
autoload :Udp, "semantic_logger/appender/udp"
26+
autoload :Wrapper, "semantic_logger/appender/wrapper"
27+
autoload :SentryRuby, "semantic_logger/appender/sentry_ruby"
2728
# @formatter:on
2829

2930
# Returns [SemanticLogger::Subscriber] appender for the supplied options
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
begin
2+
require "honeybadger"
3+
rescue LoadError
4+
raise LoadError, 'Gem honeybadger is required for logging purposes. Please add the gem "honeybadger" to your Gemfile.'
5+
end
6+
7+
# Send log messages to honeybadger events/insights API
8+
#
9+
# Example:
10+
# SemanticLogger.add_appender(appender: :honeybadger_insights)
11+
#
12+
module SemanticLogger
13+
module Appender
14+
class HoneybadgerInsights < SemanticLogger::Subscriber
15+
# Honeybadger Appender
16+
#
17+
# Parameters
18+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
19+
# Override the log level for this appender.
20+
# Default: :error
21+
#
22+
# formatter: [Object|Proc|Symbol|Hash]
23+
# An instance of a class that implements #call, or a Proc to be used to format
24+
# the output from this appender
25+
# Default: Use the built-in formatter (See: #call)
26+
#
27+
# filter: [Regexp|Proc]
28+
# RegExp: Only include log messages where the class name matches the supplied.
29+
# regular expression. All other messages will be ignored.
30+
# Proc: Only include log messages where the supplied Proc returns true
31+
# The Proc must return true or false.
32+
#
33+
# host: [String]
34+
# Name of this host to appear in log messages.
35+
# Default: SemanticLogger.host
36+
#
37+
# application: [String]
38+
# Name of this application to appear in log messages.
39+
# Default: SemanticLogger.application
40+
def initialize(level: :info, **args, &block)
41+
super(level: level, **args, &block)
42+
end
43+
44+
# Send log to honeybadger events API
45+
def log(log)
46+
event = formatter.call(log, self)
47+
48+
::Honeybadger.event(event)
49+
50+
true
51+
end
52+
53+
private
54+
55+
# Use Raw Formatter by default
56+
def default_formatter
57+
SemanticLogger::Formatters::Raw.new(time_key: :ts, time_format: :rfc_3339)
58+
end
59+
end
60+
end
61+
end
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
require_relative "../test_helper"
2+
3+
# Unit Test for SemanticLogger::Appender::HoneybadgerInsights
4+
module Appender
5+
class HoneybadgerInsightsTest < Minitest::Test
6+
describe SemanticLogger::Appender::HoneybadgerInsights do
7+
before do
8+
@appender = SemanticLogger::Appender::HoneybadgerInsights.new(level: :trace)
9+
@message = "AppenderHoneybadgerInsightsTest log message"
10+
end
11+
12+
SemanticLogger::Levels::LEVELS.each do |level|
13+
it "sends :#{level} notifications to Honeybadger" do
14+
hash = nil
15+
Honeybadger.stub(:event, ->(h) { hash = h }) do
16+
@appender.send(level, @message)
17+
end
18+
19+
refute_nil hash[:ts]
20+
assert_equal @message, hash[:message]
21+
assert_equal level, hash[:level]
22+
end
23+
end
24+
25+
it "send notification to Honeybadger with custom attributes" do
26+
hash = nil
27+
Honeybadger.stub(:event, ->(h) { hash = h }) do
28+
SemanticLogger.tagged("test") do
29+
SemanticLogger.named_tagged(key1: 1, key2: "a") do
30+
@appender.measure_error(message: @message, payload: {key3: 4}) do
31+
sleep 0.001
32+
end
33+
end
34+
end
35+
end
36+
37+
refute_nil hash[:ts]
38+
assert_equal @message, hash[:message]
39+
assert_equal :error, hash[:level]
40+
41+
assert_equal ["test"], hash[:tags]
42+
43+
assert_equal 1, hash[:named_tags][:key1]
44+
assert_equal "a", hash[:named_tags][:key2]
45+
46+
refute_nil hash[:duration]
47+
refute_nil hash[:duration_ms]
48+
49+
assert_equal 4, hash[:payload][:key3]
50+
end
51+
end
52+
end
53+
end

0 commit comments

Comments
 (0)