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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -20
  3. data/Rakefile +7 -7
  4. data/lib/semantic_logger/appender/async.rb +10 -9
  5. data/lib/semantic_logger/appender/async_batch.rb +7 -3
  6. data/lib/semantic_logger/appender/bugsnag.rb +43 -30
  7. data/lib/semantic_logger/appender/elasticsearch.rb +32 -14
  8. data/lib/semantic_logger/appender/elasticsearch_http.rb +4 -4
  9. data/lib/semantic_logger/appender/file.rb +249 -67
  10. data/lib/semantic_logger/appender/graylog.rb +12 -10
  11. data/lib/semantic_logger/appender/honeybadger.rb +3 -3
  12. data/lib/semantic_logger/appender/http.rb +20 -18
  13. data/lib/semantic_logger/appender/io.rb +68 -0
  14. data/lib/semantic_logger/appender/kafka.rb +9 -5
  15. data/lib/semantic_logger/appender/mongodb.rb +6 -6
  16. data/lib/semantic_logger/appender/new_relic.rb +2 -2
  17. data/lib/semantic_logger/appender/rabbitmq.rb +5 -5
  18. data/lib/semantic_logger/appender/sentry.rb +7 -7
  19. data/lib/semantic_logger/appender/sentry_ruby.rb +138 -0
  20. data/lib/semantic_logger/appender/splunk.rb +6 -5
  21. data/lib/semantic_logger/appender/splunk_http.rb +6 -6
  22. data/lib/semantic_logger/appender/syslog.rb +23 -15
  23. data/lib/semantic_logger/appender/tcp.rb +5 -5
  24. data/lib/semantic_logger/appender/udp.rb +2 -2
  25. data/lib/semantic_logger/appender/wrapper.rb +3 -2
  26. data/lib/semantic_logger/appender.rb +42 -36
  27. data/lib/semantic_logger/appenders.rb +34 -30
  28. data/lib/semantic_logger/base.rb +57 -27
  29. data/lib/semantic_logger/formatters/base.rb +9 -3
  30. data/lib/semantic_logger/formatters/color.rb +12 -8
  31. data/lib/semantic_logger/formatters/default.rb +18 -5
  32. data/lib/semantic_logger/formatters/fluentd.rb +3 -3
  33. data/lib/semantic_logger/formatters/json.rb +1 -1
  34. data/lib/semantic_logger/formatters/logfmt.rb +72 -0
  35. data/lib/semantic_logger/formatters/raw.rb +31 -7
  36. data/lib/semantic_logger/formatters/signalfx.rb +10 -9
  37. data/lib/semantic_logger/formatters/syslog.rb +8 -6
  38. data/lib/semantic_logger/formatters/syslog_cee.rb +8 -6
  39. data/lib/semantic_logger/formatters.rb +12 -13
  40. data/lib/semantic_logger/jruby/garbage_collection_logger.rb +4 -2
  41. data/lib/semantic_logger/levels.rb +9 -7
  42. data/lib/semantic_logger/log.rb +51 -61
  43. data/lib/semantic_logger/loggable.rb +8 -1
  44. data/lib/semantic_logger/logger.rb +19 -11
  45. data/lib/semantic_logger/metric/new_relic.rb +3 -3
  46. data/lib/semantic_logger/metric/signalfx.rb +3 -3
  47. data/lib/semantic_logger/metric/statsd.rb +7 -7
  48. data/lib/semantic_logger/processor.rb +9 -7
  49. data/lib/semantic_logger/reporters/minitest.rb +4 -4
  50. data/lib/semantic_logger/semantic_logger.rb +40 -19
  51. data/lib/semantic_logger/subscriber.rb +16 -5
  52. data/lib/semantic_logger/sync.rb +12 -0
  53. data/lib/semantic_logger/sync_processor.rb +43 -0
  54. data/lib/semantic_logger/test/capture_log_events.rb +34 -0
  55. data/lib/semantic_logger/utils.rb +32 -13
  56. data/lib/semantic_logger/version.rb +1 -1
  57. data/lib/semantic_logger.rb +27 -22
  58. metadata +15 -10
@@ -1,7 +1,7 @@
1
1
  begin
2
- require 'bunny'
2
+ require "bunny"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem bunny is required for logging to RabbitMQ. Please add the gem "bunny" to your Gemfile.')
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: 'semantic_logger', rabbitmq_host: nil, metrics: false, **args, &block)
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 'sentry-raven'
2
+ require "sentry-raven"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem sentry-raven is required for logging purposes. Please add the gem "sentry-raven" to your Gemfile.')
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 == 'Raven'
49
+ return false if log.name == "Raven"
50
50
 
51
- context = formatter.call(log, self)
52
- user = context.delete(:user)
53
- tags = context.delete(: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 'splunk-sdk-ruby'
2
+ require "splunk-sdk-ruby"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem splunk-sdk-ruby is required for logging to Splunk. Please add the gem "splunk-sdk-ruby" to your Gemfile.')
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: 'main', source_type: nil, **args, &block)
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] = source_type if source_type
132
+ message[:sourcetype] = source_type if source_type
132
133
  message
133
134
  end
134
135
  end
@@ -1,4 +1,4 @@
1
- require 'json'
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['Authorization'] = "Splunk #{token}"
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
- # http://dev.splunk.com/view/event-collector/SP-CAAAE6P
90
+ # https://docs.splunk.com/Documentation/Splunk/latest/Data/FormateventsforHTTPEventCollector
91
91
  def call(log, logger)
92
- h = SemanticLogger::Formatters::Raw.new(time_format: :seconds).call(log, logger)
93
- message = {
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 'syslog'
2
- require 'uri'
3
- require 'socket'
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/rocketjob/net_tcp_client/blob/master/lib/net/tcp_client/tcp_client.rb
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: 'syslog://localhost',
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 || 'localhost'
141
+ @server = uri.host || "localhost"
136
142
  @protocol = (uri.scheme || :syslog).to_sym
137
143
  @port = uri.port || 514
138
- @server = 'localhost' if @protocol == :syslog
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 'syslog_protocol'
152
+ require "syslog_protocol"
147
153
  rescue LoadError
148
- raise LoadError.new('Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol')
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 'net/tcp_client'
161
+ require "net/tcp_client"
155
162
  rescue LoadError
156
- raise LoadError.new('Missing gem: net_tcp_client. This gem is required when logging over TCP. To fix this error: gem install net_tcp_client')
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(@tcp_client_options)
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 'net/tcp_client'
2
+ require "net/tcp_client"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem net_tcp_client is required for logging over TCP. Please add the gem "net_tcp_client" to your Gemfile.')
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 'Net::TCPClient v2.0 or greater is required to log over TCP' unless Net::TCPClient::VERSION.to_f >= 2.0
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 = 'Net::TCPClient'
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(@tcp_client_args)
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 'socket'
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(STDOUT)
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, "Supplied logger does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}")
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, '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 :Kafka, 'semantic_logger/appender/kafka'
13
- autoload :Sentry, 'semantic_logger/appender/sentry'
14
- autoload :Http, 'semantic_logger/appender/http'
15
- autoload :MongoDB, 'semantic_logger/appender/mongodb'
16
- autoload :NewRelic, 'semantic_logger/appender/new_relic'
17
- autoload :Rabbitmq, 'semantic_logger/appender/rabbitmq'
18
- autoload :Splunk, 'semantic_logger/appender/splunk'
19
- autoload :SplunkHttp, 'semantic_logger/appender/splunk_http'
20
- autoload :Syslog, 'semantic_logger/appender/syslog'
21
- autoload :Tcp, 'semantic_logger/appender/tcp'
22
- autoload :Udp, 'semantic_logger/appender/udp'
23
- autoload :Wrapper, 'semantic_logger/appender/wrapper'
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
- max_queue_size: 10_000, lag_check_interval: 1_000, lag_threshold_s: 30,
29
- batch_size: 300, batch_seconds: 5,
30
- **args,
31
- &block
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: appender,
41
- max_queue_size: max_queue_size,
42
- lag_threshold_s: lag_threshold_s,
43
- batch_size: batch_size,
44
- batch_seconds: 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 io || file_name
61
- SemanticLogger::Appender::File.new(io: io, file_name: file_name, **args, &block)
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, "Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
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, 'SemanticLogger::Metric').new(**args)
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, "Parameter :metric must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
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, 'To create an appender it must supply one of the following: :io, :file_name, :appender, :metric, or :logger')
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