semantic_logger 4.1.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/semantic_logger.rb +6 -13
- data/lib/semantic_logger/ansi_colors.rb +10 -10
- data/lib/semantic_logger/appender.rb +42 -26
- data/lib/semantic_logger/appender/async.rb +179 -0
- data/lib/semantic_logger/appender/async_batch.rb +95 -0
- data/lib/semantic_logger/appender/bugsnag.rb +2 -1
- data/lib/semantic_logger/appender/elasticsearch.rb +113 -81
- data/lib/semantic_logger/appender/elasticsearch_http.rb +1 -3
- data/lib/semantic_logger/appender/file.rb +1 -3
- data/lib/semantic_logger/appender/graylog.rb +6 -5
- data/lib/semantic_logger/appender/honeybadger.rb +0 -2
- data/lib/semantic_logger/appender/http.rb +25 -10
- data/lib/semantic_logger/appender/kafka.rb +1 -3
- data/lib/semantic_logger/appender/mongodb.rb +1 -3
- data/lib/semantic_logger/appender/new_relic.rb +7 -3
- data/lib/semantic_logger/appender/sentry.rb +6 -7
- data/lib/semantic_logger/appender/splunk.rb +1 -2
- data/lib/semantic_logger/appender/splunk_http.rb +3 -4
- data/lib/semantic_logger/appender/syslog.rb +1 -3
- data/lib/semantic_logger/appender/tcp.rb +7 -9
- data/lib/semantic_logger/appender/udp.rb +0 -2
- data/lib/semantic_logger/appender/wrapper.rb +0 -2
- data/lib/semantic_logger/base.rb +76 -19
- data/lib/semantic_logger/formatters.rb +37 -0
- data/lib/semantic_logger/formatters/base.rb +10 -3
- data/lib/semantic_logger/formatters/json.rb +2 -6
- data/lib/semantic_logger/formatters/one_line.rb +18 -0
- data/lib/semantic_logger/formatters/raw.rb +8 -2
- data/lib/semantic_logger/formatters/signalfx.rb +169 -0
- data/lib/semantic_logger/log.rb +23 -14
- data/lib/semantic_logger/loggable.rb +88 -15
- data/lib/semantic_logger/logger.rb +0 -20
- data/lib/semantic_logger/metric/new_relic.rb +75 -0
- data/lib/semantic_logger/metric/signalfx.rb +123 -0
- data/lib/semantic_logger/{metrics → metric}/statsd.rb +20 -8
- data/lib/semantic_logger/processor.rb +67 -169
- data/lib/semantic_logger/semantic_logger.rb +7 -31
- data/lib/semantic_logger/subscriber.rb +32 -36
- data/lib/semantic_logger/utils.rb +47 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/async_batch_test.rb +61 -0
- data/test/appender/async_test.rb +45 -0
- data/test/appender/elasticsearch_http_test.rb +3 -3
- data/test/appender/elasticsearch_test.rb +211 -49
- data/test/appender/file_test.rb +9 -8
- data/test/appender/mongodb_test.rb +3 -3
- data/test/appender/newrelic_rpm.rb +6 -0
- data/test/appender/sentry_test.rb +3 -1
- data/test/appender/wrapper_test.rb +29 -0
- data/test/concerns/compatibility_test.rb +64 -60
- data/test/debug_as_trace_logger_test.rb +62 -77
- data/test/formatters/one_line_test.rb +61 -0
- data/test/formatters/signalfx_test.rb +200 -0
- data/test/formatters_test.rb +36 -0
- data/test/in_memory_appender.rb +9 -0
- data/test/in_memory_appender_helper.rb +43 -0
- data/test/in_memory_batch_appender.rb +9 -0
- data/test/in_memory_metrics_appender.rb +14 -0
- data/test/loggable_test.rb +15 -30
- data/test/logger_test.rb +181 -135
- data/test/measure_test.rb +212 -113
- data/test/metric/new_relic_test.rb +36 -0
- data/test/metric/signalfx_test.rb +78 -0
- data/test/semantic_logger_test.rb +58 -65
- data/test/test_helper.rb +19 -2
- metadata +33 -7
- data/lib/semantic_logger/metrics/new_relic.rb +0 -30
- data/lib/semantic_logger/metrics/udp.rb +0 -80
- data/test/mock_logger.rb +0 -29
data/lib/semantic_logger/log.rb
CHANGED
@@ -47,7 +47,10 @@ module SemanticLogger
|
|
47
47
|
# context [Hash]
|
48
48
|
# Named contexts that were captured when the log entry was created.
|
49
49
|
class Log
|
50
|
-
attr_accessor :level, :
|
50
|
+
attr_accessor :level, :level_index, :name, :message, :time, :duration,
|
51
|
+
:payload, :exception, :thread_name, :backtrace,
|
52
|
+
:tags, :named_tags, :context,
|
53
|
+
:metric, :metric_amount, :dimensions
|
51
54
|
|
52
55
|
def initialize(name, level, index = nil)
|
53
56
|
@level = level
|
@@ -65,7 +68,17 @@ module SemanticLogger
|
|
65
68
|
#
|
66
69
|
# Example:
|
67
70
|
# logger.info(name: 'value')
|
68
|
-
def assign(message: nil,
|
71
|
+
def assign(message: nil,
|
72
|
+
payload: nil,
|
73
|
+
min_duration: 0.0,
|
74
|
+
exception: nil,
|
75
|
+
metric: nil,
|
76
|
+
metric_amount: nil,
|
77
|
+
duration: nil,
|
78
|
+
backtrace: nil,
|
79
|
+
log_exception: :full,
|
80
|
+
on_exception_level: nil,
|
81
|
+
dimensions: nil)
|
69
82
|
# Elastic logging: Log when :duration exceeds :min_duration
|
70
83
|
# Except if there is an exception when it will always be logged
|
71
84
|
if duration
|
@@ -95,14 +108,15 @@ module SemanticLogger
|
|
95
108
|
end
|
96
109
|
|
97
110
|
if backtrace
|
98
|
-
self.backtrace =
|
111
|
+
self.backtrace = Utils.cleanse_backtrace(backtrace)
|
99
112
|
elsif level_index >= SemanticLogger.backtrace_level_index
|
100
|
-
self.backtrace =
|
113
|
+
self.backtrace = Utils.cleanse_backtrace
|
101
114
|
end
|
102
115
|
|
103
116
|
if metric
|
104
117
|
self.metric = metric
|
105
118
|
self.metric_amount = metric_amount
|
119
|
+
self.dimensions = dimensions
|
106
120
|
end
|
107
121
|
|
108
122
|
self.payload = payload if payload && (payload.size > 0)
|
@@ -125,6 +139,8 @@ module SemanticLogger
|
|
125
139
|
elsif exception.nil? && payload && payload.respond_to?(:backtrace) && payload.respond_to?(:message)
|
126
140
|
exception = payload
|
127
141
|
payload = nil
|
142
|
+
elsif payload.is_a?(String)
|
143
|
+
message = message.nil? ? payload : "#{message} -- #{payload}"
|
128
144
|
end
|
129
145
|
|
130
146
|
# Add result of block as message or payload if not nil
|
@@ -277,16 +293,9 @@ module SemanticLogger
|
|
277
293
|
(self.context ||= {})[key] = value
|
278
294
|
end
|
279
295
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
# Extract the backtrace leaving out Semantic Logger
|
285
|
-
def self.cleanse_backtrace(stack = caller)
|
286
|
-
while (first = stack.first) && first.include?(SELF_PATTERN)
|
287
|
-
stack.shift
|
288
|
-
end
|
289
|
-
stack
|
296
|
+
# A metric only event has a metric but no message, exception, or payload.
|
297
|
+
def metric_only?
|
298
|
+
metric && message.nil? && exception.nil? && payload.nil?
|
290
299
|
end
|
291
300
|
|
292
301
|
end
|
@@ -5,29 +5,34 @@
|
|
5
5
|
# By including this mix-in into any class it will define a class level logger
|
6
6
|
# and also make it accessible via instance methods
|
7
7
|
#
|
8
|
-
# Example
|
8
|
+
# Example:
|
9
|
+
# require 'semantic_logger'
|
10
|
+
# SemanticLogger.default_level = :debug
|
11
|
+
# SemanticLogger.add_appender(io: STDOUT, formatter: :color)
|
9
12
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
+
# class ExternalSupplier
|
14
|
+
# # Create class and instance logger methods
|
15
|
+
# include SemanticLogger::Loggable
|
13
16
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# include SemanticLogger::Loggable
|
17
|
+
# def call_supplier(amount, name)
|
18
|
+
# logger.debug "Calculating with amount", { amount: amount, name: name }
|
17
19
|
#
|
18
|
-
#
|
19
|
-
#
|
20
|
+
# # Measure and log on completion how long the call took to the external supplier
|
21
|
+
# logger.measure_info "Calling external interface" do
|
22
|
+
# # Code to call the external supplier ...
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# end
|
20
26
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# end
|
26
|
-
# end
|
27
|
+
# Notes:
|
28
|
+
# * To forcibly replace Rails or any other existing logging methods
|
29
|
+
# use `prepend` instead of `include`. For example:
|
30
|
+
# ExternalSupplier.prepend SemanticLogger::Loggable
|
27
31
|
module SemanticLogger
|
28
32
|
module Loggable
|
29
33
|
|
30
34
|
def self.included(base)
|
35
|
+
base.extend ClassMethods
|
31
36
|
base.class_eval do
|
32
37
|
# Returns [SemanticLogger::Logger] class level logger
|
33
38
|
def self.logger
|
@@ -51,5 +56,73 @@ module SemanticLogger
|
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
59
|
+
module ClassMethods
|
60
|
+
# Measure and log the performance of an instance method.
|
61
|
+
#
|
62
|
+
# Parameters:
|
63
|
+
# method_name: [Symbol]
|
64
|
+
# The name of the method that should be measured.
|
65
|
+
#
|
66
|
+
# options: [Hash]
|
67
|
+
# Any valid options that can be passed to measure.
|
68
|
+
#
|
69
|
+
# Approximate overhead when logging a method call with a metric:
|
70
|
+
# 0.044 ms per method call.
|
71
|
+
# 0.009 ms per method call. If `min_duration` is not met
|
72
|
+
# 0.0005 ms per method call. If `level` is not met
|
73
|
+
def logger_measure_method(method_name,
|
74
|
+
min_duration: 0.0,
|
75
|
+
metric: "#{name}/#{method_name}",
|
76
|
+
log_exception: :partial,
|
77
|
+
on_exception_level: nil,
|
78
|
+
message: "##{method_name}",
|
79
|
+
level: :info)
|
80
|
+
|
81
|
+
# unless visibility = Utils.method_visibility(self, method_name)
|
82
|
+
# logger.warn("Unable to measure method: #{name}##{method_name} since it does not exist")
|
83
|
+
# return false
|
84
|
+
# end
|
85
|
+
|
86
|
+
index = SemanticLogger.level_to_index(level)
|
87
|
+
|
88
|
+
logger_measure_module.module_eval(<<-EOT, __FILE__, __LINE__ + 1)
|
89
|
+
def #{method_name}(*args, &block)
|
90
|
+
if logger.send(:level_index) <= #{index}
|
91
|
+
logger.send(
|
92
|
+
:measure_method,
|
93
|
+
index: #{index},
|
94
|
+
level: #{level.inspect},
|
95
|
+
message: #{message.inspect},
|
96
|
+
min_duration: #{min_duration},
|
97
|
+
metric: #{metric.inspect},
|
98
|
+
log_exception: #{log_exception.inspect},
|
99
|
+
on_exception_level: #{on_exception_level.inspect}
|
100
|
+
) do
|
101
|
+
super(*args, &block)
|
102
|
+
end
|
103
|
+
else
|
104
|
+
super(*args, &block)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
EOT
|
108
|
+
#{"#{visibility} :#{method_name}" unless visibility == :public}
|
109
|
+
true
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
# Dynamic Module to intercept method calls for measuring purposes.
|
115
|
+
def logger_measure_module
|
116
|
+
if const_defined?(:SemanticLoggerMeasure, _search_ancestors = false)
|
117
|
+
const_get(:SemanticLoggerMeasure)
|
118
|
+
else
|
119
|
+
mod = const_set(:SemanticLoggerMeasure, Module.new)
|
120
|
+
prepend mod
|
121
|
+
mod
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
54
127
|
end
|
55
128
|
end
|
@@ -38,25 +38,5 @@ module SemanticLogger
|
|
38
38
|
Processor << log
|
39
39
|
end
|
40
40
|
|
41
|
-
# DEPRECATED
|
42
|
-
def self.queue_size
|
43
|
-
Processor.queue_size
|
44
|
-
end
|
45
|
-
|
46
|
-
# DEPRECATED
|
47
|
-
def self.flush
|
48
|
-
Processor.flush
|
49
|
-
end
|
50
|
-
|
51
|
-
# DEPRECATED
|
52
|
-
def self.close
|
53
|
-
Processor.close
|
54
|
-
end
|
55
|
-
|
56
|
-
# DEPRECATED
|
57
|
-
def self.logger=(logger)
|
58
|
-
Processor.logger = logger
|
59
|
-
end
|
60
|
-
|
61
41
|
end
|
62
42
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
begin
|
2
|
+
require 'newrelic_rpm'
|
3
|
+
rescue LoadError
|
4
|
+
raise 'Gem newrelic_rpm is required for logging to New Relic. Please add the gem "newrelic_rpm" to your Gemfile.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# Send Metrics to NewRelic
|
8
|
+
#
|
9
|
+
# The :error and :fatal log entries will show up under
|
10
|
+
# "Applications" > "Application Name" > "Events" > "Errors" in New Relic.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# SemanticLogger.add_appender(metric: :new_relic)
|
14
|
+
class SemanticLogger::Metric::NewRelic < SemanticLogger::Subscriber
|
15
|
+
attr_accessor :prefix
|
16
|
+
|
17
|
+
# Create Appender
|
18
|
+
#
|
19
|
+
# Parameters
|
20
|
+
# :prefix [String]
|
21
|
+
# Prefix to add to every metric before forwarding to NewRelic.
|
22
|
+
# Default: 'Custom'
|
23
|
+
#
|
24
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
25
|
+
# Override the log level for this appender.
|
26
|
+
# Default: :error
|
27
|
+
#
|
28
|
+
# formatter: [Object|Proc]
|
29
|
+
# An instance of a class that implements #call, or a Proc to be used to format
|
30
|
+
# the output from this appender
|
31
|
+
# Default: Use the built-in formatter (See: #call)
|
32
|
+
#
|
33
|
+
# filter: [Regexp|Proc]
|
34
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
35
|
+
# regular expression. All other messages will be ignored.
|
36
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
37
|
+
# The Proc must return true or false.
|
38
|
+
def initialize(prefix: 'Custom',
|
39
|
+
level: nil,
|
40
|
+
formatter: nil,
|
41
|
+
filter: nil,
|
42
|
+
application: nil,
|
43
|
+
host: nil,
|
44
|
+
&block)
|
45
|
+
|
46
|
+
@prefix = prefix
|
47
|
+
super(level: level, formatter: formatter, filter: filter, application: application, host: host, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns metric name to use.
|
51
|
+
def call(log, _logger)
|
52
|
+
metric = log.metric
|
53
|
+
# Add prefix for NewRelic
|
54
|
+
metric = "#{prefix}/#{metric}" unless metric.start_with?(prefix)
|
55
|
+
metric
|
56
|
+
end
|
57
|
+
|
58
|
+
def log(log)
|
59
|
+
name = formatter.call(log, self)
|
60
|
+
if duration = log.duration
|
61
|
+
# Convert duration to seconds
|
62
|
+
::NewRelic::Agent.record_metric(name, duration / 1000.0)
|
63
|
+
else
|
64
|
+
::NewRelic::Agent.increment_metric(name, log.metric_amount || 1)
|
65
|
+
end
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
# Only forward log entries that contain metrics.
|
70
|
+
def should_log?(log)
|
71
|
+
# Does not support metrics with dimensions.
|
72
|
+
log.metric && !log.dimensions && meets_log_level?(log) && !filtered?(log)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# Forward application metrics to SignalFx.
|
2
|
+
#
|
3
|
+
# Example:
|
4
|
+
# SemanticLogger.add_appender(
|
5
|
+
# metric: :signalfx,
|
6
|
+
# token: 'SIGNALFX_ORG_ACCESS_TOKEN'
|
7
|
+
# )
|
8
|
+
class SemanticLogger::Metric::Signalfx < SemanticLogger::Appender::Http
|
9
|
+
attr_reader :full_url
|
10
|
+
|
11
|
+
END_POINT = 'v2/datapoint'
|
12
|
+
|
13
|
+
# Create SignalFx metrics appender.
|
14
|
+
#
|
15
|
+
# Parameters:
|
16
|
+
# token: [String]
|
17
|
+
# Access Token to use for sending metrics.
|
18
|
+
# Obtain the Signalfx token via the Signalfx Web UI under `Organization` -> `Access Tokens`.
|
19
|
+
#
|
20
|
+
# dimensions: [Array<String>]
|
21
|
+
# Dimensions to forward to signalfx when they are present in the named tags of any log message.
|
22
|
+
# By default `application` and `host` are always included as dimensions in all forwarded metrics.
|
23
|
+
# Example: [:user_id, :state]
|
24
|
+
#
|
25
|
+
# filter: [Regexp|Proc]
|
26
|
+
# RegExp: Only include log messages where the class name matches the supplied
|
27
|
+
# regular expression. All other messages will be ignored.
|
28
|
+
# Proc: Only include log messages where the supplied Proc returns true.
|
29
|
+
# The Proc must return true or false.
|
30
|
+
#
|
31
|
+
# host: [String]
|
32
|
+
# Name of this host to send as a dimension.
|
33
|
+
# Default: SemanticLogger.host
|
34
|
+
#
|
35
|
+
# application: [String]
|
36
|
+
# Name of this application to send as a dimension.
|
37
|
+
# Default: SemanticLogger.application
|
38
|
+
#
|
39
|
+
# url: [String]
|
40
|
+
# Override the SignalFx service url.
|
41
|
+
# For historical data use: https://backfill.signalfx.com/v1/backfill
|
42
|
+
# Default: https://ingest.signalfx.com
|
43
|
+
#
|
44
|
+
# Notes:
|
45
|
+
#
|
46
|
+
# When sending a metric to Signalfx, it is necessary to send both a `gauge` and a `counter` when a
|
47
|
+
# duration is included in the metric, otherwise it is not possible to chart counts of the metric.
|
48
|
+
# Unfortunately this doubles the number of metrics, but it is the way Signalfx works.
|
49
|
+
# Using a `count` of a `gauge` in a chart will significantly under-count the number of occurrences.
|
50
|
+
#
|
51
|
+
# If dimensions are added to the metric, then the metric will be sent as-is and
|
52
|
+
# the above logic will _not_ be applied.
|
53
|
+
#
|
54
|
+
# Example, Gauge metric, supplying the duration in `metric_amount`:
|
55
|
+
# logger.info(metric: 'Filters.average', metric_amount: 1.2, dimensions: {user: 'jbloggs'})
|
56
|
+
#
|
57
|
+
# Example, Counter metric:
|
58
|
+
# logger.info(metric: 'Filters.count', dimensions: {user: 'jbloggs'})
|
59
|
+
#
|
60
|
+
# Example, Counter metric with a count other than 1:
|
61
|
+
# logger.info(metric: 'Filters.count', metric_amount: 23, dimensions: {user: 'jbloggs'})
|
62
|
+
#
|
63
|
+
# When a duration is supplied and no dimensions are supplied:
|
64
|
+
# logger.info(metric: 'Common/User/authorize', duration: 1.4)
|
65
|
+
#
|
66
|
+
# Then it is translated into the following 2 log entries under the covers:
|
67
|
+
# logger.info(metric: 'Application.average', metric_amount: 1.4, dimensions: {class: 'Common::User', action: 'authorize'})
|
68
|
+
# logger.info(metric: 'Application.counter', metric_amount: 1, dimensions: {class: 'Common::User', action: 'authorize'})
|
69
|
+
#
|
70
|
+
# Similarly with a measure block which automatically supplies the duration:
|
71
|
+
# logger.measure_info(metric: 'Common/User/authorize') do
|
72
|
+
# sleep 1
|
73
|
+
# end
|
74
|
+
def initialize(token:,
|
75
|
+
dimensions: nil,
|
76
|
+
url: 'https://ingest.signalfx.com',
|
77
|
+
open_timeout: 2.0,
|
78
|
+
read_timeout: 1.0,
|
79
|
+
continue_timeout: 1.0,
|
80
|
+
filter: nil,
|
81
|
+
application: nil,
|
82
|
+
host: nil,
|
83
|
+
formatter: nil,
|
84
|
+
&block)
|
85
|
+
|
86
|
+
formatter ||= SemanticLogger::Formatters::Signalfx.new(token: token, dimensions: dimensions)
|
87
|
+
|
88
|
+
super(
|
89
|
+
url: url,
|
90
|
+
read_timeout: read_timeout,
|
91
|
+
open_timeout: open_timeout,
|
92
|
+
continue_timeout: continue_timeout,
|
93
|
+
filter: filter,
|
94
|
+
application: application,
|
95
|
+
host: host,
|
96
|
+
formatter: formatter,
|
97
|
+
&block
|
98
|
+
)
|
99
|
+
|
100
|
+
@header['X-SF-TOKEN'] = token
|
101
|
+
@full_url = "#{url}/#{END_POINT}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def log(log)
|
105
|
+
message = formatter.call(log, self)
|
106
|
+
logger.trace(message)
|
107
|
+
post(message, full_url)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Logs in batches
|
111
|
+
def batch(logs)
|
112
|
+
message = formatter.batch(logs, self)
|
113
|
+
logger.trace(message)
|
114
|
+
post(message, full_url)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Only forward log entries that contain metrics.
|
118
|
+
def should_log?(log)
|
119
|
+
log.metric && meets_log_level?(log) && !filtered?(log)
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
@@ -6,8 +6,10 @@ rescue LoadError
|
|
6
6
|
end
|
7
7
|
|
8
8
|
module SemanticLogger
|
9
|
-
module
|
9
|
+
module Metric
|
10
10
|
class Statsd < Subscriber
|
11
|
+
attr_accessor :url
|
12
|
+
|
11
13
|
# Create Statsd metrics subscriber
|
12
14
|
#
|
13
15
|
# Parameters:
|
@@ -20,12 +22,16 @@ module SemanticLogger
|
|
20
22
|
# Default: udp://localhost:8125
|
21
23
|
#
|
22
24
|
# Example:
|
23
|
-
#
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
# SemanticLogger.add_appender(
|
26
|
+
# metric: :statsd,
|
27
|
+
# url: 'localhost:8125'
|
28
|
+
# )
|
29
|
+
def initialize(url: 'udp://localhost:8125')
|
30
|
+
@url = url
|
31
|
+
end
|
32
|
+
|
33
|
+
def reopen
|
34
|
+
uri = URI.parse(@url)
|
29
35
|
raise('Statsd only supports udp. Example: "udp://localhost:8125"') if uri.scheme != 'udp'
|
30
36
|
|
31
37
|
@statsd = ::Statsd.new(uri.host, uri.port)
|
@@ -33,7 +39,7 @@ module SemanticLogger
|
|
33
39
|
@statsd.namespace = path.sub('/', '') if path != ''
|
34
40
|
end
|
35
41
|
|
36
|
-
def
|
42
|
+
def log(log)
|
37
43
|
metric = log.metric
|
38
44
|
if duration = log.duration
|
39
45
|
@statsd.timing(metric, duration)
|
@@ -47,6 +53,12 @@ module SemanticLogger
|
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
56
|
+
# Only forward log entries that contain metrics.
|
57
|
+
def should_log?(log)
|
58
|
+
# Does not support metrics with dimensions.
|
59
|
+
log.metric && !log.dimensions && meets_log_level?(log) && !filtered?(log)
|
60
|
+
end
|
61
|
+
|
50
62
|
end
|
51
63
|
end
|
52
64
|
end
|