semantic_logger 2.21.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/lib/semantic_logger.rb +13 -9
- data/lib/semantic_logger/appender/base.rb +20 -24
- data/lib/semantic_logger/appender/bugsnag.rb +37 -53
- data/lib/semantic_logger/appender/elasticsearch.rb +53 -0
- data/lib/semantic_logger/appender/file.rb +17 -3
- data/lib/semantic_logger/appender/graylog.rb +123 -0
- data/lib/semantic_logger/appender/http.rb +169 -0
- data/lib/semantic_logger/appender/mongodb.rb +90 -111
- data/lib/semantic_logger/appender/new_relic.rb +38 -72
- data/lib/semantic_logger/appender/splunk.rb +10 -5
- data/lib/semantic_logger/appender/splunk_http.rb +99 -0
- data/lib/semantic_logger/appender/syslog.rb +116 -103
- data/lib/semantic_logger/appender/wrapper.rb +26 -11
- data/lib/semantic_logger/base.rb +13 -16
- data/lib/semantic_logger/log.rb +85 -5
- data/lib/semantic_logger/logger.rb +1 -1
- data/lib/semantic_logger/semantic_logger.rb +24 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/bugsnag_test.rb +39 -41
- data/test/appender/graylog_test.rb +63 -0
- data/test/appender/http_test.rb +61 -0
- data/test/appender/mongodb_test.rb +20 -20
- data/test/appender/new_relic_test.rb +4 -3
- data/test/appender/splunk_http_test.rb +78 -0
- data/test/logger_test.rb +1 -1
- metadata +27 -3
@@ -1,12 +1,17 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'splunk-sdk-ruby'
|
3
|
+
rescue LoadError
|
4
|
+
raise 'Gem splunk-sdk-ruby is required for logging to Splunk. Please add the gem "splunk-sdk-ruby" to your Gemfile.'
|
5
|
+
end
|
2
6
|
|
3
|
-
# Note:
|
7
|
+
# Note: This appender is Deprecated. Use: SemanticLogger::Appender::SplunkHttp
|
4
8
|
class SemanticLogger::Appender::Splunk < SemanticLogger::Appender::Base
|
5
9
|
attr_reader :config, :index, :service, :service_index
|
6
10
|
|
7
|
-
#
|
8
|
-
# Default: :error
|
11
|
+
# DEPRECATED, Please use SemanticLogger::Appender::SplunkHttp
|
9
12
|
def initialize(options, level=:error, &block)
|
13
|
+
Kernel.warn('Splunk Appender is deprecated, please use SemanticLogger::Appender::SplunkHttp')
|
14
|
+
|
10
15
|
# Parse input options for setting up splunk connection
|
11
16
|
parse_options(options)
|
12
17
|
|
@@ -31,7 +36,7 @@ class SemanticLogger::Appender::Splunk < SemanticLogger::Appender::Base
|
|
31
36
|
# Ensure minimum log level is met, and check filter
|
32
37
|
return false if (level_index > (log.level_index || 0)) || !include_message?(log)
|
33
38
|
# Submit the log message
|
34
|
-
@service_index.submit(formatter.call(log))
|
39
|
+
@service_index.submit(formatter.call(log, self))
|
35
40
|
true
|
36
41
|
end
|
37
42
|
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Splunk log appender.
|
2
|
+
#
|
3
|
+
# Use the newer, faster and more complete JSON over HTTP interface for Splunk.
|
4
|
+
#
|
5
|
+
# To configure Splunk to receive log messages via this appender:
|
6
|
+
# http://dev.splunk.com/view/event-collector/SP-CAAAE7F
|
7
|
+
#
|
8
|
+
# Example
|
9
|
+
# appender = SemanticLogger::Appender::SplunkHttp.new(
|
10
|
+
# url: 'http://localhost:8080',
|
11
|
+
# token: '70CA900C-3D7E-42A4-9C79-7975D1C422A8'
|
12
|
+
# )
|
13
|
+
# SemanticLogger.add_appender(appender)
|
14
|
+
class SemanticLogger::Appender::SplunkHttp < SemanticLogger::Appender::Http
|
15
|
+
# Create Splunk appender over persistent HTTP(S)
|
16
|
+
#
|
17
|
+
# Parameters:
|
18
|
+
# token: [String]
|
19
|
+
# Token created in Splunk for this HTTP Appender
|
20
|
+
# Mandatory.
|
21
|
+
#
|
22
|
+
# source_type: [String]
|
23
|
+
# Optional: Source type to display in Splunk
|
24
|
+
#
|
25
|
+
# index: [String]
|
26
|
+
# Optional: Name of a valid index for this message in Splunk.
|
27
|
+
#
|
28
|
+
# url: [String]
|
29
|
+
# Valid URL to post to.
|
30
|
+
# Example: http://example.com
|
31
|
+
# To enable SSL include https in the URL.
|
32
|
+
# Example: https://example.com
|
33
|
+
# verify_mode will default: OpenSSL::SSL::VERIFY_PEER
|
34
|
+
#
|
35
|
+
# application: [String]
|
36
|
+
# Name of this application to appear in log messages.
|
37
|
+
# Default: SemanticLogger.application
|
38
|
+
#
|
39
|
+
# host: [String]
|
40
|
+
# Name of this host to appear in log messages.
|
41
|
+
# Default: SemanticLogger.host
|
42
|
+
#
|
43
|
+
# compress: [true|false]
|
44
|
+
# Whether to compress the JSON string with GZip.
|
45
|
+
# Default: true
|
46
|
+
#
|
47
|
+
# ssl: [Hash]
|
48
|
+
# Specific SSL options: For more details see NET::HTTP.start
|
49
|
+
# ca_file, ca_path, cert, cert_store, ciphers, key, open_timeout, read_timeout, ssl_timeout,
|
50
|
+
# ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
|
51
|
+
#
|
52
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
53
|
+
# Override the log level for this appender.
|
54
|
+
# Default: SemanticLogger.default_level
|
55
|
+
#
|
56
|
+
# filter: [Regexp|Proc]
|
57
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
58
|
+
# regular expression. All other messages will be ignored.
|
59
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
60
|
+
# The Proc must return true or false.
|
61
|
+
def initialize(options, &block)
|
62
|
+
options = options.dup
|
63
|
+
@source_type = options.delete(:source_type)
|
64
|
+
@index = options.delete(:index)
|
65
|
+
token = options.delete(:token)
|
66
|
+
raise(ArgumentError, 'Missing mandatory parameter :token') unless token
|
67
|
+
|
68
|
+
# Splunk supports HTTP Compression, enable by default
|
69
|
+
options[:compress] = true unless options.key?(:compress)
|
70
|
+
|
71
|
+
super(options, &block)
|
72
|
+
|
73
|
+
@header['Authorization'] = "Splunk #{token}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns [String] JSON to send to Splunk
|
77
|
+
# For splunk format requirements see:
|
78
|
+
# http://dev.splunk.com/view/event-collector/SP-CAAAE6P
|
79
|
+
def default_formatter
|
80
|
+
Proc.new do |log, logger|
|
81
|
+
h = log.to_h
|
82
|
+
h.delete(:application)
|
83
|
+
h.delete(:host)
|
84
|
+
h.delete(:time)
|
85
|
+
message = {
|
86
|
+
source: logger.application,
|
87
|
+
host: logger.host,
|
88
|
+
time: log.time.utc.to_f,
|
89
|
+
event: h
|
90
|
+
}
|
91
|
+
message[:source_type] = @source_type if @source_type
|
92
|
+
message[:index] = @index if @index
|
93
|
+
|
94
|
+
# Render to JSON
|
95
|
+
message.to_json
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -1,41 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
# require 'semantic_logger'
|
7
|
-
# SemanticLogger.default_level = :trace
|
1
|
+
require 'syslog'
|
2
|
+
require 'uri'
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
# Send log messages to local syslog, or remote syslog servers over TCP or UDP.
|
8
6
|
#
|
9
|
-
#
|
10
|
-
#
|
7
|
+
# Example: Log to a local Syslog daemon
|
8
|
+
# SemanticLogger.add_appender(SemanticLogger::Appender::Syslog.new)
|
11
9
|
#
|
12
|
-
#
|
13
|
-
#
|
10
|
+
# Example: Log to a remote Syslog server using TCP:
|
11
|
+
# appender = SemanticLogger::Appender::Syslog.new(
|
12
|
+
# url: 'tcp://myloghost:514'
|
13
|
+
# )
|
14
14
|
#
|
15
|
+
# # Optional: Add filter to exclude health_check, or other log entries
|
16
|
+
# appender.filter = Proc.new { |log| log.message !~ /(health_check|Not logged in)/ }
|
15
17
|
#
|
16
|
-
#
|
17
|
-
# Send to a remote syslog appender - myloghost - over TCP on port 514.
|
18
|
-
# Tested with syslog-ng as part of an ELSA installation.
|
19
|
-
# https://code.google.com/p/enterprise-log-search-and-archive/
|
18
|
+
# SemanticLogger.add_appender(appender)
|
20
19
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
20
|
+
# Example: Log to a remote Syslog server using UDP:
|
21
|
+
# appender = SemanticLogger::Appender::Syslog.new(
|
22
|
+
# url: 'udp://myloghost:514'
|
23
|
+
# )
|
25
24
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# logger.error "Error! Error! - This message should appear in the remote syslog!"
|
25
|
+
# # Optional: Add filter to exclude health_check, or other log entries
|
26
|
+
# appender.filter = Proc.new { |log| log.message !~ /(health_check|Not logged in)/ }
|
29
27
|
#
|
30
|
-
|
31
|
-
require 'uri'
|
32
|
-
require 'socket'
|
33
|
-
|
28
|
+
# SemanticLogger.add_appender(appender)
|
34
29
|
module SemanticLogger
|
35
30
|
module Appender
|
36
31
|
class Syslog < SemanticLogger::Appender::Base
|
37
32
|
|
38
|
-
attr_reader :remote_syslog, :
|
33
|
+
attr_reader :remote_syslog, :url, :server, :port, :protocol, :facility, :host, :application
|
39
34
|
|
40
35
|
# Default mapping of ruby log levels to syslog log levels
|
41
36
|
#
|
@@ -56,14 +51,47 @@ module SemanticLogger
|
|
56
51
|
trace: ::Syslog::LOG_DEBUG
|
57
52
|
}
|
58
53
|
|
59
|
-
#
|
54
|
+
# Create a Syslog appender instance.
|
55
|
+
#
|
60
56
|
# Parameters
|
57
|
+
# url: [String]
|
58
|
+
# Default: 'syslog://localhost'
|
59
|
+
# For writing logs to a remote syslog server
|
60
|
+
# URL of server: protocol://host:port
|
61
|
+
# Uses port 514 by default for TCP and UDP.
|
62
|
+
# local syslog example: 'syslog://localhost'
|
63
|
+
# TCP example with default port: 'tcp://logger'
|
64
|
+
# TCP example with custom port: 'tcp://logger:8514'
|
65
|
+
# UDP example with default port: 'udp://logger'
|
66
|
+
# UDP example with custom port: 'udp://logger:8514'
|
67
|
+
# When using the :syslog protocol, logs will always be sent to the localhost syslog
|
61
68
|
#
|
62
|
-
# :
|
63
|
-
#
|
64
|
-
# Default:
|
69
|
+
# host: [String]
|
70
|
+
# Host name to provide to the remote syslog.
|
71
|
+
# Default: SemanticLogger.host
|
65
72
|
#
|
66
|
-
# :
|
73
|
+
# tcp_client: [Hash]
|
74
|
+
# Default: {}
|
75
|
+
# Only used with the TCP protocol.
|
76
|
+
# Specify custom parameters to pass into Net::TCPClient.new
|
77
|
+
# For a list of options see the net_tcp_client documentation:
|
78
|
+
# https://www.omniref.com/ruby/gems/net_tcp_client/1.0.0/symbols/Net::TCPClient/initialize
|
79
|
+
#
|
80
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
81
|
+
# Override the log level for this appender.
|
82
|
+
# Default: SemanticLogger.default_level
|
83
|
+
#
|
84
|
+
# filter: [Regexp|Proc]
|
85
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
86
|
+
# regular expression. All other messages will be ignored.
|
87
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
88
|
+
# The Proc must return true or false.
|
89
|
+
#
|
90
|
+
# application: [String]
|
91
|
+
# Identity of the program.
|
92
|
+
# Default: SemanticLogger.application
|
93
|
+
#
|
94
|
+
# options: [Integer]
|
67
95
|
# Default: ::Syslog::LOG_PID | ::Syslog::LOG_CONS
|
68
96
|
# Any of the following (options can be logically OR'd together)
|
69
97
|
# ::Syslog::LOG_CONS
|
@@ -73,7 +101,7 @@ module SemanticLogger
|
|
73
101
|
# ::Syslog::LOG_PERROR
|
74
102
|
# ::Syslog::LOG_PID
|
75
103
|
#
|
76
|
-
# :
|
104
|
+
# facility: [Integer]
|
77
105
|
# Default: ::Syslog::LOG_USER
|
78
106
|
# Type of program (can be logically OR'd together)
|
79
107
|
# ::Syslog::LOG_AUTH
|
@@ -100,11 +128,7 @@ module SemanticLogger
|
|
100
128
|
# ::Syslog::LOG_LOCAL6
|
101
129
|
# ::Syslog::LOG_LOCAL7
|
102
130
|
#
|
103
|
-
# :
|
104
|
-
# Default: SemanticLogger's log level.
|
105
|
-
# The minimum level at which this appender will write logs. Any log messages below this level will be ignored.
|
106
|
-
#
|
107
|
-
# :level_map [Hash]
|
131
|
+
# level_map: [Hash]
|
108
132
|
# Supply a custom map of SemanticLogger levels to syslog levels.
|
109
133
|
# For example, passing in { warn: ::Syslog::LOG_NOTICE }
|
110
134
|
# would result in a log mapping that matches the default level map,
|
@@ -119,51 +143,28 @@ module SemanticLogger
|
|
119
143
|
# debug: ::Syslog::LOG_INFO,
|
120
144
|
# trace: ::Syslog::LOG_DEBUG
|
121
145
|
# }
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
# :tcp_client [Hash]
|
140
|
-
# Default: {}
|
141
|
-
# Only used with the TCP protocol.
|
142
|
-
# Specify custom parameters to pass into Net::TCPClient.new
|
143
|
-
# For a list of options see the net_tcp_client documentation:
|
144
|
-
# https://www.omniref.com/ruby/gems/net_tcp_client/1.0.0/symbols/Net::TCPClient/initialize
|
145
|
-
def initialize(params = {}, &block)
|
146
|
-
params = params.dup
|
147
|
-
@ident = params.delete(:ident) || 'ruby'
|
148
|
-
@options = params.delete(:options) || (::Syslog::LOG_PID | ::Syslog::LOG_CONS)
|
149
|
-
@facility = params.delete(:facility) || ::Syslog::LOG_USER
|
150
|
-
filter = params.delete(:filter)
|
151
|
-
level = params.delete(:level)
|
152
|
-
level_map = params.delete(:level_map)
|
153
|
-
@level_map = DEFAULT_LEVEL_MAP.dup
|
154
|
-
@level_map.update(level_map) if level_map
|
155
|
-
@server = params.delete(:server) || 'syslog://localhost'
|
156
|
-
uri = URI(@server)
|
157
|
-
@host = uri.host || 'localhost'
|
158
|
-
@protocol = (uri.scheme || :syslog).to_sym
|
146
|
+
def initialize(options = {}, &block)
|
147
|
+
options = options.dup
|
148
|
+
level = options.delete(:level)
|
149
|
+
filter = options.delete(:filter)
|
150
|
+
@application = options.delete(:application) || options.delete(:ident) || 'ruby'
|
151
|
+
@options = options.delete(:options) || (::Syslog::LOG_PID | ::Syslog::LOG_CONS)
|
152
|
+
@facility = options.delete(:facility) || ::Syslog::LOG_USER
|
153
|
+
level_map = options.delete(:level_map)
|
154
|
+
@url = options.delete(:url) || options.delete(:server) || 'syslog://localhost'
|
155
|
+
uri = URI(@url)
|
156
|
+
@server = uri.host || 'localhost'
|
157
|
+
@protocol = (uri.scheme || :syslog).to_sym
|
158
|
+
@port = uri.port || 514
|
159
|
+
@server = 'localhost' if @protocol == :syslog
|
160
|
+
@host = options.delete(:host) || options.delete(:local_hostname) || SemanticLogger.host
|
161
|
+
@tcp_client_options = options.delete(:tcp_client)
|
162
|
+
|
159
163
|
raise "Unknown protocol #{@protocol}!" unless [:syslog, :tcp, :udp].include?(@protocol)
|
160
|
-
|
161
|
-
@port = URI(@server).port || 514
|
162
|
-
@local_hostname = params.delete(:local_hostname) || Socket.gethostname || `hostname`.strip
|
163
|
-
@tcp_client_options = params.delete(:tcp_client)
|
164
|
+
raise(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
|
164
165
|
|
165
|
-
|
166
|
-
|
166
|
+
@level_map = DEFAULT_LEVEL_MAP.dup
|
167
|
+
@level_map.update(level_map) if level_map
|
167
168
|
|
168
169
|
# The syslog_protocol gem is required when logging over TCP or UDP.
|
169
170
|
if [:tcp, :udp].include?(@protocol)
|
@@ -176,7 +177,7 @@ module SemanticLogger
|
|
176
177
|
# The net_tcp_client gem is required when logging over TCP.
|
177
178
|
if protocol == :tcp
|
178
179
|
@tcp_client_options ||= {}
|
179
|
-
@tcp_client_options[:server] = "#{@
|
180
|
+
@tcp_client_options[:server] = "#{@server}:#{@port}"
|
180
181
|
begin
|
181
182
|
require 'net/tcp_client'
|
182
183
|
rescue LoadError
|
@@ -195,7 +196,7 @@ module SemanticLogger
|
|
195
196
|
def reopen
|
196
197
|
case @protocol
|
197
198
|
when :syslog
|
198
|
-
::Syslog.open(@
|
199
|
+
::Syslog.open(@application, @options, @facility)
|
199
200
|
when :tcp
|
200
201
|
# Use the local logger for @remote_syslog so errors with the remote logger can be recorded locally.
|
201
202
|
@tcp_client_options[:logger] = SemanticLogger::Logger.logger
|
@@ -207,7 +208,7 @@ module SemanticLogger
|
|
207
208
|
end
|
208
209
|
end
|
209
210
|
|
210
|
-
# Write the log using the specified protocol and
|
211
|
+
# Write the log using the specified protocol and server.
|
211
212
|
def log(log)
|
212
213
|
# Ensure minimum log level is met, and check filter
|
213
214
|
return false if (level_index > (log.level_index || 0)) || !include_message?(log)
|
@@ -215,12 +216,12 @@ module SemanticLogger
|
|
215
216
|
case @protocol
|
216
217
|
when :syslog
|
217
218
|
# Since the Ruby Syslog API supports sprintf format strings, double up all existing '%'
|
218
|
-
message = formatter.call(log).gsub '%', '%%'
|
219
|
+
message = formatter.call(log, self).gsub '%', '%%'
|
219
220
|
::Syslog.log @level_map[log.level], message
|
220
221
|
when :tcp
|
221
222
|
@remote_syslog.retry_on_connection_failure { @remote_syslog.write("#{syslog_packet_formatter(log)}\r\n") }
|
222
223
|
when :udp
|
223
|
-
@remote_syslog.send syslog_packet_formatter(log), 0, @
|
224
|
+
@remote_syslog.send syslog_packet_formatter(log), 0, @server, @port
|
224
225
|
else
|
225
226
|
raise "Unsupported protocol: #{protocol}"
|
226
227
|
end
|
@@ -232,36 +233,48 @@ module SemanticLogger
|
|
232
233
|
@remote_syslog.flush if @remote_syslog && @remote_syslog.respond_to?(:flush)
|
233
234
|
end
|
234
235
|
|
235
|
-
# Custom log formatter for syslog
|
236
|
+
# Custom log formatter for syslog.
|
237
|
+
# Only difference is the removal of the timestamp string since it is in the syslog packet.
|
236
238
|
def default_formatter
|
237
239
|
Proc.new do |log|
|
238
|
-
|
240
|
+
# Header with date, time, log level and process info
|
241
|
+
entry = "#{log.level_to_s} [#{log.process_info}]"
|
239
242
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
message << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
|
249
|
-
end
|
243
|
+
# Tags
|
244
|
+
entry << ' ' << log.tags.collect { |tag| "[#{tag}]" }.join(' ') if log.tags && (log.tags.size > 0)
|
245
|
+
|
246
|
+
# Duration
|
247
|
+
entry << " (#{log.duration_human})" if log.duration
|
248
|
+
|
249
|
+
# Class / app name
|
250
|
+
entry << " #{log.name}"
|
250
251
|
|
251
|
-
|
252
|
+
# Log message
|
253
|
+
entry << " -- #{log.message}" if log.message
|
252
254
|
|
253
|
-
|
255
|
+
# Payload
|
256
|
+
if payload = log.payload_to_s(false)
|
257
|
+
entry << ' -- ' << payload
|
258
|
+
end
|
259
|
+
|
260
|
+
# Exceptions
|
261
|
+
if log.exception
|
262
|
+
entry << " -- Exception: #{log.exception.class}: #{log.exception.message}\n"
|
263
|
+
entry << log.backtrace_to_s
|
264
|
+
end
|
265
|
+
entry
|
254
266
|
end
|
255
267
|
end
|
256
268
|
|
257
269
|
# Format the syslog packet so it can be sent over TCP or UDP
|
258
270
|
def syslog_packet_formatter(log)
|
259
271
|
packet = SyslogProtocol::Packet.new
|
260
|
-
packet.hostname = @
|
272
|
+
packet.hostname = @host
|
261
273
|
packet.facility = @facility
|
262
274
|
packet.severity = @level_map[log.level]
|
263
|
-
packet.tag = @
|
264
|
-
packet.content = default_formatter.call(log)
|
275
|
+
packet.tag = @application
|
276
|
+
packet.content = default_formatter.call(log, self)
|
277
|
+
packet.time = log.time
|
265
278
|
packet.to_s
|
266
279
|
end
|
267
280
|
end
|
@@ -1,19 +1,35 @@
|
|
1
|
-
#
|
1
|
+
# Send log messages to any standard Ruby logging class.
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Forwards logging call to loggers such as Logger, log4r, etc.
|
4
4
|
#
|
5
5
|
module SemanticLogger
|
6
6
|
module Appender
|
7
7
|
class Wrapper < SemanticLogger::Appender::Base
|
8
8
|
attr_reader :logger
|
9
9
|
|
10
|
-
#
|
10
|
+
# Forward all logging calls to the supplied logging instance.
|
11
|
+
#
|
12
|
+
# Parameters
|
13
|
+
# logger: [Object]
|
14
|
+
# Instance of an existing logger conforming to the Ruby Logger methods.
|
15
|
+
#
|
16
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
17
|
+
# Override the log level for this appender.
|
18
|
+
# Default: SemanticLogger.default_level
|
19
|
+
#
|
20
|
+
# filter: [Regexp|Proc]
|
21
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
22
|
+
# regular expression. All other messages will be ignored.
|
23
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
24
|
+
# The Proc must return true or false.
|
11
25
|
#
|
12
26
|
# Ruby Logger
|
13
27
|
# require 'logger'
|
14
28
|
# require 'semantic_logger'
|
29
|
+
#
|
15
30
|
# ruby_logger = Logger.new(STDOUT)
|
16
31
|
# SemanticLogger.add_appender(ruby_logger)
|
32
|
+
#
|
17
33
|
# logger = SemanticLogger['test']
|
18
34
|
# logger.info('Hello World', some: :payload)
|
19
35
|
#
|
@@ -25,26 +41,25 @@ module SemanticLogger
|
|
25
41
|
# # Make ActiveRecord logging include its class name in every log entry
|
26
42
|
# ActiveRecord::Base.logger = SemanticLogger['ActiveRecord']
|
27
43
|
#
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
raise 'logger cannot be null when initiailizing the SemanticLogging::Appender::Wrapper' unless logger
|
44
|
+
# Install the `rails_semantic_logger` gem to replace the Rails logger with Semantic Logger.
|
45
|
+
def initialize(logger, level = nil, filter = nil, &block)
|
46
|
+
raise 'logger cannot be null when initializing the SemanticLogging::Appender::Wrapper' unless logger
|
32
47
|
@logger = logger
|
33
48
|
|
34
49
|
# Set the formatter to the supplied block
|
35
50
|
@formatter = block || self.default_formatter
|
36
|
-
super(
|
51
|
+
super(level, filter, &block)
|
37
52
|
end
|
38
53
|
|
39
54
|
# Pass log calls to the underlying Rails, log4j or Ruby logger
|
40
55
|
# trace entries are mapped to debug since :trace is not supported by the
|
41
56
|
# Ruby or Rails Loggers
|
42
57
|
def log(log)
|
43
|
-
#
|
44
|
-
return false
|
58
|
+
# Ensure minimum log level is met, and check filter
|
59
|
+
return false if (level_index > (log.level_index || 0)) || !include_message?(log)
|
45
60
|
|
46
61
|
# Underlying wrapper logger implements log level, so don't check here
|
47
|
-
@logger.send(log.level == :trace ? :debug : log.level, @formatter.call(log))
|
62
|
+
@logger.send(log.level == :trace ? :debug : log.level, @formatter.call(log, self))
|
48
63
|
true
|
49
64
|
end
|
50
65
|
|