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,240 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
module Metrics
|
|
5
|
+
# @api private
|
|
6
|
+
class CpuMem
|
|
7
|
+
include Logging
|
|
8
|
+
|
|
9
|
+
# @api private
|
|
10
|
+
class Sample
|
|
11
|
+
# rubocop:disable Metrics/ParameterLists
|
|
12
|
+
def initialize(
|
|
13
|
+
system_cpu_total:,
|
|
14
|
+
system_cpu_usage:,
|
|
15
|
+
system_memory_total:,
|
|
16
|
+
system_memory_free:,
|
|
17
|
+
process_cpu_usage:,
|
|
18
|
+
process_memory_size:,
|
|
19
|
+
process_memory_rss:,
|
|
20
|
+
page_size:
|
|
21
|
+
)
|
|
22
|
+
@system_cpu_total = system_cpu_total
|
|
23
|
+
@system_cpu_usage = system_cpu_usage
|
|
24
|
+
@system_memory_total = system_memory_total
|
|
25
|
+
@system_memory_free = system_memory_free
|
|
26
|
+
@process_cpu_usage = process_cpu_usage
|
|
27
|
+
@process_memory_size = process_memory_size
|
|
28
|
+
@process_memory_rss = process_memory_rss
|
|
29
|
+
@page_size = page_size
|
|
30
|
+
end
|
|
31
|
+
# rubocop:enable Metrics/ParameterLists
|
|
32
|
+
|
|
33
|
+
attr_accessor :system_cpu_total, :system_cpu_usage,
|
|
34
|
+
:system_memory_total, :system_memory_free, :process_cpu_usage,
|
|
35
|
+
:process_memory_size, :process_memory_rss, :page_size
|
|
36
|
+
|
|
37
|
+
def delta(previous)
|
|
38
|
+
dup.tap do |sample|
|
|
39
|
+
sample.system_cpu_total =
|
|
40
|
+
system_cpu_total - previous.system_cpu_total
|
|
41
|
+
sample.system_cpu_usage =
|
|
42
|
+
system_cpu_usage - previous.system_cpu_usage
|
|
43
|
+
sample.process_cpu_usage =
|
|
44
|
+
process_cpu_usage - previous.process_cpu_usage
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def initialize(config)
|
|
50
|
+
@config = config
|
|
51
|
+
@sampler = sampler_for_platform(Metrics.platform)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
attr_reader :config, :sampler
|
|
55
|
+
|
|
56
|
+
def sample
|
|
57
|
+
@sampler.sample
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
61
|
+
def collect
|
|
62
|
+
return unless sampler
|
|
63
|
+
|
|
64
|
+
current = sample
|
|
65
|
+
|
|
66
|
+
unless @previous
|
|
67
|
+
@previous = current
|
|
68
|
+
return
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
delta = current.delta(@previous)
|
|
72
|
+
|
|
73
|
+
cpu_usage_pct = delta.system_cpu_usage.to_f / delta.system_cpu_total
|
|
74
|
+
cpu_process_pct = delta.process_cpu_usage.to_f / delta.system_cpu_total
|
|
75
|
+
|
|
76
|
+
@previous = current
|
|
77
|
+
|
|
78
|
+
{
|
|
79
|
+
'system.cpu.total.norm.pct': cpu_usage_pct,
|
|
80
|
+
'system.memory.actual.free': current.system_memory_free,
|
|
81
|
+
'system.memory.total': current.system_memory_total,
|
|
82
|
+
'system.process.cpu.total.norm.pct': cpu_process_pct,
|
|
83
|
+
'system.process.memory.size': current.process_memory_size,
|
|
84
|
+
'system.process.memory.rss.bytes':
|
|
85
|
+
current.process_memory_rss * current.page_size
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def sampler_for_platform(platform)
|
|
93
|
+
case platform
|
|
94
|
+
when :linux then Linux.new
|
|
95
|
+
else
|
|
96
|
+
warn "Unsupported platform '#{platform}' - Disabling metrics"
|
|
97
|
+
@disabled = true
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @api private
|
|
103
|
+
class Linux
|
|
104
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
105
|
+
def sample
|
|
106
|
+
proc_stat = ProcStat.new.read!
|
|
107
|
+
proc_self_stat = ProcSelfStat.new.read!
|
|
108
|
+
meminfo = Meminfo.new.read!
|
|
109
|
+
|
|
110
|
+
Sample.new(
|
|
111
|
+
system_cpu_total: proc_stat.total,
|
|
112
|
+
system_cpu_usage: proc_stat.usage,
|
|
113
|
+
system_memory_total: meminfo.total,
|
|
114
|
+
system_memory_free: meminfo.available,
|
|
115
|
+
process_cpu_usage: proc_self_stat.total,
|
|
116
|
+
process_memory_size: proc_self_stat.vsize,
|
|
117
|
+
process_memory_rss: proc_self_stat.rss,
|
|
118
|
+
page_size: meminfo.page_size
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
122
|
+
|
|
123
|
+
# @api private
|
|
124
|
+
class ProcStat
|
|
125
|
+
attr_reader :total, :usage
|
|
126
|
+
|
|
127
|
+
CPU_FIELDS = %i[
|
|
128
|
+
user
|
|
129
|
+
nice
|
|
130
|
+
system
|
|
131
|
+
idle
|
|
132
|
+
iowait
|
|
133
|
+
irq
|
|
134
|
+
softirq
|
|
135
|
+
steal
|
|
136
|
+
guest
|
|
137
|
+
guest_nice
|
|
138
|
+
].freeze
|
|
139
|
+
|
|
140
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
141
|
+
def read!
|
|
142
|
+
stat =
|
|
143
|
+
IO.readlines('/proc/stat')
|
|
144
|
+
.lazy
|
|
145
|
+
.find { |sp| sp.start_with?('cpu ') }
|
|
146
|
+
.split
|
|
147
|
+
.map(&:to_i)[1..-1]
|
|
148
|
+
|
|
149
|
+
values =
|
|
150
|
+
CPU_FIELDS.each_with_index.each_with_object({}) do |(key, i), v|
|
|
151
|
+
v[key] = stat[i] || 0
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
@total =
|
|
155
|
+
values[:user] +
|
|
156
|
+
values[:nice] +
|
|
157
|
+
values[:system] +
|
|
158
|
+
values[:idle] +
|
|
159
|
+
values[:iowait] +
|
|
160
|
+
values[:irq] +
|
|
161
|
+
values[:softirq] +
|
|
162
|
+
values[:steal]
|
|
163
|
+
|
|
164
|
+
@usage = @total - (values[:idle] + values[:iowait])
|
|
165
|
+
|
|
166
|
+
self
|
|
167
|
+
end
|
|
168
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
UTIME_POS = 13
|
|
172
|
+
STIME_POS = 14
|
|
173
|
+
VSIZE_POS = 22
|
|
174
|
+
RSS_POS = 23
|
|
175
|
+
|
|
176
|
+
# @api private
|
|
177
|
+
class ProcSelfStat
|
|
178
|
+
attr_reader :total, :vsize, :rss
|
|
179
|
+
|
|
180
|
+
def read!
|
|
181
|
+
stat =
|
|
182
|
+
IO.readlines('/proc/self/stat')
|
|
183
|
+
.lazy
|
|
184
|
+
.first
|
|
185
|
+
.split
|
|
186
|
+
.map(&:to_i)
|
|
187
|
+
|
|
188
|
+
@total = stat[UTIME_POS] + stat[STIME_POS]
|
|
189
|
+
@vsize = stat[VSIZE_POS]
|
|
190
|
+
@rss = stat[RSS_POS]
|
|
191
|
+
|
|
192
|
+
self
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @api private
|
|
197
|
+
class Meminfo
|
|
198
|
+
attr_reader :total, :available, :page_size
|
|
199
|
+
|
|
200
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
201
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
202
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
203
|
+
def read!
|
|
204
|
+
# rubocop:disable Style/RescueModifier
|
|
205
|
+
@page_size = `getconf PAGESIZE`.chomp.to_i rescue 4096
|
|
206
|
+
# rubocop:enable Style/RescueModifier
|
|
207
|
+
|
|
208
|
+
info =
|
|
209
|
+
IO.readlines('/proc/meminfo')
|
|
210
|
+
.lazy
|
|
211
|
+
.each_with_object({}) do |line, hsh|
|
|
212
|
+
if line.start_with?('MemTotal:')
|
|
213
|
+
hsh[:total] = line.split[1].to_i * 1024
|
|
214
|
+
elsif line.start_with?('MemAvailable:')
|
|
215
|
+
hsh[:available] = line.split[1].to_i * 1024
|
|
216
|
+
elsif line.start_with?('MemFree:')
|
|
217
|
+
hsh[:free] = line.split[1].to_i * 1024
|
|
218
|
+
elsif line.start_with?('Buffers:')
|
|
219
|
+
hsh[:buffers] = line.split[1].to_i * 1024
|
|
220
|
+
elsif line.start_with?('Cached:')
|
|
221
|
+
hsh[:cached] = line.split[1].to_i * 1024
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
break hsh if hsh[:total] && hsh[:available]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
@total = info[:total]
|
|
228
|
+
@available =
|
|
229
|
+
info[:available] || info[:free] + info[:buffers] + info[:cached]
|
|
230
|
+
|
|
231
|
+
self
|
|
232
|
+
end
|
|
233
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
234
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
235
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
module Metrics
|
|
5
|
+
# @api private
|
|
6
|
+
class VM
|
|
7
|
+
include Logging
|
|
8
|
+
|
|
9
|
+
def initialize(config)
|
|
10
|
+
@config = config
|
|
11
|
+
@total_time = 0
|
|
12
|
+
@disabled = false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_reader :config
|
|
16
|
+
attr_writer :disabled
|
|
17
|
+
|
|
18
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
19
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
20
|
+
def collect
|
|
21
|
+
return if disabled?
|
|
22
|
+
|
|
23
|
+
stat = GC.stat
|
|
24
|
+
thread_count = Thread.list.count
|
|
25
|
+
|
|
26
|
+
sample = {
|
|
27
|
+
'ruby.gc.count': stat[:count],
|
|
28
|
+
'ruby.threads': thread_count
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
(live_slots = stat[:heap_live_slots]) &&
|
|
32
|
+
sample[:'ruby.heap.slots.live'] = live_slots
|
|
33
|
+
(heap_slots = stat[:heap_free_slots]) &&
|
|
34
|
+
sample[:'ruby.heap.slots.free'] = heap_slots
|
|
35
|
+
(allocated = stat[:total_allocated_objects]) &&
|
|
36
|
+
sample[:'ruby.heap.allocations.total'] = allocated
|
|
37
|
+
|
|
38
|
+
return sample unless GC::Profiler.enabled?
|
|
39
|
+
|
|
40
|
+
@total_time += GC::Profiler.total_time
|
|
41
|
+
GC::Profiler.clear
|
|
42
|
+
sample[:'ruby.gc.time'] = @total_time
|
|
43
|
+
|
|
44
|
+
sample
|
|
45
|
+
rescue TypeError => e
|
|
46
|
+
error 'VM metrics encountered error: %s', e
|
|
47
|
+
debug('Backtrace:') { e.backtrace.join("\n") }
|
|
48
|
+
|
|
49
|
+
@disabled = true
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
53
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
54
|
+
|
|
55
|
+
def disabled?
|
|
56
|
+
@disabled
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
class Metricset
|
|
6
|
+
def initialize(timestamp: Util.micros, labels: nil, **samples)
|
|
7
|
+
@timestamp = timestamp
|
|
8
|
+
@labels = labels
|
|
9
|
+
@samples = samples
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_accessor :timestamp
|
|
13
|
+
attr_reader :samples, :labels
|
|
14
|
+
|
|
15
|
+
def empty?
|
|
16
|
+
samples.empty?
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Atatus
|
|
5
|
+
# @api private
|
|
6
|
+
class Middleware
|
|
7
|
+
include Logging
|
|
8
|
+
|
|
9
|
+
def initialize(app)
|
|
10
|
+
@app = app
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
14
|
+
def call(env)
|
|
15
|
+
begin
|
|
16
|
+
if running? && !path_ignored?(env)
|
|
17
|
+
transaction = start_transaction(env)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
resp = @app.call env
|
|
21
|
+
rescue InternalError
|
|
22
|
+
raise # Don't report Atatus errors
|
|
23
|
+
rescue ::Exception => e
|
|
24
|
+
context = Atatus.build_context(rack_env: env, for_type: :error)
|
|
25
|
+
Atatus.report(e, context: context, handled: false)
|
|
26
|
+
raise
|
|
27
|
+
ensure
|
|
28
|
+
if resp && transaction
|
|
29
|
+
status, headers, _body = resp
|
|
30
|
+
transaction.add_response(status, headers: headers.dup)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Atatus.end_transaction http_result(status)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
resp
|
|
37
|
+
end
|
|
38
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def http_result(status)
|
|
43
|
+
status && "HTTP #{status.to_s[0]}xx"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def path_ignored?(env)
|
|
47
|
+
config.ignore_url_patterns.any? do |r|
|
|
48
|
+
env['PATH_INFO'].match r
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def start_transaction(env)
|
|
53
|
+
context = Atatus.build_context(rack_env: env, for_type: :transaction)
|
|
54
|
+
|
|
55
|
+
Atatus.start_transaction 'Rack', 'request',
|
|
56
|
+
context: context,
|
|
57
|
+
trace_context: trace_context(env)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def trace_context(env)
|
|
61
|
+
return unless (header = env['HTTP_ATATUS_APM_TRACEPARENT'])
|
|
62
|
+
TraceContext.parse(header)
|
|
63
|
+
rescue TraceContext::InvalidTraceparentHeader
|
|
64
|
+
warn "Couldn't parse invalid traceparent header: #{header.inspect}"
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def running?
|
|
69
|
+
Atatus.running?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def config
|
|
73
|
+
@config ||= Atatus.agent.config
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module NaivelyHashable
|
|
6
|
+
def naively_hashable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_h
|
|
11
|
+
instance_variables.each_with_object({}) do |name, h|
|
|
12
|
+
key = name.to_s.delete('@').to_sym
|
|
13
|
+
value = instance_variable_get(name)
|
|
14
|
+
is_hashable =
|
|
15
|
+
value.respond_to?(:naively_hashable?) && value.naively_hashable?
|
|
16
|
+
|
|
17
|
+
h[key] = is_hashable ? value.to_h : value
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus # :nodoc:
|
|
4
|
+
# @api private
|
|
5
|
+
module Normalizers
|
|
6
|
+
# @api privagte
|
|
7
|
+
class Normalizer
|
|
8
|
+
def initialize(config)
|
|
9
|
+
@config = config
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.register(name)
|
|
13
|
+
Normalizers.register(name, self)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.register(name, klass)
|
|
18
|
+
@registered ||= {}
|
|
19
|
+
@registered[name] = klass
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.build(config)
|
|
23
|
+
normalizers = @registered.each_with_object({}) do |(name, klass), built|
|
|
24
|
+
built[name] = klass.new(config)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Collection.new(normalizers)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @api private
|
|
31
|
+
class Collection
|
|
32
|
+
# @api private
|
|
33
|
+
class SkipNormalizer
|
|
34
|
+
def initialize; end
|
|
35
|
+
|
|
36
|
+
def normalize(*_args)
|
|
37
|
+
:skip
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize(normalizers)
|
|
42
|
+
@normalizers = normalizers
|
|
43
|
+
@default = SkipNormalizer.new
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def for(name)
|
|
47
|
+
@normalizers.fetch(name) { @default }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def keys
|
|
51
|
+
@normalizers.keys
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def normalize(transaction, name, payload)
|
|
55
|
+
self.for(name).normalize(transaction, name, payload)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
%w[
|
|
61
|
+
action_controller
|
|
62
|
+
action_mailer
|
|
63
|
+
action_view
|
|
64
|
+
active_record
|
|
65
|
+
].each do |lib|
|
|
66
|
+
require "atatus/normalizers/#{lib}"
|
|
67
|
+
end
|
|
68
|
+
end
|