atatus 1.0.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 +7 -0
- data/.gitignore +16 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +57 -0
- data/LICENSE +65 -0
- data/LICENSE-THIRD-PARTY +205 -0
- data/README.md +13 -0
- data/Rakefile +19 -0
- data/atatus.gemspec +36 -0
- data/atatus.yml +2 -0
- data/bench/.gitignore +2 -0
- data/bench/app.rb +53 -0
- data/bench/benchmark.rb +36 -0
- data/bench/report.rb +55 -0
- data/bench/rubyprof.rb +39 -0
- data/bench/stackprof.rb +23 -0
- data/bin/build_docs +5 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/bin/with_framework +7 -0
- data/lib/atatus.rb +325 -0
- data/lib/atatus/agent.rb +260 -0
- data/lib/atatus/central_config.rb +141 -0
- data/lib/atatus/central_config/cache_control.rb +34 -0
- data/lib/atatus/collector/base.rb +329 -0
- data/lib/atatus/collector/builder.rb +317 -0
- data/lib/atatus/collector/transport.rb +72 -0
- data/lib/atatus/config.rb +248 -0
- data/lib/atatus/config/bytes.rb +25 -0
- data/lib/atatus/config/duration.rb +23 -0
- data/lib/atatus/config/options.rb +134 -0
- data/lib/atatus/config/regexp_list.rb +13 -0
- data/lib/atatus/context.rb +33 -0
- data/lib/atatus/context/request.rb +11 -0
- data/lib/atatus/context/request/socket.rb +19 -0
- data/lib/atatus/context/request/url.rb +42 -0
- data/lib/atatus/context/response.rb +22 -0
- data/lib/atatus/context/user.rb +42 -0
- data/lib/atatus/context_builder.rb +97 -0
- data/lib/atatus/deprecations.rb +22 -0
- data/lib/atatus/error.rb +22 -0
- data/lib/atatus/error/exception.rb +46 -0
- data/lib/atatus/error/log.rb +24 -0
- data/lib/atatus/error_builder.rb +76 -0
- data/lib/atatus/instrumenter.rb +224 -0
- data/lib/atatus/internal_error.rb +6 -0
- data/lib/atatus/logging.rb +55 -0
- data/lib/atatus/metadata.rb +19 -0
- data/lib/atatus/metadata/process_info.rb +18 -0
- data/lib/atatus/metadata/service_info.rb +61 -0
- data/lib/atatus/metadata/system_info.rb +35 -0
- data/lib/atatus/metadata/system_info/container_info.rb +121 -0
- data/lib/atatus/metadata/system_info/hw_info.rb +118 -0
- data/lib/atatus/metadata/system_info/os_info.rb +31 -0
- data/lib/atatus/metrics.rb +98 -0
- data/lib/atatus/metrics/cpu_mem.rb +240 -0
- data/lib/atatus/metrics/vm.rb +60 -0
- data/lib/atatus/metricset.rb +19 -0
- data/lib/atatus/middleware.rb +76 -0
- data/lib/atatus/naively_hashable.rb +21 -0
- data/lib/atatus/normalizers.rb +68 -0
- data/lib/atatus/normalizers/action_controller.rb +27 -0
- data/lib/atatus/normalizers/action_mailer.rb +26 -0
- data/lib/atatus/normalizers/action_view.rb +77 -0
- data/lib/atatus/normalizers/active_record.rb +45 -0
- data/lib/atatus/opentracing.rb +346 -0
- data/lib/atatus/rails.rb +61 -0
- data/lib/atatus/railtie.rb +30 -0
- data/lib/atatus/span.rb +125 -0
- data/lib/atatus/span/context.rb +40 -0
- data/lib/atatus/span_helpers.rb +44 -0
- data/lib/atatus/spies.rb +86 -0
- data/lib/atatus/spies/action_dispatch.rb +28 -0
- data/lib/atatus/spies/delayed_job.rb +68 -0
- data/lib/atatus/spies/elasticsearch.rb +36 -0
- data/lib/atatus/spies/faraday.rb +70 -0
- data/lib/atatus/spies/http.rb +44 -0
- data/lib/atatus/spies/json.rb +22 -0
- data/lib/atatus/spies/mongo.rb +87 -0
- data/lib/atatus/spies/net_http.rb +70 -0
- data/lib/atatus/spies/rake.rb +45 -0
- data/lib/atatus/spies/redis.rb +27 -0
- data/lib/atatus/spies/sequel.rb +47 -0
- data/lib/atatus/spies/sidekiq.rb +89 -0
- data/lib/atatus/spies/sinatra.rb +41 -0
- data/lib/atatus/spies/tilt.rb +27 -0
- data/lib/atatus/sql_summarizer.rb +35 -0
- data/lib/atatus/stacktrace.rb +16 -0
- data/lib/atatus/stacktrace/frame.rb +52 -0
- data/lib/atatus/stacktrace_builder.rb +104 -0
- data/lib/atatus/subscriber.rb +77 -0
- data/lib/atatus/trace_context.rb +85 -0
- data/lib/atatus/transaction.rb +100 -0
- data/lib/atatus/transport/base.rb +174 -0
- data/lib/atatus/transport/connection.rb +156 -0
- data/lib/atatus/transport/connection/http.rb +116 -0
- data/lib/atatus/transport/connection/proxy_pipe.rb +75 -0
- data/lib/atatus/transport/filters.rb +43 -0
- data/lib/atatus/transport/filters/secrets_filter.rb +74 -0
- data/lib/atatus/transport/serializers.rb +93 -0
- data/lib/atatus/transport/serializers/context_serializer.rb +85 -0
- data/lib/atatus/transport/serializers/error_serializer.rb +77 -0
- data/lib/atatus/transport/serializers/metadata_serializer.rb +70 -0
- data/lib/atatus/transport/serializers/metricset_serializer.rb +28 -0
- data/lib/atatus/transport/serializers/span_serializer.rb +80 -0
- data/lib/atatus/transport/serializers/transaction_serializer.rb +37 -0
- data/lib/atatus/transport/worker.rb +73 -0
- data/lib/atatus/util.rb +42 -0
- data/lib/atatus/util/inflector.rb +93 -0
- data/lib/atatus/util/lru_cache.rb +48 -0
- data/lib/atatus/util/prefixed_logger.rb +18 -0
- data/lib/atatus/util/throttle.rb +35 -0
- data/lib/atatus/version.rb +5 -0
- data/vendor/.gitkeep +0 -0
- metadata +190 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Deprecations
|
|
6
|
+
def deprecate(name, replacement = nil)
|
|
7
|
+
alias_name = "#{name.to_s.chomp('=')}__deprecated_"
|
|
8
|
+
alias_name += '=' if name.to_s.end_with?('=')
|
|
9
|
+
|
|
10
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
11
|
+
alias :"#{alias_name}" :"#{name}"
|
|
12
|
+
|
|
13
|
+
def #{name}(*args, &block)
|
|
14
|
+
warn "[Atatus] [DEPRECATED] `#{name}' is being removed. " \
|
|
15
|
+
"#{replacement && "See `#{replacement}'."}" \
|
|
16
|
+
"\nCalled from \#{caller.first}"
|
|
17
|
+
send("#{alias_name}", *args, &block)
|
|
18
|
+
end
|
|
19
|
+
RUBY
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/atatus/error.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'atatus/stacktrace'
|
|
4
|
+
require 'atatus/context'
|
|
5
|
+
require 'atatus/error/exception'
|
|
6
|
+
require 'atatus/error/log'
|
|
7
|
+
|
|
8
|
+
module Atatus
|
|
9
|
+
# @api private
|
|
10
|
+
class Error
|
|
11
|
+
def initialize(culprit: nil, context: nil)
|
|
12
|
+
@id = SecureRandom.hex(16)
|
|
13
|
+
@culprit = culprit
|
|
14
|
+
@timestamp = Util.micros
|
|
15
|
+
@context = context
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_accessor :id, :culprit, :exception, :log, :transaction_id,
|
|
19
|
+
:transaction, :context, :parent_id, :trace_id
|
|
20
|
+
attr_reader :timestamp
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
class Error
|
|
5
|
+
# @api private
|
|
6
|
+
class Exception
|
|
7
|
+
MOD_SPLIT = '::'
|
|
8
|
+
|
|
9
|
+
def initialize(attrs = nil)
|
|
10
|
+
return unless attrs
|
|
11
|
+
|
|
12
|
+
attrs.each do |key, val|
|
|
13
|
+
send(:"#{key}=", val)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.from_exception(exception, **attrs)
|
|
18
|
+
new({
|
|
19
|
+
message: exception.message.to_s,
|
|
20
|
+
type: exception.class.to_s,
|
|
21
|
+
module: format_module(exception),
|
|
22
|
+
cause: exception.cause && Exception.from_exception(exception.cause)
|
|
23
|
+
}.merge(attrs))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_accessor(
|
|
27
|
+
:attributes,
|
|
28
|
+
:code,
|
|
29
|
+
:handled,
|
|
30
|
+
:message,
|
|
31
|
+
:module,
|
|
32
|
+
:stacktrace,
|
|
33
|
+
:type,
|
|
34
|
+
:cause
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def format_module(exception)
|
|
41
|
+
exception.class.to_s.split(MOD_SPLIT)[0...-1].join(MOD_SPLIT)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
class Error
|
|
5
|
+
# @api private
|
|
6
|
+
class Log
|
|
7
|
+
def initialize(message, attrs = {})
|
|
8
|
+
@message = message
|
|
9
|
+
|
|
10
|
+
attrs.each do |key, val|
|
|
11
|
+
send(:"#{key}=", val)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_accessor(
|
|
16
|
+
:level,
|
|
17
|
+
:logger_name,
|
|
18
|
+
:message,
|
|
19
|
+
:param_message,
|
|
20
|
+
:stacktrace
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
class ErrorBuilder
|
|
6
|
+
def initialize(agent)
|
|
7
|
+
@agent = agent
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def build_exception(exception, context: nil, handled: true)
|
|
11
|
+
error = Error.new context: context || Context.new
|
|
12
|
+
error.exception =
|
|
13
|
+
Error::Exception.from_exception(exception, handled: handled)
|
|
14
|
+
|
|
15
|
+
Util.reverse_merge!(error.context.labels, @agent.config.default_labels)
|
|
16
|
+
|
|
17
|
+
if exception.backtrace
|
|
18
|
+
add_stacktrace error, :exception, exception.backtrace
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
add_current_transaction_fields error, Atatus.current_transaction
|
|
22
|
+
|
|
23
|
+
error
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def build_log(message, context: nil, backtrace: nil, **attrs)
|
|
27
|
+
error = Error.new context: context || Context.new
|
|
28
|
+
error.log = Error::Log.new(message, **attrs)
|
|
29
|
+
|
|
30
|
+
if backtrace
|
|
31
|
+
add_stacktrace error, :log, backtrace
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
add_current_transaction_fields error, Atatus.current_transaction
|
|
35
|
+
|
|
36
|
+
error
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def add_stacktrace(error, kind, backtrace)
|
|
42
|
+
stacktrace =
|
|
43
|
+
@agent.stacktrace_builder.build(backtrace, type: :error)
|
|
44
|
+
return unless stacktrace
|
|
45
|
+
|
|
46
|
+
case kind
|
|
47
|
+
when :exception
|
|
48
|
+
error.exception.stacktrace = stacktrace
|
|
49
|
+
when :log
|
|
50
|
+
error.log.stacktrace = stacktrace
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
error.culprit = stacktrace.frames.first&.function
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
57
|
+
def add_current_transaction_fields(error, transaction)
|
|
58
|
+
return unless transaction
|
|
59
|
+
|
|
60
|
+
error.transaction_id = transaction.id
|
|
61
|
+
error.transaction = {
|
|
62
|
+
sampled: transaction.sampled?,
|
|
63
|
+
type: transaction.type
|
|
64
|
+
}
|
|
65
|
+
error.transaction[:name] = transaction.name unless transaction.name.nil?
|
|
66
|
+
error.trace_id = transaction.trace_id
|
|
67
|
+
error.parent_id = Atatus.current_span&.id || transaction.id
|
|
68
|
+
|
|
69
|
+
return unless transaction.context
|
|
70
|
+
|
|
71
|
+
Util.reverse_merge!(error.context.labels, transaction.context.labels)
|
|
72
|
+
Util.reverse_merge!(error.context.custom, transaction.context.custom)
|
|
73
|
+
end
|
|
74
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'atatus/trace_context'
|
|
4
|
+
require 'atatus/span'
|
|
5
|
+
require 'atatus/transaction'
|
|
6
|
+
require 'atatus/span_helpers'
|
|
7
|
+
|
|
8
|
+
module Atatus
|
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
|
10
|
+
# @api private
|
|
11
|
+
class Instrumenter
|
|
12
|
+
TRANSACTION_KEY = :__atatus_instrumenter_transaction_key
|
|
13
|
+
SPAN_KEY = :__atatus_instrumenter_spans_key
|
|
14
|
+
|
|
15
|
+
include Logging
|
|
16
|
+
|
|
17
|
+
# @api private
|
|
18
|
+
class Current
|
|
19
|
+
def initialize
|
|
20
|
+
self.transaction = nil
|
|
21
|
+
self.spans = []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def transaction
|
|
25
|
+
Thread.current[TRANSACTION_KEY]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def transaction=(transaction)
|
|
29
|
+
Thread.current[TRANSACTION_KEY] = transaction
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def spans
|
|
33
|
+
Thread.current[SPAN_KEY] ||= []
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def spans=(spans)
|
|
37
|
+
Thread.current[SPAN_KEY] ||= []
|
|
38
|
+
Thread.current[SPAN_KEY] = spans
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def initialize(config, stacktrace_builder:, &enqueue)
|
|
43
|
+
@config = config
|
|
44
|
+
@stacktrace_builder = stacktrace_builder
|
|
45
|
+
@enqueue = enqueue
|
|
46
|
+
|
|
47
|
+
@current = Current.new
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
attr_reader :config, :stacktrace_builder, :enqueue
|
|
51
|
+
|
|
52
|
+
def start
|
|
53
|
+
debug 'Starting instrumenter'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def stop
|
|
57
|
+
debug 'Stopping instrumenter'
|
|
58
|
+
|
|
59
|
+
self.current_transaction = nil
|
|
60
|
+
current_spans.pop until current_spans.empty?
|
|
61
|
+
|
|
62
|
+
@subscriber.unregister! if @subscriber
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def subscriber=(subscriber)
|
|
66
|
+
debug 'Registering subscriber'
|
|
67
|
+
@subscriber = subscriber
|
|
68
|
+
@subscriber.register!
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# transactions
|
|
72
|
+
|
|
73
|
+
def current_transaction
|
|
74
|
+
@current.transaction
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def current_transaction=(transaction)
|
|
78
|
+
@current.transaction = transaction
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# rubocop:disable Metrics/MethodLength
|
|
82
|
+
def start_transaction(
|
|
83
|
+
name = nil,
|
|
84
|
+
type = nil,
|
|
85
|
+
context: nil,
|
|
86
|
+
trace_context: nil
|
|
87
|
+
)
|
|
88
|
+
return nil unless config.instrument?
|
|
89
|
+
|
|
90
|
+
if (transaction = current_transaction)
|
|
91
|
+
raise ExistingTransactionError,
|
|
92
|
+
"Transactions may not be nested.\nAlready inside #{transaction}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
sampled = trace_context ? trace_context.recorded? : random_sample?
|
|
96
|
+
|
|
97
|
+
transaction =
|
|
98
|
+
Transaction.new(
|
|
99
|
+
name,
|
|
100
|
+
type,
|
|
101
|
+
context: context,
|
|
102
|
+
trace_context: trace_context,
|
|
103
|
+
sampled: sampled,
|
|
104
|
+
labels: config.default_labels
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
transaction.start
|
|
108
|
+
|
|
109
|
+
self.current_transaction = transaction
|
|
110
|
+
end
|
|
111
|
+
# rubocop:enable Metrics/MethodLength
|
|
112
|
+
|
|
113
|
+
def end_transaction(result = nil)
|
|
114
|
+
return nil unless (transaction = current_transaction)
|
|
115
|
+
|
|
116
|
+
self.current_transaction = nil
|
|
117
|
+
|
|
118
|
+
transaction.done result
|
|
119
|
+
|
|
120
|
+
enqueue.call transaction
|
|
121
|
+
|
|
122
|
+
transaction
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# spans
|
|
126
|
+
|
|
127
|
+
def current_spans
|
|
128
|
+
@current.spans
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def current_span
|
|
132
|
+
current_spans.last
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
136
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
137
|
+
# rubocop:disable Metrics/ParameterLists
|
|
138
|
+
def start_span(
|
|
139
|
+
name,
|
|
140
|
+
type = nil,
|
|
141
|
+
subtype: nil,
|
|
142
|
+
action: nil,
|
|
143
|
+
backtrace: nil,
|
|
144
|
+
context: nil,
|
|
145
|
+
trace_context: nil
|
|
146
|
+
)
|
|
147
|
+
return unless (transaction = current_transaction)
|
|
148
|
+
return unless transaction.sampled?
|
|
149
|
+
|
|
150
|
+
transaction.inc_started_spans!
|
|
151
|
+
|
|
152
|
+
if transaction.max_spans_reached?(config)
|
|
153
|
+
transaction.inc_dropped_spans!
|
|
154
|
+
return
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
parent = current_span || transaction
|
|
158
|
+
|
|
159
|
+
span = Span.new(
|
|
160
|
+
name: name,
|
|
161
|
+
subtype: subtype,
|
|
162
|
+
action: action,
|
|
163
|
+
transaction_id: transaction.id,
|
|
164
|
+
trace_context: trace_context || parent.trace_context.child,
|
|
165
|
+
type: type,
|
|
166
|
+
context: context,
|
|
167
|
+
stacktrace_builder: stacktrace_builder
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
if backtrace && config.span_frames_min_duration?
|
|
171
|
+
span.original_backtrace = backtrace
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
current_spans.push span
|
|
175
|
+
|
|
176
|
+
span.start
|
|
177
|
+
end
|
|
178
|
+
# rubocop:enable Metrics/ParameterLists
|
|
179
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
180
|
+
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
181
|
+
|
|
182
|
+
def end_span
|
|
183
|
+
return unless (span = current_spans.pop)
|
|
184
|
+
|
|
185
|
+
span.done
|
|
186
|
+
|
|
187
|
+
enqueue.call span
|
|
188
|
+
|
|
189
|
+
span
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# metadata
|
|
193
|
+
|
|
194
|
+
def set_label(key, value)
|
|
195
|
+
return unless current_transaction
|
|
196
|
+
|
|
197
|
+
key = key.to_s.gsub(/[\."\*]/, '_').to_sym
|
|
198
|
+
current_transaction.context.labels[key] = value
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def set_custom_context(context)
|
|
202
|
+
return unless current_transaction
|
|
203
|
+
current_transaction.context.custom.merge!(context)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def set_user(user)
|
|
207
|
+
return unless current_transaction
|
|
208
|
+
current_transaction.context.user = Context::User.infer(config, user)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def inspect
|
|
212
|
+
'<Atatus::Instrumenter ' \
|
|
213
|
+
"current_transaction=#{current_transaction.inspect}" \
|
|
214
|
+
'>'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
private
|
|
218
|
+
|
|
219
|
+
def random_sample?
|
|
220
|
+
rand <= config.transaction_sample_rate
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
# rubocop:enable Metrics/ClassLength
|
|
224
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Atatus
|
|
6
|
+
# @api private
|
|
7
|
+
module Logging
|
|
8
|
+
PREFIX = '[Atatus] '
|
|
9
|
+
|
|
10
|
+
LEVELS = {
|
|
11
|
+
debug: Logger::DEBUG,
|
|
12
|
+
info: Logger::INFO,
|
|
13
|
+
warn: Logger::WARN,
|
|
14
|
+
error: Logger::ERROR,
|
|
15
|
+
fatal: Logger::FATAL
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
def debug(msg, *args, &block)
|
|
19
|
+
log(:debug, msg, *args, &block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def info(msg, *args, &block)
|
|
23
|
+
log(:info, msg, *args, &block)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def warn(msg, *args, &block)
|
|
27
|
+
log(:warn, msg, *args, &block)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def error(msg, *args, &block)
|
|
31
|
+
log(:error, msg, *args, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def fatal(msg, *args, &block)
|
|
35
|
+
log(:fatal, msg, *args, &block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def log(lvl, msg, *args)
|
|
41
|
+
return unless (logger = @config&.logger)
|
|
42
|
+
return unless LEVELS[lvl] >= (@config&.log_level || 0)
|
|
43
|
+
|
|
44
|
+
formatted_msg = prepend_prefix(format(msg.to_s, *args))
|
|
45
|
+
|
|
46
|
+
return logger.send(lvl, formatted_msg) unless block_given?
|
|
47
|
+
|
|
48
|
+
logger.send(lvl, "#{formatted_msg}\n#{yield}")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def prepend_prefix(str)
|
|
52
|
+
"#{PREFIX}#{str}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|