semantic_logger 4.5.0 → 4.12.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.
- checksums.yaml +4 -4
- data/README.md +51 -21
- data/Rakefile +7 -7
- data/lib/semantic_logger/ansi_colors.rb +0 -10
- data/lib/semantic_logger/appender/async.rb +12 -10
- data/lib/semantic_logger/appender/async_batch.rb +7 -3
- data/lib/semantic_logger/appender/bugsnag.rb +43 -30
- data/lib/semantic_logger/appender/elasticsearch.rb +34 -15
- data/lib/semantic_logger/appender/elasticsearch_http.rb +4 -4
- data/lib/semantic_logger/appender/file.rb +249 -67
- data/lib/semantic_logger/appender/graylog.rb +15 -10
- data/lib/semantic_logger/appender/honeybadger.rb +3 -3
- data/lib/semantic_logger/appender/http.rb +41 -20
- data/lib/semantic_logger/appender/io.rb +68 -0
- data/lib/semantic_logger/appender/kafka.rb +46 -31
- data/lib/semantic_logger/appender/mongodb.rb +6 -6
- data/lib/semantic_logger/appender/new_relic.rb +2 -2
- data/lib/semantic_logger/appender/rabbitmq.rb +5 -5
- data/lib/semantic_logger/appender/sentry.rb +7 -7
- data/lib/semantic_logger/appender/sentry_ruby.rb +138 -0
- data/lib/semantic_logger/appender/splunk.rb +7 -5
- data/lib/semantic_logger/appender/splunk_http.rb +6 -5
- data/lib/semantic_logger/appender/syslog.rb +23 -15
- data/lib/semantic_logger/appender/tcp.rb +9 -9
- data/lib/semantic_logger/appender/udp.rb +2 -2
- data/lib/semantic_logger/appender/wrapper.rb +3 -2
- data/lib/semantic_logger/appender.rb +62 -65
- data/lib/semantic_logger/appenders.rb +36 -53
- data/lib/semantic_logger/base.rb +61 -39
- data/lib/semantic_logger/formatters/base.rb +16 -6
- data/lib/semantic_logger/formatters/color.rb +14 -15
- data/lib/semantic_logger/formatters/default.rb +18 -5
- data/lib/semantic_logger/formatters/fluentd.rb +7 -18
- data/lib/semantic_logger/formatters/json.rb +3 -5
- data/lib/semantic_logger/formatters/logfmt.rb +77 -0
- data/lib/semantic_logger/formatters/raw.rb +39 -10
- data/lib/semantic_logger/formatters/signalfx.rb +14 -21
- data/lib/semantic_logger/formatters/syslog.rb +8 -6
- data/lib/semantic_logger/formatters/syslog_cee.rb +9 -7
- data/lib/semantic_logger/formatters.rb +13 -13
- data/lib/semantic_logger/jruby/garbage_collection_logger.rb +4 -2
- data/lib/semantic_logger/levels.rb +9 -7
- data/lib/semantic_logger/log.rb +58 -73
- data/lib/semantic_logger/loggable.rb +8 -1
- data/lib/semantic_logger/logger.rb +19 -11
- data/lib/semantic_logger/metric/new_relic.rb +3 -3
- data/lib/semantic_logger/metric/signalfx.rb +3 -3
- data/lib/semantic_logger/metric/statsd.rb +7 -7
- data/lib/semantic_logger/processor.rb +9 -7
- data/lib/semantic_logger/reporters/minitest.rb +4 -4
- data/lib/semantic_logger/semantic_logger.rb +57 -23
- data/lib/semantic_logger/subscriber.rb +24 -7
- data/lib/semantic_logger/sync.rb +12 -0
- data/lib/semantic_logger/sync_processor.rb +58 -0
- data/lib/semantic_logger/test/capture_log_events.rb +34 -0
- data/lib/semantic_logger/utils.rb +32 -13
- data/lib/semantic_logger/version.rb +1 -1
- data/lib/semantic_logger.rb +27 -22
- metadata +15 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b09c37737f1e42edbeee95b036ba0581d5164d756e13de37aca9b22b3093cd45
|
|
4
|
+
data.tar.gz: 9f66b72480df2371a7d305164e443f9667e1acd5521c1347d54c3841efbfa4c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fb27aa1a6d5dc1f2e0e6505ba9348a7cec091a153763361e8c9c20c21177bf84ac11ac2f21fc37ec994988ba31763dcd5c3134ac40a169ac987ed617eceec46e
|
|
7
|
+
data.tar.gz: 5d084bc8cc57b1e836326eae912667ef6b7a284b0125c0b0acee678af78c01017b9667db9a43df7c0fb38af4998b0ab3128ac05d3e2bce266176e9c4d8fadccd
|
data/README.md
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
# Semantic Logger
|
|
2
|
-
[](https://rubygems.org/gems/semantic_logger) [](https://rubygems.org/gems/semantic_logger) [](https://github.com/reidmorrison/semantic_logger/actions?query=workflow%3Abuild) [](https://rubygems.org/gems/semantic_logger) [](http://opensource.org/licenses/Apache-2.0) 
|
|
3
3
|
|
|
4
4
|
Semantic Logger is a feature rich logging framework, and replacement for existing Ruby & Rails loggers.
|
|
5
5
|
|
|
6
|
-
* https://rocketjob.
|
|
6
|
+
* https://logger.rocketjob.io/
|
|
7
7
|
|
|
8
8
|
## Documentation
|
|
9
9
|
|
|
10
|
-
[Semantic Logger Guide](
|
|
11
|
-
|
|
12
|
-
[Reference Documentation](http://www.rubydoc.info/gems/semantic_logger/)
|
|
13
|
-
|
|
14
|
-
## Upgrading to Semantic Logger v4.4
|
|
15
|
-
|
|
16
|
-
With some forking frameworks it is necessary to call `reopen` after the fork. With v4.4 the
|
|
17
|
-
workaround for Ruby 2.5 crashes is no longer needed.
|
|
18
|
-
I.e. Please remove the following line if being called anywhere:
|
|
19
|
-
|
|
20
|
-
~~~ruby
|
|
21
|
-
SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
|
|
22
|
-
~~~
|
|
10
|
+
[Semantic Logger Guide](https://logger.rocketjob.io/)
|
|
23
11
|
|
|
24
12
|
## Logging Destinations
|
|
25
13
|
|
|
@@ -34,7 +22,7 @@ Logging to the following destinations are all supported "out-of-the-box":
|
|
|
34
22
|
* Splunk
|
|
35
23
|
* MongoDB
|
|
36
24
|
* Honeybadger
|
|
37
|
-
* Sentry
|
|
25
|
+
* Sentry (both with legacy `sentry-raven` and modern `sentry-ruby` gem)
|
|
38
26
|
* HTTP
|
|
39
27
|
* TCP
|
|
40
28
|
* UDP
|
|
@@ -50,7 +38,7 @@ handles saving log information to multiple destinations / appenders.
|
|
|
50
38
|
|
|
51
39
|
## Rails
|
|
52
40
|
|
|
53
|
-
When running Rails, use [rails_semantic_logger](http://github.com/
|
|
41
|
+
When running Rails, use [rails_semantic_logger](http://github.com/reidmorrison/rails_semantic_logger)
|
|
54
42
|
instead of Semantic Logger directly since it will automatically replace the Rails default logger with Semantic Logger.
|
|
55
43
|
|
|
56
44
|
## Rocket Job
|
|
@@ -72,11 +60,53 @@ and are therefore not automatically included by this gem:
|
|
|
72
60
|
- Splunk Appender: gem 'splunk-sdk-ruby'
|
|
73
61
|
- Elasticsearch Appender: gem 'elasticsearch'
|
|
74
62
|
- Kafka Appender: gem 'ruby-kafka'
|
|
63
|
+
- Legacy Sentry Appender: gem 'sentry-raven' (deprecated)
|
|
64
|
+
- Sentry Appender: gem 'sentry-ruby'
|
|
65
|
+
|
|
66
|
+
## Upgrading to Semantic Logger v4.9
|
|
67
|
+
|
|
68
|
+
These changes should not be noticeable by the majority of users of Semantic Logger, since
|
|
69
|
+
they are to the internal API. It is possible that advanced users may be using these internal
|
|
70
|
+
API's directly.
|
|
71
|
+
|
|
72
|
+
This does not affect any calls to the public api `SemanticLogger.add_appender`.
|
|
73
|
+
|
|
74
|
+
File and IO are now separate appenders. When creating the File appender explicitly, its arguments
|
|
75
|
+
have changed. For example, when requesting an IO stream, it needs to be changed from:
|
|
76
|
+
|
|
77
|
+
~~~ruby
|
|
78
|
+
SemanticLogger::Appender::File.new(io: $stderr)
|
|
79
|
+
~~~
|
|
80
|
+
to:
|
|
81
|
+
~~~ruby
|
|
82
|
+
SemanticLogger::Appender::IO.new($stderr)
|
|
83
|
+
~~~
|
|
84
|
+
|
|
85
|
+
Additionally, this needs to be changed from:
|
|
86
|
+
~~~ruby
|
|
87
|
+
SemanticLogger::Appender::File.new(file_name: "file.log")
|
|
88
|
+
~~~
|
|
89
|
+
to:
|
|
90
|
+
~~~ruby
|
|
91
|
+
SemanticLogger::Appender::File.new("file.log")
|
|
92
|
+
~~~
|
|
93
|
+
|
|
94
|
+
Rails Semantic Logger, if used, needs to be upgraded to v4.9 when upgrading to Semantic Logger v4.9.
|
|
95
|
+
|
|
96
|
+
## Upgrading to Semantic Logger v4.4
|
|
97
|
+
|
|
98
|
+
With some forking frameworks it is necessary to call `reopen` after the fork. With v4.4 the
|
|
99
|
+
workaround for Ruby 2.5 crashes is no longer needed.
|
|
100
|
+
I.e. Please remove the following line if being called anywhere:
|
|
101
|
+
|
|
102
|
+
~~~ruby
|
|
103
|
+
SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
|
|
104
|
+
~~~
|
|
75
105
|
|
|
76
|
-
##
|
|
106
|
+
## Upgrading to Semantic Logger v4.0
|
|
77
107
|
|
|
78
108
|
The following changes need to be made when upgrading to V4:
|
|
79
|
-
- Ruby V2.
|
|
109
|
+
- Ruby V2.3 / JRuby V9.1 is now the minimum runtime version.
|
|
80
110
|
- Replace calls to Logger#with_payload with SemanticLogger.named_tagged.
|
|
81
111
|
- Replace calls to Logger#payload with SemanticLogger.named_tags.
|
|
82
112
|
- MongoDB Appender requires Mongo Ruby Client V2 or greater.
|
|
@@ -129,13 +159,13 @@ SemanticLogger.default_level = :trace
|
|
|
129
159
|
SemanticLogger.add_appender(file_name: 'development.log', formatter: :color)
|
|
130
160
|
~~~
|
|
131
161
|
|
|
132
|
-
If running rails, see: [Semantic Logger Rails](
|
|
162
|
+
If running rails, see: [Semantic Logger Rails](https://logger.rocketjob.io/rails.html)
|
|
133
163
|
|
|
134
164
|
## Author
|
|
135
165
|
|
|
136
166
|
[Reid Morrison](https://github.com/reidmorrison)
|
|
137
167
|
|
|
138
|
-
[Contributors](https://github.com/
|
|
168
|
+
[Contributors](https://github.com/reidmorrison/semantic_logger/graphs/contributors)
|
|
139
169
|
|
|
140
170
|
## Versioning
|
|
141
171
|
|
data/Rakefile
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "rake/clean"
|
|
2
|
+
require "rake/testtask"
|
|
3
3
|
|
|
4
|
-
$LOAD_PATH.unshift File.expand_path(
|
|
5
|
-
require
|
|
4
|
+
$LOAD_PATH.unshift File.expand_path("lib", __dir__)
|
|
5
|
+
require "semantic_logger/version"
|
|
6
6
|
|
|
7
7
|
task :gem do
|
|
8
|
-
system
|
|
8
|
+
system "gem build semantic_logger.gemspec"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
task publish: :gem do
|
|
12
12
|
system "git tag -a v#{SemanticLogger::VERSION} -m 'Tagging #{SemanticLogger::VERSION}'"
|
|
13
|
-
system
|
|
13
|
+
system "git push --tags"
|
|
14
14
|
system "gem push semantic_logger-#{SemanticLogger::VERSION}.gem"
|
|
15
15
|
system "rm semantic_logger-#{SemanticLogger::VERSION}.gem"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
Rake::TestTask.new(:test) do |t|
|
|
19
|
-
t.pattern =
|
|
19
|
+
t.pattern = "test/**/*_test.rb"
|
|
20
20
|
t.verbose = true
|
|
21
21
|
t.warning = false
|
|
22
22
|
end
|
|
@@ -11,15 +11,5 @@ module SemanticLogger
|
|
|
11
11
|
MAGENTA = "\e[35m".freeze
|
|
12
12
|
CYAN = "\e[36m".freeze
|
|
13
13
|
WHITE = "\e[37m".freeze
|
|
14
|
-
|
|
15
|
-
# DEPRECATED - NOT USED
|
|
16
|
-
LEVEL_MAP = {
|
|
17
|
-
trace: MAGENTA,
|
|
18
|
-
debug: GREEN,
|
|
19
|
-
info: CYAN,
|
|
20
|
-
warn: BOLD,
|
|
21
|
-
error: RED,
|
|
22
|
-
fatal: RED
|
|
23
|
-
}.freeze
|
|
24
14
|
end
|
|
25
15
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "forwardable"
|
|
2
2
|
|
|
3
3
|
module SemanticLogger
|
|
4
4
|
module Appender
|
|
@@ -15,6 +15,7 @@ module SemanticLogger
|
|
|
15
15
|
def_delegator :@appender, :filter
|
|
16
16
|
def_delegator :@appender, :host
|
|
17
17
|
def_delegator :@appender, :application
|
|
18
|
+
def_delegator :@appender, :environment
|
|
18
19
|
def_delegator :@appender, :level
|
|
19
20
|
def_delegator :@appender, :level=
|
|
20
21
|
def_delegator :@appender, :logger
|
|
@@ -52,13 +53,13 @@ module SemanticLogger
|
|
|
52
53
|
# Re-open appender after a fork
|
|
53
54
|
def reopen
|
|
54
55
|
# Workaround CRuby crash on fork by recreating queue on reopen
|
|
55
|
-
# https://github.com/
|
|
56
|
+
# https://github.com/reidmorrison/semantic_logger/issues/103
|
|
56
57
|
@queue&.close
|
|
57
58
|
create_queue
|
|
58
59
|
|
|
59
60
|
appender.reopen if appender.respond_to?(:reopen)
|
|
60
61
|
|
|
61
|
-
@thread
|
|
62
|
+
@thread&.kill if @thread&.alive?
|
|
62
63
|
@thread = Thread.new { process }
|
|
63
64
|
end
|
|
64
65
|
|
|
@@ -72,6 +73,7 @@ module SemanticLogger
|
|
|
72
73
|
# Starts the worker thread if not running.
|
|
73
74
|
def thread
|
|
74
75
|
return @thread if @thread&.alive?
|
|
76
|
+
|
|
75
77
|
@thread = Thread.new { process }
|
|
76
78
|
end
|
|
77
79
|
|
|
@@ -114,21 +116,21 @@ module SemanticLogger
|
|
|
114
116
|
# This thread is designed to never go down unless the main thread terminates
|
|
115
117
|
# or the appender is closed.
|
|
116
118
|
Thread.current.name = logger.name
|
|
117
|
-
logger.trace
|
|
119
|
+
logger.trace "Async: Appender thread active"
|
|
118
120
|
begin
|
|
119
121
|
process_messages
|
|
120
|
-
rescue StandardError =>
|
|
122
|
+
rescue StandardError => e
|
|
121
123
|
# This block may be called after the file handles have been released by Ruby
|
|
122
124
|
begin
|
|
123
|
-
logger.error(
|
|
125
|
+
logger.error("Async: Restarting due to exception", e)
|
|
124
126
|
rescue StandardError
|
|
125
127
|
nil
|
|
126
128
|
end
|
|
127
129
|
retry
|
|
128
|
-
rescue Exception =>
|
|
130
|
+
rescue Exception => e
|
|
129
131
|
# This block may be called after the file handles have been released by Ruby
|
|
130
132
|
begin
|
|
131
|
-
logger.error(
|
|
133
|
+
logger.error("Async: Stopping due to fatal exception", e)
|
|
132
134
|
rescue StandardError
|
|
133
135
|
nil
|
|
134
136
|
end
|
|
@@ -136,7 +138,7 @@ module SemanticLogger
|
|
|
136
138
|
@thread = nil
|
|
137
139
|
# This block may be called after the file handles have been released by Ruby
|
|
138
140
|
begin
|
|
139
|
-
logger.trace(
|
|
141
|
+
logger.trace("Async: Thread has stopped")
|
|
140
142
|
rescue StandardError
|
|
141
143
|
nil
|
|
142
144
|
end
|
|
@@ -158,7 +160,7 @@ module SemanticLogger
|
|
|
158
160
|
break unless process_message(message)
|
|
159
161
|
end
|
|
160
162
|
end
|
|
161
|
-
logger.trace
|
|
163
|
+
logger.trace "Async: Queue Closed"
|
|
162
164
|
end
|
|
163
165
|
|
|
164
166
|
# Returns false when message processing should be stopped
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "concurrent"
|
|
2
2
|
|
|
3
3
|
module SemanticLogger
|
|
4
4
|
module Appender
|
|
@@ -42,7 +42,9 @@ module SemanticLogger
|
|
|
42
42
|
lag_threshold_s: lag_threshold_s
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
return if appender.respond_to?(:batch)
|
|
46
|
+
|
|
47
|
+
raise(ArgumentError, "#{appender.class.name} does not support batching. It must implement #batch")
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
# Add log message for processing.
|
|
@@ -62,6 +64,7 @@ module SemanticLogger
|
|
|
62
64
|
signal.wait(batch_seconds)
|
|
63
65
|
|
|
64
66
|
logs = []
|
|
67
|
+
messages = []
|
|
65
68
|
first = true
|
|
66
69
|
message_count = queue.length
|
|
67
70
|
message_count.times do
|
|
@@ -74,10 +77,11 @@ module SemanticLogger
|
|
|
74
77
|
first = false
|
|
75
78
|
end
|
|
76
79
|
else
|
|
77
|
-
|
|
80
|
+
messages << message
|
|
78
81
|
end
|
|
79
82
|
end
|
|
80
83
|
appender.batch(logs) if logs.size.positive?
|
|
84
|
+
messages.each { |message| process_message(message) }
|
|
81
85
|
signal.reset unless queue.size >= batch_size
|
|
82
86
|
end
|
|
83
87
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
begin
|
|
2
|
-
require
|
|
2
|
+
require "bugsnag"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
raise 'Gem bugsnag is required for logging purposes. Please add the gem "bugsnag" to your Gemfile.'
|
|
4
|
+
raise LoadError, 'Gem bugsnag is required for logging purposes. Please add the gem "bugsnag" to your Gemfile.'
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
# Send log messages to Bugsnag
|
|
@@ -30,7 +30,7 @@ module SemanticLogger
|
|
|
30
30
|
# Proc: Only include log messages where the supplied Proc returns true
|
|
31
31
|
# The Proc must return true or false.
|
|
32
32
|
def initialize(level: :error, **args, &block)
|
|
33
|
-
raise
|
|
33
|
+
raise "Bugsnag only supports :info, :warn, or :error log levels" unless %i[info warn error fatal].include?(level)
|
|
34
34
|
|
|
35
35
|
# Replace the Bugsnag logger so that we can identify its log messages and not forward them to Bugsnag
|
|
36
36
|
::Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] }
|
|
@@ -40,48 +40,61 @@ module SemanticLogger
|
|
|
40
40
|
|
|
41
41
|
# Returns [Hash] of parameters to send to Bugsnag.
|
|
42
42
|
def call(log, logger)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
hash = SemanticLogger::Formatters::Raw.new.call(log, logger)
|
|
44
|
+
hash.delete(:message) if hash[:exception] && (hash[:message] == hash[:exception][:message])
|
|
45
|
+
hash.delete(:time)
|
|
46
|
+
hash.delete(:level_index)
|
|
47
|
+
hash.delete(:exception)
|
|
48
|
+
hash[:file] = "#{hash[:file]}:#{hash.delete(:line)}" if hash.key?(:file)
|
|
49
|
+
hash
|
|
49
50
|
end
|
|
50
51
|
|
|
51
|
-
# Send an error notification to Bugsnag
|
|
52
52
|
def log(log)
|
|
53
53
|
# Ignore logs coming from Bugsnag itself
|
|
54
|
-
return false if log.name ==
|
|
54
|
+
return false if log.name == "Bugsnag"
|
|
55
55
|
|
|
56
56
|
# Send error messages as Runtime exceptions
|
|
57
|
-
exception =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
log.exception.set_backtrace(log.backtrace) if !log.exception.backtrace && log.backtrace
|
|
61
|
-
log.exception
|
|
62
|
-
else
|
|
63
|
-
error = RuntimeError.new(log.message)
|
|
64
|
-
error.set_backtrace(log.backtrace) if log.backtrace
|
|
65
|
-
error
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# For more documentation on the Bugsnag.notify method see:
|
|
69
|
-
# https://bugsnag.com/docs/notifiers/ruby#sending-handled-exceptions
|
|
70
|
-
::Bugsnag.notify(exception, formatter.call(log, self))
|
|
57
|
+
exception = extract_exception(log)
|
|
58
|
+
hash = formatter.call(log, self)
|
|
59
|
+
bugsnag_notify(exception, hash, log_level(log.level))
|
|
71
60
|
true
|
|
72
61
|
end
|
|
73
62
|
|
|
74
63
|
private
|
|
75
64
|
|
|
65
|
+
def bugsnag_notify(exception, hash, level)
|
|
66
|
+
if ::Bugsnag::VERSION.to_i >= 6
|
|
67
|
+
::Bugsnag.notify(exception) do |report|
|
|
68
|
+
report.severity = level
|
|
69
|
+
hash.each_pair { |key, value| report.add_tab(key, value) }
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
hash[:severity] = level
|
|
73
|
+
::Bugsnag.notify(exception, hash)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def extract_exception(log)
|
|
78
|
+
if log.exception
|
|
79
|
+
# Manually constructed Exception, without a backtrace.
|
|
80
|
+
log.exception.set_backtrace(log.backtrace) if !log.exception.backtrace && log.backtrace
|
|
81
|
+
return log.exception
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
error = RuntimeError.new(log.message)
|
|
85
|
+
error.set_backtrace(log.backtrace) if log.backtrace
|
|
86
|
+
error
|
|
87
|
+
end
|
|
88
|
+
|
|
76
89
|
# Bugsnag supports: error, warning or info
|
|
77
|
-
def log_level(
|
|
78
|
-
case
|
|
90
|
+
def log_level(level)
|
|
91
|
+
case level
|
|
79
92
|
when :error, :fatal
|
|
80
|
-
|
|
93
|
+
"error"
|
|
81
94
|
when :warn
|
|
82
|
-
|
|
95
|
+
"warning"
|
|
83
96
|
else
|
|
84
|
-
|
|
97
|
+
"info"
|
|
85
98
|
end
|
|
86
99
|
end
|
|
87
100
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
begin
|
|
2
|
-
require
|
|
2
|
+
require "elasticsearch"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
raise
|
|
4
|
+
raise LoadError,
|
|
5
|
+
'Gem elasticsearch is required for logging to Elasticsearch. Please add the gem "elasticsearch" to your Gemfile.'
|
|
5
6
|
end
|
|
6
7
|
|
|
7
|
-
require
|
|
8
|
+
require "date"
|
|
8
9
|
|
|
9
10
|
# Forward all log messages to Elasticsearch.
|
|
10
11
|
#
|
|
@@ -17,7 +18,8 @@ require 'date'
|
|
|
17
18
|
module SemanticLogger
|
|
18
19
|
module Appender
|
|
19
20
|
class Elasticsearch < SemanticLogger::Subscriber
|
|
20
|
-
attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size,
|
|
21
|
+
attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size,
|
|
22
|
+
:elasticsearch_args
|
|
21
23
|
|
|
22
24
|
# Create Elasticsearch appender over persistent HTTP(S)
|
|
23
25
|
#
|
|
@@ -123,16 +125,17 @@ module SemanticLogger
|
|
|
123
125
|
# send_get_body_as [String]
|
|
124
126
|
# Specify the HTTP method to use for GET requests with a body.
|
|
125
127
|
# Default: 'GET'
|
|
126
|
-
def initialize(url:
|
|
127
|
-
index:
|
|
128
|
-
date_pattern:
|
|
129
|
-
type:
|
|
128
|
+
def initialize(url: "http://localhost:9200",
|
|
129
|
+
index: "semantic_logger",
|
|
130
|
+
date_pattern: "%Y.%m.%d",
|
|
131
|
+
type: "log",
|
|
130
132
|
level: nil,
|
|
131
133
|
formatter: nil,
|
|
132
134
|
filter: nil,
|
|
133
135
|
application: nil,
|
|
136
|
+
environment: nil,
|
|
134
137
|
host: nil,
|
|
135
|
-
|
|
138
|
+
data_stream: false,
|
|
136
139
|
**elasticsearch_args,
|
|
137
140
|
&block)
|
|
138
141
|
|
|
@@ -143,8 +146,9 @@ module SemanticLogger
|
|
|
143
146
|
@elasticsearch_args = elasticsearch_args.dup
|
|
144
147
|
@elasticsearch_args[:url] = url if url && !elasticsearch_args[:hosts]
|
|
145
148
|
@elasticsearch_args[:logger] = logger
|
|
149
|
+
@data_stream = data_stream
|
|
146
150
|
|
|
147
|
-
super(level: level, formatter: formatter, filter: filter, application: application, host: host, metrics: false, &block)
|
|
151
|
+
super(level: level, formatter: formatter, filter: filter, application: application, environment: environment, host: host, metrics: false, &block)
|
|
148
152
|
reopen
|
|
149
153
|
end
|
|
150
154
|
|
|
@@ -172,20 +176,35 @@ module SemanticLogger
|
|
|
172
176
|
private
|
|
173
177
|
|
|
174
178
|
def write_to_elasticsearch(messages)
|
|
175
|
-
bulk_result = @
|
|
176
|
-
|
|
179
|
+
bulk_result = if @data_stream
|
|
180
|
+
@client.bulk(index: index, body: messages)
|
|
181
|
+
else
|
|
182
|
+
@client.bulk(body: messages)
|
|
183
|
+
end
|
|
177
184
|
|
|
178
|
-
|
|
185
|
+
return unless bulk_result["errors"]
|
|
186
|
+
|
|
187
|
+
failed = bulk_result["items"].reject { |x| x["status"] == 201 }
|
|
179
188
|
logger.error("ElasticSearch: Write failed. Messages discarded. : #{failed}")
|
|
180
189
|
end
|
|
181
190
|
|
|
182
191
|
def bulk_index(log)
|
|
183
192
|
expanded_index_name = log.time.strftime("#{index}-#{date_pattern}")
|
|
184
|
-
|
|
193
|
+
if @data_stream
|
|
194
|
+
{"create" => {}}
|
|
195
|
+
else
|
|
196
|
+
{"index" => {"_index" => expanded_index_name, "_type" => type}}
|
|
197
|
+
end
|
|
185
198
|
end
|
|
186
199
|
|
|
187
200
|
def default_formatter
|
|
188
|
-
|
|
201
|
+
time_key = if @data_stream
|
|
202
|
+
"@timestamp"
|
|
203
|
+
else
|
|
204
|
+
:timestamp
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
SemanticLogger::Formatters::Raw.new(time_format: :iso_8601, time_key: time_key)
|
|
189
208
|
end
|
|
190
209
|
end
|
|
191
210
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "date"
|
|
2
2
|
# Forward all log messages to Elasticsearch one at a time via a HTTP post.
|
|
3
3
|
#
|
|
4
4
|
# Note:
|
|
@@ -50,9 +50,9 @@ module SemanticLogger
|
|
|
50
50
|
# application: [String]
|
|
51
51
|
# Name of this application to appear in log messages.
|
|
52
52
|
# Default: SemanticLogger.application
|
|
53
|
-
def initialize(index:
|
|
54
|
-
type:
|
|
55
|
-
url:
|
|
53
|
+
def initialize(index: "semantic_logger",
|
|
54
|
+
type: "log",
|
|
55
|
+
url: "http://localhost:9200",
|
|
56
56
|
**http_args,
|
|
57
57
|
&block)
|
|
58
58
|
|