semantic_logger 4.6.1 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +50 -20
- data/Rakefile +7 -7
- data/lib/semantic_logger/appender/async.rb +10 -9
- 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 +32 -14
- 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 +12 -10
- data/lib/semantic_logger/appender/honeybadger.rb +3 -3
- data/lib/semantic_logger/appender/http.rb +20 -18
- data/lib/semantic_logger/appender/io.rb +68 -0
- data/lib/semantic_logger/appender/kafka.rb +9 -5
- 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 +6 -5
- data/lib/semantic_logger/appender/splunk_http.rb +6 -6
- data/lib/semantic_logger/appender/syslog.rb +23 -15
- data/lib/semantic_logger/appender/tcp.rb +5 -5
- data/lib/semantic_logger/appender/udp.rb +2 -2
- data/lib/semantic_logger/appender/wrapper.rb +3 -2
- data/lib/semantic_logger/appender.rb +42 -36
- data/lib/semantic_logger/appenders.rb +34 -30
- data/lib/semantic_logger/base.rb +57 -27
- data/lib/semantic_logger/formatters/base.rb +9 -3
- data/lib/semantic_logger/formatters/color.rb +12 -8
- data/lib/semantic_logger/formatters/default.rb +18 -5
- data/lib/semantic_logger/formatters/fluentd.rb +3 -3
- data/lib/semantic_logger/formatters/json.rb +1 -1
- data/lib/semantic_logger/formatters/logfmt.rb +72 -0
- data/lib/semantic_logger/formatters/raw.rb +31 -7
- data/lib/semantic_logger/formatters/signalfx.rb +10 -9
- data/lib/semantic_logger/formatters/syslog.rb +8 -6
- data/lib/semantic_logger/formatters/syslog_cee.rb +8 -6
- data/lib/semantic_logger/formatters.rb +12 -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 +51 -61
- 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 +40 -19
- data/lib/semantic_logger/subscriber.rb +16 -5
- data/lib/semantic_logger/sync.rb +12 -0
- data/lib/semantic_logger/sync_processor.rb +43 -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
@@ -1,7 +1,7 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "bunny"
|
3
3
|
rescue LoadError
|
4
|
-
raise LoadError
|
4
|
+
raise LoadError, 'Gem bunny is required for logging to RabbitMQ. Please add the gem "bunny" to your Gemfile.'
|
5
5
|
end
|
6
6
|
|
7
7
|
# Forward all log messages to RabbitMQ.
|
@@ -14,7 +14,7 @@ end
|
|
14
14
|
# # Name of the queue in RabbitMQ where to publish the logs. This queue will be bound to "amqp.direct" exchange.
|
15
15
|
# queue: 'semantic_logger',
|
16
16
|
#
|
17
|
-
# # This host will be used for RabbitMQ connection.
|
17
|
+
# # This host will be used for RabbitMQ connection.
|
18
18
|
# # NOTE this is different than :host option which is used by the logger directly.
|
19
19
|
# rabbitmq_host: '127.0.0.1',
|
20
20
|
#
|
@@ -63,7 +63,7 @@ module SemanticLogger
|
|
63
63
|
# RabbitMQ Parameters:
|
64
64
|
#
|
65
65
|
# rabbitmq_host: [String]
|
66
|
-
# Host for AMQP connection. in Bunny this is called :host but here it has
|
66
|
+
# Host for AMQP connection. in Bunny this is called :host but here it has
|
67
67
|
# been remapped to avoid conflicting with SemanticLogger's :host param.
|
68
68
|
# Default: localhost
|
69
69
|
#
|
@@ -76,7 +76,7 @@ module SemanticLogger
|
|
76
76
|
# Default: nil
|
77
77
|
#
|
78
78
|
# more parameters supported by Bunny: http://rubybunny.info/articles/connecting.html
|
79
|
-
def initialize(queue_name:
|
79
|
+
def initialize(queue_name: "semantic_logger", rabbitmq_host: nil, metrics: false, **args, &block)
|
80
80
|
@queue_name = queue_name
|
81
81
|
@rabbitmq_args = args.dup
|
82
82
|
@rabbitmq_args[:host] = rabbitmq_host
|
@@ -1,7 +1,7 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "sentry-raven"
|
3
3
|
rescue LoadError
|
4
|
-
raise LoadError
|
4
|
+
raise LoadError, 'Gem sentry-raven is required for logging purposes. Please add the gem "sentry-raven" to your Gemfile.'
|
5
5
|
end
|
6
6
|
|
7
7
|
# Send log messages to sentry
|
@@ -46,12 +46,12 @@ module SemanticLogger
|
|
46
46
|
# Send an error notification to sentry
|
47
47
|
def log(log)
|
48
48
|
# Ignore logs coming from Raven itself
|
49
|
-
return false if log.name ==
|
49
|
+
return false if log.name == "Raven"
|
50
50
|
|
51
|
-
context
|
52
|
-
user
|
53
|
-
tags
|
54
|
-
attrs
|
51
|
+
context = formatter.call(log, self)
|
52
|
+
user = context.delete(:user)
|
53
|
+
tags = context.delete(:tags)
|
54
|
+
attrs = {
|
55
55
|
level: context.delete(:level),
|
56
56
|
extra: context
|
57
57
|
}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
begin
|
2
|
+
require "sentry-ruby"
|
3
|
+
rescue LoadError
|
4
|
+
raise LoadError, 'Gem sentry-ruby is required for logging purposes. Please add the gem "sentry-ruby" to your Gemfile.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# Send log messages to sentry
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# SemanticLogger.add_appender(appender: :sentry_ruby)
|
11
|
+
#
|
12
|
+
module SemanticLogger
|
13
|
+
module Appender
|
14
|
+
class SentryRuby < SemanticLogger::Subscriber
|
15
|
+
# Create 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: :error, **args, &block)
|
41
|
+
# Replace the Sentry Ruby logger so that we can identify its log
|
42
|
+
# messages and not forward them to Sentry
|
43
|
+
::Sentry.init { |config| config.logger = SemanticLogger[::Sentry] }
|
44
|
+
super(level: level, **args, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Send an error notification to sentry
|
48
|
+
def log(log)
|
49
|
+
# Ignore logs coming from Sentry itself
|
50
|
+
return false if log.name == "Sentry"
|
51
|
+
|
52
|
+
context = formatter.call(log, self)
|
53
|
+
payload = context.delete(:payload) || {}
|
54
|
+
named_tags = context[:named_tags] || {}
|
55
|
+
transaction_name = named_tags.delete(:transaction_name)
|
56
|
+
|
57
|
+
user = extract_user!(named_tags, payload)
|
58
|
+
tags = extract_tags!(context)
|
59
|
+
|
60
|
+
fingerprint = payload.delete(:fingerprint)
|
61
|
+
|
62
|
+
::Sentry.with_scope do |scope|
|
63
|
+
scope.set_user(user) if user
|
64
|
+
scope.set_level(context.delete(:level)) if context[:level]
|
65
|
+
scope.set_fingerprint(fingerprint) if fingerprint
|
66
|
+
scope.set_transaction_name(transaction_name) if transaction_name
|
67
|
+
scope.set_tags(tags)
|
68
|
+
scope.set_extras(context)
|
69
|
+
scope.set_extras(payload)
|
70
|
+
|
71
|
+
if log.exception
|
72
|
+
::Sentry.capture_exception(log.exception)
|
73
|
+
elsif log.backtrace
|
74
|
+
::Sentry.capture_message(context[:message], backtrace: log.backtrace)
|
75
|
+
else
|
76
|
+
::Sentry.capture_message(context[:message])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Use Raw Formatter by default
|
86
|
+
def default_formatter
|
87
|
+
SemanticLogger::Formatters::Raw.new
|
88
|
+
end
|
89
|
+
|
90
|
+
# Extract user data from named tags or payload.
|
91
|
+
#
|
92
|
+
# Keys :user_id and :user_email will be used as :id and :email respectively.
|
93
|
+
# Keys :username and :ip_address will be used verbatim.
|
94
|
+
#
|
95
|
+
# Any additional value nested in a :user key will be added, provided any of
|
96
|
+
# the above keys is already present.
|
97
|
+
#
|
98
|
+
def extract_user!(*sources)
|
99
|
+
keys = {user_id: :id, username: :username, user_email: :email, ip_address: :ip_address}
|
100
|
+
|
101
|
+
user = {}
|
102
|
+
|
103
|
+
sources.each do |source|
|
104
|
+
keys.each do |source_key, target_key|
|
105
|
+
value = source.delete(source_key)
|
106
|
+
user[target_key] = value if value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
return if user.empty?
|
111
|
+
|
112
|
+
sources.each do |source|
|
113
|
+
extras = source.delete(:user)
|
114
|
+
user.merge!(extras) if extras.is_a?(Hash)
|
115
|
+
end
|
116
|
+
|
117
|
+
user
|
118
|
+
end
|
119
|
+
|
120
|
+
# Extract tags.
|
121
|
+
#
|
122
|
+
# Named tags will be stringified (both key and value).
|
123
|
+
# Unnamed tags will be stringified and joined with a comma. Then they will
|
124
|
+
# be used as a "tag" named tag. If such a tag already exists, it is also
|
125
|
+
# joined with a comma.
|
126
|
+
#
|
127
|
+
# Finally, the tag names are limited to 32 characters and the tag values to 256.
|
128
|
+
#
|
129
|
+
def extract_tags!(context)
|
130
|
+
named_tags = context.delete(:named_tags) || {}
|
131
|
+
named_tags = named_tags.map { |k, v| [k.to_s, v.to_s] }.to_h
|
132
|
+
tags = context.delete(:tags)
|
133
|
+
named_tags.merge!("tag" => tags.join(", ")) { |_, v1, v2| "#{v1}, #{v2}" } if tags
|
134
|
+
named_tags.map { |k, v| [k[0...32], v[0...256]] }.to_h
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "splunk-sdk-ruby"
|
3
3
|
rescue LoadError
|
4
|
-
raise LoadError
|
4
|
+
raise LoadError,
|
5
|
+
'Gem splunk-sdk-ruby is required for logging to Splunk. Please add the gem "splunk-sdk-ruby" to your Gemfile.'
|
5
6
|
end
|
6
7
|
|
7
8
|
# Splunk log appender.
|
@@ -88,7 +89,7 @@ module SemanticLogger
|
|
88
89
|
# regular expression. All other messages will be ignored.
|
89
90
|
# Proc: Only include log messages where the supplied Proc returns true
|
90
91
|
# The Proc must return true or false.
|
91
|
-
def initialize(index:
|
92
|
+
def initialize(index: "main", source_type: nil, **args, &block)
|
92
93
|
@index = index
|
93
94
|
@source_type = source_type
|
94
95
|
|
@@ -120,7 +121,7 @@ module SemanticLogger
|
|
120
121
|
def call(log, logger)
|
121
122
|
h = SemanticLogger::Formatters::Raw.new.call(log, logger)
|
122
123
|
h.delete(:time)
|
123
|
-
message
|
124
|
+
message = {
|
124
125
|
source: logger.application,
|
125
126
|
host: logger.host,
|
126
127
|
time: log.time.utc.to_f,
|
@@ -128,7 +129,7 @@ module SemanticLogger
|
|
128
129
|
event: h
|
129
130
|
}
|
130
131
|
message[:environment] = logger.environment if logger.environment
|
131
|
-
message[:sourcetype]
|
132
|
+
message[:sourcetype] = source_type if source_type
|
132
133
|
message
|
133
134
|
end
|
134
135
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
# Splunk log appender using the Splunk HTTP(S) listener.
|
3
3
|
#
|
4
4
|
# Use the newer, faster and more complete JSON over HTTP interface for Splunk.
|
@@ -81,22 +81,22 @@ module SemanticLogger
|
|
81
81
|
super(compress: compress, **args, &block)
|
82
82
|
|
83
83
|
# Put splunk auth token in the header of every HTTP post.
|
84
|
-
@header[
|
84
|
+
@header["Authorization"] = "Splunk #{token}"
|
85
85
|
end
|
86
86
|
|
87
87
|
# Returns [String] JSON to send to Splunk.
|
88
88
|
#
|
89
89
|
# For splunk format requirements see:
|
90
|
-
#
|
90
|
+
# https://docs.splunk.com/Documentation/Splunk/latest/Data/FormateventsforHTTPEventCollector
|
91
91
|
def call(log, logger)
|
92
|
-
h
|
93
|
-
|
92
|
+
h = SemanticLogger::Formatters::Raw.new(time_format: :seconds).call(log, logger)
|
93
|
+
h.delete(:host)
|
94
|
+
message = {
|
94
95
|
source: logger.application,
|
95
96
|
host: logger.host,
|
96
97
|
time: h.delete(:time),
|
97
98
|
event: h
|
98
99
|
}
|
99
|
-
message[:environment] = logger.environment if logger.environment
|
100
100
|
message[:sourcetype] = source_type if source_type
|
101
101
|
message[:index] = index if index
|
102
102
|
message.to_json
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "syslog"
|
2
|
+
require "uri"
|
3
|
+
require "socket"
|
4
4
|
# Send log messages to local syslog, or remote syslog servers over TCP or UDP.
|
5
5
|
#
|
6
6
|
# Example:
|
@@ -31,7 +31,7 @@ require 'socket'
|
|
31
31
|
module SemanticLogger
|
32
32
|
module Appender
|
33
33
|
class Syslog < SemanticLogger::Subscriber
|
34
|
-
attr_reader :remote_syslog, :url, :server, :port, :protocol, :facility, :options, :level_map
|
34
|
+
attr_reader :remote_syslog, :url, :server, :port, :protocol, :facility, :options, :level_map, :max_size
|
35
35
|
|
36
36
|
# Create a Syslog appender instance.
|
37
37
|
#
|
@@ -57,7 +57,7 @@ module SemanticLogger
|
|
57
57
|
# Only used with the TCP protocol.
|
58
58
|
# Specify custom parameters to pass into Net::TCPClient.new
|
59
59
|
# For a list of options see the net_tcp_client documentation:
|
60
|
-
# https://github.com/
|
60
|
+
# https://github.com/reidmorrison/net_tcp_client/blob/master/lib/net/tcp_client/tcp_client.rb
|
61
61
|
#
|
62
62
|
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
63
63
|
# Override the log level for this appender.
|
@@ -73,6 +73,10 @@ module SemanticLogger
|
|
73
73
|
# Identity of the program.
|
74
74
|
# Default: SemanticLogger.application
|
75
75
|
#
|
76
|
+
# max_size: [Integer]
|
77
|
+
# Set your own packet size.
|
78
|
+
# Default: 1024 bytes
|
79
|
+
#
|
76
80
|
# options: [Integer]
|
77
81
|
# Default: ::Syslog::LOG_PID | ::Syslog::LOG_CONS
|
78
82
|
# Any of the following (options can be logically OR'd together)
|
@@ -119,8 +123,9 @@ module SemanticLogger
|
|
119
123
|
# Example:
|
120
124
|
# # Change the warn level to LOG_NOTICE level instead of a the default of LOG_WARNING.
|
121
125
|
# SemanticLogger.add_appender(appender: :syslog, level_map: {warn: ::Syslog::LOG_NOTICE})
|
122
|
-
def initialize(url:
|
126
|
+
def initialize(url: "syslog://localhost",
|
123
127
|
facility: ::Syslog::LOG_USER,
|
128
|
+
max_size: 1024,
|
124
129
|
level_map: SemanticLogger::Formatters::Syslog::LevelMap.new,
|
125
130
|
options: ::Syslog::LOG_PID | ::Syslog::LOG_CONS,
|
126
131
|
tcp_client: {},
|
@@ -129,13 +134,14 @@ module SemanticLogger
|
|
129
134
|
|
130
135
|
@options = options
|
131
136
|
@facility = facility
|
137
|
+
@max_size = max_size
|
132
138
|
@level_map = level_map
|
133
139
|
@url = url
|
134
140
|
uri = URI(@url)
|
135
|
-
@server = uri.host ||
|
141
|
+
@server = uri.host || "localhost"
|
136
142
|
@protocol = (uri.scheme || :syslog).to_sym
|
137
143
|
@port = uri.port || 514
|
138
|
-
@server =
|
144
|
+
@server = "localhost" if @protocol == :syslog
|
139
145
|
@tcp_client_options = tcp_client
|
140
146
|
|
141
147
|
raise "Unknown protocol #{@protocol}!" unless %i[syslog tcp udp].include?(@protocol)
|
@@ -143,17 +149,19 @@ module SemanticLogger
|
|
143
149
|
# The syslog_protocol gem is required when logging over TCP or UDP.
|
144
150
|
if %i[tcp udp].include?(@protocol)
|
145
151
|
begin
|
146
|
-
require
|
152
|
+
require "syslog_protocol"
|
147
153
|
rescue LoadError
|
148
|
-
raise LoadError
|
154
|
+
raise LoadError,
|
155
|
+
"Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol"
|
149
156
|
end
|
150
157
|
|
151
158
|
# The net_tcp_client gem is required when logging over TCP.
|
152
159
|
if protocol == :tcp
|
153
160
|
begin
|
154
|
-
require
|
161
|
+
require "net/tcp_client"
|
155
162
|
rescue LoadError
|
156
|
-
raise LoadError
|
163
|
+
raise LoadError,
|
164
|
+
"Missing gem: net_tcp_client. This gem is required when logging over TCP. To fix this error: gem install net_tcp_client"
|
157
165
|
end
|
158
166
|
end
|
159
167
|
end
|
@@ -171,7 +179,7 @@ module SemanticLogger
|
|
171
179
|
::Syslog.send(method, application, options, facility)
|
172
180
|
when :tcp
|
173
181
|
@tcp_client_options[:server] = "#{@server}:#{@port}"
|
174
|
-
@remote_syslog = Net::TCPClient.new(
|
182
|
+
@remote_syslog = Net::TCPClient.new(**@tcp_client_options)
|
175
183
|
# Use the local logger for @remote_syslog so errors with the remote logger can be recorded locally.
|
176
184
|
@remote_syslog.logger = logger
|
177
185
|
when :udp
|
@@ -186,7 +194,7 @@ module SemanticLogger
|
|
186
194
|
case @protocol
|
187
195
|
when :syslog
|
188
196
|
# Since the Ruby Syslog API supports sprintf format strings, double up all existing '%'
|
189
|
-
message = formatter.call(log, self).gsub
|
197
|
+
message = formatter.call(log, self).gsub "%", "%%"
|
190
198
|
::Syslog.log @level_map[log.level], message
|
191
199
|
when :tcp
|
192
200
|
@remote_syslog.retry_on_connection_failure { @remote_syslog.write("#{formatter.call(log, self)}\r\n") }
|
@@ -209,7 +217,7 @@ module SemanticLogger
|
|
209
217
|
# Format is text output without the time
|
210
218
|
SemanticLogger::Formatters::Default.new(time_format: nil)
|
211
219
|
else
|
212
|
-
SemanticLogger::Formatters::Syslog.new(facility: facility, level_map: level_map)
|
220
|
+
SemanticLogger::Formatters::Syslog.new(facility: facility, level_map: level_map, max_size: max_size)
|
213
221
|
end
|
214
222
|
end
|
215
223
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "net/tcp_client"
|
3
3
|
rescue LoadError
|
4
|
-
raise LoadError
|
4
|
+
raise LoadError, 'Gem net_tcp_client is required for logging over TCP. Please add the gem "net_tcp_client" to your Gemfile.'
|
5
5
|
end
|
6
6
|
|
7
|
-
raise
|
7
|
+
raise "Net::TCPClient v2.0 or greater is required to log over TCP" unless Net::TCPClient::VERSION.to_f >= 2.0
|
8
8
|
|
9
9
|
module SemanticLogger
|
10
10
|
module Appender
|
@@ -189,7 +189,7 @@ module SemanticLogger
|
|
189
189
|
|
190
190
|
# Use the internal logger so that errors with remote logging are only written locally.
|
191
191
|
Net::TCPClient.logger = logger
|
192
|
-
Net::TCPClient.logger.name =
|
192
|
+
Net::TCPClient.logger.name = "Net::TCPClient"
|
193
193
|
|
194
194
|
super(level: level, formatter: formatter, filter: filter, application: application, environment: environment, host: host, &block)
|
195
195
|
reopen
|
@@ -198,7 +198,7 @@ module SemanticLogger
|
|
198
198
|
# After forking an active process call #reopen to re-open the handles to resources.
|
199
199
|
def reopen
|
200
200
|
close
|
201
|
-
@tcp_client = Net::TCPClient.new(
|
201
|
+
@tcp_client = Net::TCPClient.new(**@tcp_client_args)
|
202
202
|
end
|
203
203
|
|
204
204
|
# Write the log using the specified protocol and server.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "socket"
|
2
2
|
module SemanticLogger
|
3
3
|
module Appender
|
4
4
|
# UDP log appender.
|
@@ -74,7 +74,7 @@ module SemanticLogger
|
|
74
74
|
def reopen
|
75
75
|
close
|
76
76
|
@socket = UDPSocket.new
|
77
|
-
host, port = server.split(
|
77
|
+
host, port = server.split(":")
|
78
78
|
@socket.connect(host, port.to_i)
|
79
79
|
end
|
80
80
|
|
@@ -32,7 +32,7 @@ module SemanticLogger
|
|
32
32
|
# require 'logger'
|
33
33
|
# require 'semantic_logger'
|
34
34
|
#
|
35
|
-
# ruby_logger = Logger.new(
|
35
|
+
# ruby_logger = Logger.new($stdout)
|
36
36
|
# SemanticLogger.add_appender(logger: ruby_logger)
|
37
37
|
#
|
38
38
|
# logger = SemanticLogger['test']
|
@@ -45,7 +45,8 @@ module SemanticLogger
|
|
45
45
|
# Check if the custom appender responds to all the log levels. For example Ruby ::Logger
|
46
46
|
does_not_implement = LEVELS[1..-1].find { |i| !@logger.respond_to?(i) }
|
47
47
|
if does_not_implement
|
48
|
-
raise(ArgumentError,
|
48
|
+
raise(ArgumentError,
|
49
|
+
"Supplied logger does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}")
|
49
50
|
end
|
50
51
|
|
51
52
|
super(**args, &block)
|
@@ -1,35 +1,36 @@
|
|
1
1
|
module SemanticLogger
|
2
2
|
module Appender
|
3
3
|
# @formatter:off
|
4
|
-
autoload :Async,
|
5
|
-
autoload :AsyncBatch,
|
6
|
-
autoload :Bugsnag,
|
7
|
-
autoload :Elasticsearch,
|
8
|
-
autoload :ElasticsearchHttp,
|
9
|
-
autoload :File,
|
10
|
-
autoload :Graylog,
|
11
|
-
autoload :Honeybadger,
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
22
|
-
autoload :
|
23
|
-
autoload :
|
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 :Rabbitmq, "semantic_logger/appender/rabbitmq"
|
19
|
+
autoload :Splunk, "semantic_logger/appender/splunk"
|
20
|
+
autoload :SplunkHttp, "semantic_logger/appender/splunk_http"
|
21
|
+
autoload :Syslog, "semantic_logger/appender/syslog"
|
22
|
+
autoload :Tcp, "semantic_logger/appender/tcp"
|
23
|
+
autoload :Udp, "semantic_logger/appender/udp"
|
24
|
+
autoload :Wrapper, "semantic_logger/appender/wrapper"
|
25
|
+
autoload :SentryRuby, "semantic_logger/appender/sentry_ruby"
|
24
26
|
# @formatter:on
|
25
27
|
|
26
28
|
# Returns [SemanticLogger::Subscriber] appender for the supplied options
|
27
29
|
def self.factory(async: false, batch: nil,
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
)
|
30
|
+
max_queue_size: 10_000, lag_check_interval: 1_000, lag_threshold_s: 30,
|
31
|
+
batch_size: 300, batch_seconds: 5,
|
32
|
+
**args,
|
33
|
+
&block)
|
33
34
|
appender = build(**args, &block)
|
34
35
|
|
35
36
|
# If appender implements #batch, then it should use the batch proxy by default.
|
@@ -37,11 +38,11 @@ module SemanticLogger
|
|
37
38
|
|
38
39
|
if batch == true
|
39
40
|
Appender::AsyncBatch.new(
|
40
|
-
appender:
|
41
|
-
max_queue_size:
|
42
|
-
lag_threshold_s:
|
43
|
-
batch_size:
|
44
|
-
batch_seconds:
|
41
|
+
appender: appender,
|
42
|
+
max_queue_size: max_queue_size,
|
43
|
+
lag_threshold_s: lag_threshold_s,
|
44
|
+
batch_size: batch_size,
|
45
|
+
batch_seconds: batch_seconds
|
45
46
|
)
|
46
47
|
elsif async == true
|
47
48
|
Appender::Async.new(
|
@@ -57,8 +58,10 @@ module SemanticLogger
|
|
57
58
|
|
58
59
|
# Returns [Subscriber] instance from the supplied options.
|
59
60
|
def self.build(io: nil, file_name: nil, appender: nil, metric: nil, logger: nil, **args, &block)
|
60
|
-
if
|
61
|
-
SemanticLogger::Appender::File.new(
|
61
|
+
if file_name
|
62
|
+
SemanticLogger::Appender::File.new(file_name, **args, &block)
|
63
|
+
elsif io
|
64
|
+
SemanticLogger::Appender::IO.new(io, **args, &block)
|
62
65
|
elsif logger
|
63
66
|
SemanticLogger::Appender::Wrapper.new(logger: logger, **args, &block)
|
64
67
|
elsif appender
|
@@ -67,18 +70,21 @@ module SemanticLogger
|
|
67
70
|
elsif appender.is_a?(Subscriber)
|
68
71
|
appender
|
69
72
|
else
|
70
|
-
raise(ArgumentError,
|
73
|
+
raise(ArgumentError,
|
74
|
+
"Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
|
71
75
|
end
|
72
76
|
elsif metric
|
73
77
|
if metric.is_a?(Symbol)
|
74
|
-
SemanticLogger::Utils.constantize_symbol(metric,
|
78
|
+
SemanticLogger::Utils.constantize_symbol(metric, "SemanticLogger::Metric").new(**args)
|
75
79
|
elsif metric.is_a?(Subscriber)
|
76
80
|
metric
|
77
81
|
else
|
78
|
-
raise(ArgumentError,
|
82
|
+
raise(ArgumentError,
|
83
|
+
"Parameter :metric must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
|
79
84
|
end
|
80
85
|
else
|
81
|
-
raise(ArgumentError,
|
86
|
+
raise(ArgumentError,
|
87
|
+
"To create an appender it must supply one of the following: :io, :file_name, :appender, :metric, or :logger")
|
82
88
|
end
|
83
89
|
end
|
84
90
|
|