semantic_logger 4.6.1 → 4.10.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.
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