atatus 1.6.2 → 2.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 +4 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile +49 -13
- data/LICENSE +1 -1
- data/atatus.gemspec +3 -3
- data/lib/atatus/agent.rb +18 -7
- data/lib/atatus/central_config.rb +19 -8
- data/lib/atatus/collector/base.rb +113 -1
- data/lib/atatus/collector/builder.rb +8 -0
- data/lib/atatus/collector/layer.rb +1 -1
- data/lib/atatus/collector/transport.rb +23 -2
- data/lib/atatus/{sql_summarizer.rb → config/log_level_map.rb} +22 -28
- data/lib/atatus/config/options.rb +2 -1
- data/lib/atatus/config/regexp_list.rb +1 -1
- data/lib/atatus/config/round_float.rb +31 -0
- data/lib/atatus/config/server_info.rb +50 -0
- data/lib/atatus/config/wildcard_pattern_list.rb +3 -1
- data/lib/atatus/config.rb +94 -70
- data/lib/atatus/context/company.rb +38 -0
- data/lib/atatus/context/request/socket.rb +1 -2
- data/lib/atatus/context/response.rb +1 -3
- data/lib/atatus/context.rb +4 -8
- data/lib/atatus/context_builder.rb +3 -3
- data/lib/atatus/error.rb +2 -1
- data/lib/atatus/error_builder.rb +1 -1
- data/lib/atatus/fields.rb +98 -0
- data/lib/atatus/graphql.rb +2 -0
- data/lib/atatus/grpc.rb +5 -7
- data/lib/atatus/instrumenter.rb +38 -24
- data/lib/atatus/metadata/cloud_info.rb +156 -0
- data/lib/atatus/metadata/service_info.rb +3 -3
- data/lib/atatus/metadata/system_info/container_info.rb +20 -8
- data/lib/atatus/metadata/system_info.rb +20 -5
- data/lib/atatus/metadata.rb +3 -1
- data/lib/atatus/metrics/cpu_mem_set.rb +10 -38
- data/lib/atatus/metrics/jvm_set.rb +88 -0
- data/lib/atatus/metrics/metric.rb +2 -0
- data/lib/atatus/metrics.rb +32 -16
- data/lib/atatus/middleware.rb +8 -3
- data/lib/atatus/naively_hashable.rb +1 -0
- data/lib/atatus/normalizers/rails/active_record.rb +25 -7
- data/lib/atatus/normalizers.rb +2 -2
- data/lib/atatus/opentracing.rb +5 -3
- data/lib/atatus/rails.rb +1 -1
- data/lib/atatus/span/context/db.rb +1 -1
- data/lib/atatus/span/context/destination.rb +58 -32
- data/lib/atatus/span/context/http.rb +2 -0
- data/lib/atatus/span/context/links.rb +32 -0
- data/lib/atatus/{sql.rb → span/context/message.rb} +16 -12
- data/lib/atatus/span/context/service.rb +55 -0
- data/lib/atatus/span/context.rb +28 -3
- data/lib/atatus/span.rb +35 -5
- data/lib/atatus/span_helpers.rb +12 -23
- data/lib/atatus/spies/action_dispatch.rb +10 -13
- data/lib/atatus/spies/azure_storage_table.rb +148 -0
- data/lib/atatus/spies/delayed_job.rb +19 -13
- data/lib/atatus/spies/dynamo_db.rb +56 -15
- data/lib/atatus/spies/elasticsearch.rb +54 -39
- data/lib/atatus/spies/faraday.rb +92 -58
- data/lib/atatus/spies/http.rb +33 -37
- data/lib/atatus/spies/json.rb +5 -9
- data/lib/atatus/spies/mongo.rb +26 -19
- data/lib/atatus/spies/net_http.rb +53 -51
- data/lib/atatus/spies/racecar.rb +77 -0
- data/lib/atatus/spies/rake.rb +27 -27
- data/lib/atatus/spies/redis.rb +11 -12
- data/lib/atatus/spies/resque.rb +18 -23
- data/lib/atatus/spies/s3.rb +132 -0
- data/lib/atatus/spies/sequel.rb +50 -40
- data/lib/atatus/spies/shoryuken.rb +4 -6
- data/lib/atatus/spies/sidekiq.rb +23 -31
- data/lib/atatus/spies/sinatra.rb +20 -28
- data/lib/atatus/spies/sneakers.rb +2 -0
- data/lib/atatus/spies/sns.rb +126 -0
- data/lib/atatus/spies/sqs.rb +231 -0
- data/lib/atatus/spies/sucker_punch.rb +20 -22
- data/lib/atatus/spies/tilt.rb +10 -13
- data/lib/atatus/spies.rb +20 -0
- data/lib/atatus/sql/signature.rb +4 -2
- data/lib/atatus/sql/tokenizer.rb +23 -7
- data/lib/atatus/stacktrace/frame.rb +1 -0
- data/lib/atatus/stacktrace_builder.rb +12 -16
- data/lib/atatus/subscriber.rb +1 -0
- data/lib/atatus/trace_context/traceparent.rb +5 -8
- data/lib/atatus/trace_context/tracestate.rb +16 -14
- data/lib/atatus/trace_context.rb +6 -16
- data/lib/atatus/transaction.rb +25 -4
- data/lib/atatus/transport/base.rb +1 -3
- data/lib/atatus/transport/connection/http.rb +11 -3
- data/lib/atatus/transport/connection/proxy_pipe.rb +1 -2
- data/lib/atatus/transport/connection.rb +3 -2
- data/lib/atatus/transport/filters/hash_sanitizer.rb +16 -34
- data/lib/atatus/transport/filters/secrets_filter.rb +35 -12
- data/lib/atatus/transport/serializers/context_serializer.rb +1 -2
- data/lib/atatus/transport/serializers/metadata_serializer.rb +54 -8
- data/lib/atatus/transport/serializers/metricset_serializer.rb +2 -2
- data/lib/atatus/transport/serializers/span_serializer.rb +55 -9
- data/lib/atatus/transport/serializers/transaction_serializer.rb +1 -0
- data/lib/atatus/transport/serializers.rb +9 -6
- data/lib/atatus/transport/user_agent.rb +16 -9
- data/lib/atatus/transport/worker.rb +2 -1
- data/lib/atatus/util/deep_dup.rb +65 -0
- data/lib/atatus/util/precision_validator.rb +46 -0
- data/lib/atatus/util.rb +2 -0
- data/lib/atatus/version.rb +1 -1
- data/lib/atatus.rb +48 -5
- metadata +41 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 454ba0ab877ac91b387bb0d4b3355494c2707a56634cd97774b0bcdb3e2194a6
|
|
4
|
+
data.tar.gz: dc8b8beca08a3a6ecc278c999d48ea7c316ac1fe8f5a221cd32df8a0bcd37262
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8377d4e174399b782592ce39b48ca738a806a8b881fe045cb3586cdc232d1f9d29a3f99ec02ab27cddd8c84a3c250b9bf35ac1f1bbb5f82c94a4d7fb8f7db661
|
|
7
|
+
data.tar.gz: 6bc01e9bec29bf52a0910abc465cbee55ca8c17dbd9bee531028d8ade630fa91517b06493c928aecfdd7cccee0bbc88cfeeff6ee143c758aec2e606d2f830367
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## 2.0.0 (Fri, 19 Jan 2024)
|
|
8
|
+
|
|
9
|
+
- Change the instrumentation method to prepend mode.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## 1.7.0 (Fri, 15 Jul 2022)
|
|
13
|
+
|
|
14
|
+
- Added support for analytics.
|
|
15
|
+
- Fixed sequel instrumentation.
|
|
16
|
+
|
|
17
|
+
|
|
7
18
|
## 1.6.2 (Mon, 31 Jan 2022)
|
|
8
19
|
|
|
9
20
|
- Fixed config environment.
|
data/Gemfile
CHANGED
|
@@ -22,42 +22,50 @@ source 'https://rubygems.org'
|
|
|
22
22
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
23
23
|
|
|
24
24
|
# Tools
|
|
25
|
-
gem 'bootsnap', require: false
|
|
26
25
|
gem 'cucumber', require: false
|
|
27
|
-
gem 'pry'
|
|
28
26
|
gem 'rack-test'
|
|
29
27
|
gem 'rspec', '~> 3'
|
|
30
28
|
gem 'rspec-its'
|
|
31
|
-
gem 'rubocop', require:
|
|
32
|
-
gem 'rubocop-performance', require:
|
|
29
|
+
gem 'rubocop', require: false
|
|
30
|
+
gem 'rubocop-performance', require: false
|
|
33
31
|
gem 'timecop'
|
|
34
32
|
gem 'webmock'
|
|
35
33
|
|
|
36
34
|
# Integrations
|
|
37
35
|
gem 'aws-sdk-dynamodb', require: nil
|
|
36
|
+
gem 'aws-sdk-s3', require: nil
|
|
38
37
|
gem 'aws-sdk-sqs', require: nil
|
|
38
|
+
gem 'aws-sdk-sns', require: nil
|
|
39
|
+
gem 'azure-storage-table', require: nil if RUBY_VERSION < '3.0'
|
|
40
|
+
gem 'ecs-logging', require: 'ecs_logging/logger'
|
|
39
41
|
gem 'elasticsearch', require: nil
|
|
40
42
|
gem 'fakeredis', require: nil
|
|
41
43
|
gem 'faraday', require: nil
|
|
42
44
|
gem 'graphql', require: nil
|
|
43
|
-
|
|
44
|
-
gem '
|
|
45
|
+
if !defined?(JRUBY_VERSION) && RUBY_VERSION < '2.5'
|
|
46
|
+
gem 'google-protobuf', '< 3.12'
|
|
47
|
+
end
|
|
48
|
+
gem 'grpc' if !defined?(JRUBY_VERSION) && RUBY_VERSION < '3.0'
|
|
45
49
|
gem 'json'
|
|
46
50
|
gem 'json-schema', require: nil
|
|
47
51
|
gem 'mongo', require: nil
|
|
48
52
|
gem 'opentracing', require: nil
|
|
49
|
-
gem 'rake', require: nil
|
|
53
|
+
gem 'rake', '>= 13.0', require: nil
|
|
54
|
+
gem 'racecar', require: nil if !defined?(JRUBY_VERSION)
|
|
50
55
|
gem 'resque', require: nil
|
|
51
56
|
gem 'sequel', require: nil
|
|
52
57
|
gem 'shoryuken', require: nil
|
|
53
58
|
gem 'sidekiq', require: nil
|
|
54
59
|
gem 'simplecov', require: false
|
|
55
60
|
gem 'simplecov-cobertura', require: false
|
|
56
|
-
gem 'sneakers', '~> 2.12', require: nil
|
|
57
61
|
gem 'sucker_punch', '~> 2.0', require: nil
|
|
58
62
|
gem 'yard', require: nil
|
|
59
63
|
gem 'yarjuf'
|
|
60
64
|
|
|
65
|
+
if RUBY_VERSION < '2.5'
|
|
66
|
+
gem 'loofah', '~> 2.20.0', require: nil
|
|
67
|
+
end
|
|
68
|
+
|
|
61
69
|
## Install Framework
|
|
62
70
|
GITHUB_REPOS = {
|
|
63
71
|
'grape' => 'ruby-grape/grape',
|
|
@@ -74,9 +82,15 @@ frameworks_versions = parsed_frameworks.inject({}) do |frameworks, str|
|
|
|
74
82
|
end
|
|
75
83
|
|
|
76
84
|
frameworks_versions.each do |framework, version|
|
|
85
|
+
if framework =='rails' && RUBY_VERSION >= '3.1'
|
|
86
|
+
gem 'net-smtp', require: false
|
|
87
|
+
end
|
|
88
|
+
|
|
77
89
|
case version
|
|
78
|
-
when 'master'
|
|
90
|
+
when 'master' # grape
|
|
79
91
|
gem framework, github: GITHUB_REPOS.fetch(framework)
|
|
92
|
+
when 'main' # sinatra, rails
|
|
93
|
+
gem framework, github: GITHUB_REPOS.fetch(framework), branch: 'main'
|
|
80
94
|
when /.+/
|
|
81
95
|
gem framework, "~> #{version}.0"
|
|
82
96
|
else
|
|
@@ -85,18 +99,40 @@ frameworks_versions.each do |framework, version|
|
|
|
85
99
|
end
|
|
86
100
|
|
|
87
101
|
if frameworks_versions.key?('rails')
|
|
88
|
-
unless frameworks_versions['rails']
|
|
102
|
+
unless /^(main|6)/.match?(frameworks_versions['rails'])
|
|
89
103
|
gem 'delayed_job', require: nil
|
|
90
104
|
end
|
|
91
105
|
end
|
|
92
106
|
|
|
93
107
|
if RUBY_PLATFORM == 'java'
|
|
94
|
-
|
|
95
|
-
gem '
|
|
108
|
+
# See issue #6547 in the JRuby repo. It is fixed in JRuby 9.3
|
|
109
|
+
gem 'i18n', '< 1.8.8' if JRUBY_VERSION < '9.3'
|
|
110
|
+
|
|
111
|
+
case rails = frameworks_versions['rails']
|
|
112
|
+
when 'main'
|
|
113
|
+
gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter', glob: 'activerecord-jdbcsqlite3-adapter/*.gemspec'
|
|
114
|
+
when ''
|
|
115
|
+
gem 'activerecord-jdbcsqlite3-adapter', "~> 61.0"
|
|
116
|
+
when nil
|
|
117
|
+
gem 'jdbc-sqlite3'
|
|
118
|
+
else
|
|
119
|
+
gem 'activerecord-jdbcsqlite3-adapter', "~> #{rails.tr('.', '')}.0"
|
|
120
|
+
end
|
|
96
121
|
elsif frameworks_versions['rails'] =~ /^(4|5)/
|
|
97
122
|
gem 'sqlite3', '~> 1.3.6'
|
|
123
|
+
elsif RUBY_VERSION < '2.7'
|
|
124
|
+
gem 'sqlite3', '~> 1.4.4'
|
|
98
125
|
else
|
|
99
|
-
gem 'sqlite3'
|
|
126
|
+
gem 'sqlite3'
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# sneakers main only supports >=2.5.0
|
|
130
|
+
if Gem::Version.create(RUBY_VERSION) >= Gem::Version.create('2.5.0') && !defined?(JRUBY_VERSION)
|
|
131
|
+
gem 'sneakers', github: 'jondot/sneakers', ref: 'd761dfe1493', require: nil
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if Gem::Version.create(RUBY_VERSION) <= Gem::Version.create('2.5.0')
|
|
135
|
+
gem 'bigdecimal', '1.3.5'
|
|
100
136
|
end
|
|
101
137
|
|
|
102
138
|
group :bench do
|
data/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
All components of this product are Copyright (c)
|
|
1
|
+
All components of this product are Copyright (c) 2024 Atatus. All rights reserved.
|
|
2
2
|
|
|
3
3
|
Except as otherwise expressly provided in this Agreement,
|
|
4
4
|
End User shall not (and shall not permit any third party to):
|
data/atatus.gemspec
CHANGED
|
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
|
|
|
6
6
|
spec.name = 'atatus'
|
|
7
7
|
spec.version = Atatus::VERSION
|
|
8
8
|
spec.authors = ['Atatus']
|
|
9
|
-
spec.email = 'success@atatus.com'
|
|
9
|
+
spec.email = ['success@atatus.com']
|
|
10
10
|
|
|
11
11
|
spec.summary = 'Atatus Ruby Agent'
|
|
12
12
|
spec.homepage = 'https://www.atatus.com'
|
|
@@ -14,8 +14,7 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
'changelog_uri' => 'https://docs.atatus.com/docs/release-notes/ruby.html',
|
|
15
15
|
'documentation_uri' => 'https://docs.atatus.com/docs/application-monitoring/ruby-agent/overview.html',
|
|
16
16
|
}
|
|
17
|
-
spec.
|
|
18
|
-
spec.licenses = ['Atatus']
|
|
17
|
+
spec.license = 'Apache-2.0'
|
|
19
18
|
spec.required_ruby_version = ">= 2.3.0"
|
|
20
19
|
spec.extra_rdoc_files = [
|
|
21
20
|
"CHANGELOG.md",
|
|
@@ -31,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
|
31
30
|
|
|
32
31
|
spec.add_dependency('concurrent-ruby', '~> 1.0')
|
|
33
32
|
spec.add_dependency('http', '>= 3.0')
|
|
33
|
+
spec.add_runtime_dependency('ruby2_keywords')
|
|
34
34
|
|
|
35
35
|
spec.require_paths = ['lib']
|
|
36
36
|
end
|
data/lib/atatus/agent.rb
CHANGED
|
@@ -137,7 +137,7 @@ module Atatus
|
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
def stop
|
|
140
|
-
|
|
140
|
+
info 'Stopping agent'
|
|
141
141
|
|
|
142
142
|
central_config.stop
|
|
143
143
|
metrics.stop
|
|
@@ -154,7 +154,6 @@ module Atatus
|
|
|
154
154
|
# transport
|
|
155
155
|
|
|
156
156
|
def enqueue(obj)
|
|
157
|
-
# transport.submit obj
|
|
158
157
|
case obj
|
|
159
158
|
when Atatus::Transaction
|
|
160
159
|
collector.add_txn(obj)
|
|
@@ -164,7 +163,7 @@ module Atatus
|
|
|
164
163
|
collector.add_error(obj)
|
|
165
164
|
when Atatus::Metricset
|
|
166
165
|
collector.add_metrics(obj)
|
|
167
|
-
end
|
|
166
|
+
end
|
|
168
167
|
end
|
|
169
168
|
|
|
170
169
|
# instrumentation
|
|
@@ -231,8 +230,8 @@ module Atatus
|
|
|
231
230
|
end
|
|
232
231
|
# rubocop:enable Metrics/ParameterLists
|
|
233
232
|
|
|
234
|
-
def end_span
|
|
235
|
-
instrumenter.end_span
|
|
233
|
+
def end_span(span = nil)
|
|
234
|
+
instrumenter.end_span(span)
|
|
236
235
|
end
|
|
237
236
|
|
|
238
237
|
def set_label(key, value)
|
|
@@ -247,6 +246,18 @@ module Atatus
|
|
|
247
246
|
instrumenter.set_user(user)
|
|
248
247
|
end
|
|
249
248
|
|
|
249
|
+
def set_company(company)
|
|
250
|
+
instrumenter.set_company(company)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def set_response_body(response_body)
|
|
254
|
+
instrumenter.set_response_body(response_body)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def set_destination(address: nil, port: nil, service: nil, cloud: nil)
|
|
258
|
+
current_span&.set_destination(address: nil, port: nil, service: nil, cloud: nil)
|
|
259
|
+
end
|
|
260
|
+
|
|
250
261
|
def build_context(rack_env:, for_type:)
|
|
251
262
|
@context_builder.build(rack_env: rack_env, for_type: for_type)
|
|
252
263
|
end
|
|
@@ -296,8 +307,8 @@ module Atatus
|
|
|
296
307
|
def detect_forking!
|
|
297
308
|
return if @pid == Process.pid
|
|
298
309
|
|
|
299
|
-
config.logger.debug
|
|
300
|
-
restarting threads in process [PID:#{Process.pid}]"
|
|
310
|
+
config.logger.debug(
|
|
311
|
+
"Forked process detected, restarting threads in process [PID:#{Process.pid}]")
|
|
301
312
|
|
|
302
313
|
central_config.handle_forking!
|
|
303
314
|
collector.handle_forking!
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
require 'atatus/central_config/cache_control'
|
|
21
21
|
|
|
22
|
+
# rubocop:disable Style/AccessorGrouping
|
|
22
23
|
module Atatus
|
|
23
24
|
# @api private
|
|
24
25
|
class CentralConfig
|
|
@@ -27,6 +28,7 @@ module Atatus
|
|
|
27
28
|
# @api private
|
|
28
29
|
class ResponseError < InternalError
|
|
29
30
|
def initialize(response)
|
|
31
|
+
super
|
|
30
32
|
@response = response
|
|
31
33
|
end
|
|
32
34
|
|
|
@@ -66,14 +68,15 @@ module Atatus
|
|
|
66
68
|
def fetch_and_apply_config
|
|
67
69
|
@promise =
|
|
68
70
|
Concurrent::Promise
|
|
69
|
-
.execute
|
|
70
|
-
.on_success(
|
|
71
|
-
.rescue(
|
|
71
|
+
.execute { fetch_config }
|
|
72
|
+
.on_success { |resp| handle_success(resp) }
|
|
73
|
+
.rescue { |err| handle_error(err) }
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
def fetch_config
|
|
75
77
|
resp = perform_request
|
|
76
78
|
|
|
79
|
+
# rubocop:disable Lint/DuplicateBranch
|
|
77
80
|
case resp.status
|
|
78
81
|
when 200..299
|
|
79
82
|
resp
|
|
@@ -84,6 +87,7 @@ module Atatus
|
|
|
84
87
|
when 500..599
|
|
85
88
|
raise ServerError, resp
|
|
86
89
|
end
|
|
90
|
+
# rubocop:enable Lint/DuplicateBranch
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
def assign(update)
|
|
@@ -117,14 +121,14 @@ module Atatus
|
|
|
117
121
|
end
|
|
118
122
|
|
|
119
123
|
if resp.status == 304
|
|
120
|
-
|
|
124
|
+
debug 'Received 304 Not Modified'
|
|
121
125
|
else
|
|
122
126
|
if resp.body && !resp.body.empty?
|
|
123
127
|
update = JSON.parse(resp.body.to_s)
|
|
124
128
|
assign(update)
|
|
125
129
|
end
|
|
126
130
|
|
|
127
|
-
if update
|
|
131
|
+
if update&.any?
|
|
128
132
|
info 'Updated config from Kibana'
|
|
129
133
|
debug 'Modified: %s', update.inspect
|
|
130
134
|
debug 'Modified original options: %s', @modified_options.inspect
|
|
@@ -162,11 +166,12 @@ module Atatus
|
|
|
162
166
|
@server_url ||=
|
|
163
167
|
config.server_url +
|
|
164
168
|
'/config/v1/agents' \
|
|
165
|
-
"?service.name=#{config.service_name}"
|
|
169
|
+
"?service.name=#{CGI.escape(config.service_name)}" \
|
|
170
|
+
"&service.environment=#{CGI.escape(config.environment || '')}"
|
|
166
171
|
end
|
|
167
172
|
|
|
168
173
|
def headers
|
|
169
|
-
{ '
|
|
174
|
+
{ 'If-None-Match': @etag }
|
|
170
175
|
end
|
|
171
176
|
|
|
172
177
|
def schedule_next_fetch(resp = nil)
|
|
@@ -178,9 +183,15 @@ module Atatus
|
|
|
178
183
|
DEFAULT_MAX_AGE
|
|
179
184
|
end
|
|
180
185
|
|
|
186
|
+
if seconds < 5
|
|
187
|
+
debug "Next fetch is too low (#{seconds}s) - increasing to default"
|
|
188
|
+
seconds = 5
|
|
189
|
+
end
|
|
190
|
+
|
|
181
191
|
@scheduled_task =
|
|
182
192
|
Concurrent::ScheduledTask
|
|
183
|
-
.execute(seconds
|
|
193
|
+
.execute(seconds) { fetch_and_apply_config }
|
|
184
194
|
end
|
|
185
195
|
end
|
|
186
196
|
end
|
|
197
|
+
# rubocop:enable Style/AccessorGrouping
|
|
@@ -42,7 +42,12 @@ module Atatus
|
|
|
42
42
|
@metrics_lock = Mutex.new
|
|
43
43
|
@metrics_agg = []
|
|
44
44
|
|
|
45
|
+
@analytics = @config.analytics
|
|
46
|
+
@analytics_lock = Mutex.new
|
|
47
|
+
@analytics_agg = []
|
|
48
|
+
|
|
45
49
|
@hostinfo_response = {}
|
|
50
|
+
@hostinfo_response["analytics"] = true
|
|
46
51
|
@transport = Atatus::BaseTransport.new(config)
|
|
47
52
|
@collect_counter = 0
|
|
48
53
|
@running = false
|
|
@@ -154,6 +159,95 @@ module Atatus
|
|
|
154
159
|
end
|
|
155
160
|
end
|
|
156
161
|
|
|
162
|
+
def add_analytics(txn)
|
|
163
|
+
analytics_txn = {}
|
|
164
|
+
analytics_txn[:timestamp] = Util.ms(txn.timestamp).to_i
|
|
165
|
+
analytics_txn[:txnId] = ""
|
|
166
|
+
analytics_txn[:txnId] = txn.id if !txn.id.nil?
|
|
167
|
+
analytics_txn[:traceId] = ""
|
|
168
|
+
analytics_txn[:traceId] = txn.trace_id if !txn.trace_id.nil?
|
|
169
|
+
analytics_txn[:name] = txn.name
|
|
170
|
+
analytics_txn[:duration] = Util.ms(txn.duration)
|
|
171
|
+
|
|
172
|
+
if !txn.context.nil?
|
|
173
|
+
if !txn.context.request.nil?
|
|
174
|
+
r = txn.context.request
|
|
175
|
+
|
|
176
|
+
analytics_txn[:method] = r.method if !r.method.nil?
|
|
177
|
+
|
|
178
|
+
if !r.headers.nil?
|
|
179
|
+
analytics_txn[:requestHeaders] = r.headers
|
|
180
|
+
analytics_txn[:userAgent] = r.headers['User-Agent'] if r.headers.key?('User-Agent')
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if !r.body.nil?
|
|
184
|
+
if !r.body.empty?
|
|
185
|
+
if r.body != "[SKIPPED]"
|
|
186
|
+
analytics_txn[:requestBody] = r.body.to_json
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if !r.url.nil?
|
|
192
|
+
analytics_txn[:url] = r.url.full
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
if !r.socket.nil?
|
|
196
|
+
analytics_txn[:ip] = r.socket.remote_addr
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
if
|
|
202
|
+
defined?(txn.context.response_body) &&
|
|
203
|
+
!txn.context.response_body.nil?
|
|
204
|
+
then
|
|
205
|
+
analytics_txn[:responseBody] = txn.context.response_body
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
if !txn.context.response.nil?
|
|
209
|
+
if !txn.context.response.headers.nil?
|
|
210
|
+
analytics_txn[:responseHeaders] = txn.context.response.headers
|
|
211
|
+
end
|
|
212
|
+
if !txn.context.response.status_code.nil?
|
|
213
|
+
analytics_txn[:statusCode] = txn.context.response.status_code.to_i
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
if
|
|
218
|
+
defined?(txn.context.custom) &&
|
|
219
|
+
!txn.context.custom.nil? &&
|
|
220
|
+
!txn.context.custom.empty?
|
|
221
|
+
then
|
|
222
|
+
analytics_txn[:customData] = txn.context.custom
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
if
|
|
226
|
+
defined?(txn.context.user) &&
|
|
227
|
+
!txn.context.user.nil? &&
|
|
228
|
+
!txn.context.user.empty?
|
|
229
|
+
then
|
|
230
|
+
analytics_txn[:userId] = txn.context.user.id
|
|
231
|
+
analytics_txn[:userEmail] = txn.context.user.email
|
|
232
|
+
analytics_txn[:userName] = txn.context.user.username
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
if
|
|
236
|
+
defined?(txn.context.company) &&
|
|
237
|
+
!txn.context.company.nil? &&
|
|
238
|
+
!txn.context.company.empty?
|
|
239
|
+
then
|
|
240
|
+
analytics_txn[:companyId] = txn.context.company.id
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
@analytics_lock.synchronize do
|
|
245
|
+
if @analytics_agg.length < 10000
|
|
246
|
+
@analytics_agg << analytics_txn
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
157
251
|
def add_span(span)
|
|
158
252
|
ensure_worker_running
|
|
159
253
|
|
|
@@ -377,6 +471,13 @@ module Atatus
|
|
|
377
471
|
end
|
|
378
472
|
end
|
|
379
473
|
|
|
474
|
+
if @hostinfo_response.key?("analytics")
|
|
475
|
+
if @hostinfo_response["analytics"] == true && @analytics == true
|
|
476
|
+
if background == false
|
|
477
|
+
add_analytics txn
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
end
|
|
380
481
|
end
|
|
381
482
|
end
|
|
382
483
|
|
|
@@ -420,7 +521,6 @@ module Atatus
|
|
|
420
521
|
@collect_counter += 1
|
|
421
522
|
|
|
422
523
|
end_time = (Time.now.to_f * 1000).to_i
|
|
423
|
-
debug '%s: data collector', pid_str
|
|
424
524
|
|
|
425
525
|
txns_data = nil
|
|
426
526
|
txn_hist_data = nil
|
|
@@ -429,6 +529,7 @@ module Atatus
|
|
|
429
529
|
error_requests_data = nil
|
|
430
530
|
errors_data = nil
|
|
431
531
|
metrics_data = nil
|
|
532
|
+
analytics_data = nil
|
|
432
533
|
|
|
433
534
|
@txns_lock.synchronize do
|
|
434
535
|
txns_data = @txns_agg
|
|
@@ -447,6 +548,11 @@ module Atatus
|
|
|
447
548
|
@error_requests_agg = []
|
|
448
549
|
end
|
|
449
550
|
|
|
551
|
+
@analytics_lock.synchronize do
|
|
552
|
+
analytics_data = @analytics_agg
|
|
553
|
+
@analytics_agg = []
|
|
554
|
+
end
|
|
555
|
+
|
|
450
556
|
@errors_lock.synchronize do
|
|
451
557
|
errors_data = @errors_aggs
|
|
452
558
|
@errors_aggs = []
|
|
@@ -473,6 +579,12 @@ module Atatus
|
|
|
473
579
|
@transport.errors(start_time, end_time, errors_data) unless errors_data.empty?
|
|
474
580
|
|
|
475
581
|
@transport.metrics(start_time, end_time, metrics_data) unless metrics_data.empty?
|
|
582
|
+
|
|
583
|
+
if @hostinfo_response.key?("analytics")
|
|
584
|
+
if @hostinfo_response["analytics"] == true && @analytics == true
|
|
585
|
+
@transport.analytics(start_time, end_time, analytics_data) unless analytics_data.empty?
|
|
586
|
+
end
|
|
587
|
+
end
|
|
476
588
|
end
|
|
477
589
|
end
|
|
478
590
|
end
|
|
@@ -92,6 +92,14 @@ module Atatus
|
|
|
92
92
|
payload
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
def analytics(start_time, end_time, analytics_data)
|
|
96
|
+
payload = common()
|
|
97
|
+
payload[:startTime] = start_time
|
|
98
|
+
payload[:endTime] = end_time
|
|
99
|
+
payload[:requests] = analytics_data
|
|
100
|
+
payload
|
|
101
|
+
end
|
|
102
|
+
|
|
95
103
|
private
|
|
96
104
|
|
|
97
105
|
def keyword_field(value)
|
|
@@ -14,6 +14,7 @@ module Atatus
|
|
|
14
14
|
ERROR_ENDPOINT = "/track/apm/error".freeze
|
|
15
15
|
ERROR_METRIC_ENDPOINT = "/track/apm/error_metric".freeze
|
|
16
16
|
METRIC_ENDPOINT = "/track/apm/metric".freeze
|
|
17
|
+
ANALYTICS_ENDPOINT = "/track/apm/analytics/txn".freeze
|
|
17
18
|
|
|
18
19
|
def initialize(config)
|
|
19
20
|
@config = config
|
|
@@ -24,6 +25,12 @@ module Atatus
|
|
|
24
25
|
@notify_host = "https://apm-rx.atatus.com"
|
|
25
26
|
end
|
|
26
27
|
|
|
28
|
+
@analytics_notify_host = @config.analytics_notify_host
|
|
29
|
+
uri = URI(@analytics_notify_host)
|
|
30
|
+
if not uri.kind_of?(URI::HTTPS) and not uri.kind_of?(URI::HTTP)
|
|
31
|
+
@analytics_notify_host = "https://an-rx.atatus.com"
|
|
32
|
+
end
|
|
33
|
+
|
|
27
34
|
@builder = Atatus::Builder.new(config)
|
|
28
35
|
@headers = {}
|
|
29
36
|
@headers['Content-Type'] = "application/json"
|
|
@@ -71,6 +78,11 @@ module Atatus
|
|
|
71
78
|
post(METRIC_ENDPOINT, payload)
|
|
72
79
|
end
|
|
73
80
|
|
|
81
|
+
def analytics(start_time, end_time, analytics_data)
|
|
82
|
+
payload = @builder.analytics(start_time, end_time, analytics_data)
|
|
83
|
+
post(ANALYTICS_ENDPOINT, payload)
|
|
84
|
+
end
|
|
85
|
+
|
|
74
86
|
private
|
|
75
87
|
|
|
76
88
|
def post(endpoint, data)
|
|
@@ -80,7 +92,12 @@ module Atatus
|
|
|
80
92
|
end
|
|
81
93
|
|
|
82
94
|
begin
|
|
83
|
-
|
|
95
|
+
notify_host = @notify_host
|
|
96
|
+
if endpoint == ANALYTICS_ENDPOINT
|
|
97
|
+
notify_host = @analytics_notify_host
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
uri = URI(notify_host + endpoint)
|
|
84
101
|
uri.query = URI.encode_www_form({"license_key": @config.license_key, "agent_name": AGENT_NAME, "agent_version": VERSION})
|
|
85
102
|
|
|
86
103
|
request = Net::HTTP::Post.new(uri.request_uri, @headers)
|
|
@@ -90,7 +107,7 @@ module Atatus
|
|
|
90
107
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
91
108
|
response = http.start { |http| http.request(request) }
|
|
92
109
|
rescue SystemCallError, Timeout::Error, EOFError, SocketError => e
|
|
93
|
-
error format('Atatus transport [%s%s] failed with exception: %s',
|
|
110
|
+
error format('Atatus transport [%s%s] failed with exception: %s', notify_host, endpoint, e.message)
|
|
94
111
|
return
|
|
95
112
|
end
|
|
96
113
|
|
|
@@ -109,6 +126,10 @@ module Atatus
|
|
|
109
126
|
|
|
110
127
|
resp = JSON.parse response.body
|
|
111
128
|
if resp
|
|
129
|
+
if resp.key?("analytics")
|
|
130
|
+
@hostinfo_response['analytics'] = resp["analytics"]
|
|
131
|
+
end
|
|
132
|
+
|
|
112
133
|
if resp.key?("capturePercentiles")
|
|
113
134
|
@capture_percentiles = resp["capturePercentiles"]
|
|
114
135
|
@hostinfo_response['capturePercentiles'] = @capture_percentiles
|
|
@@ -17,37 +17,31 @@
|
|
|
17
17
|
|
|
18
18
|
# frozen_string_literal: true
|
|
19
19
|
|
|
20
|
-
require 'atatus/util/lru_cache'
|
|
21
|
-
|
|
22
20
|
module Atatus
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
class Config
|
|
22
|
+
# @api private
|
|
23
|
+
class LogLevelMap
|
|
24
|
+
LEVELS = {
|
|
25
|
+
debug: Logger::DEBUG,
|
|
26
|
+
info: Logger::INFO,
|
|
27
|
+
warn: Logger::WARN,
|
|
28
|
+
error: Logger::ERROR,
|
|
29
|
+
fatal: Logger::FATAL,
|
|
30
|
+
trace: Logger::DEBUG,
|
|
31
|
+
warning: Logger::WARN,
|
|
32
|
+
critical: Logger::FATAL,
|
|
33
|
+
off: Logger::FATAL
|
|
34
|
+
}.freeze
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def self.cache
|
|
40
|
-
@cache ||= Util::LruCache.new
|
|
41
|
-
end
|
|
36
|
+
DEFAULT = Logger::INFO
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end || DEFAULT
|
|
38
|
+
def call(value)
|
|
39
|
+
if value.is_a?(Integer)
|
|
40
|
+
LEVELS.value?(value) ? value : DEFAULT
|
|
41
|
+
else
|
|
42
|
+
LEVELS.fetch(value.to_sym, DEFAULT)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
51
45
|
end
|
|
52
46
|
end
|
|
53
47
|
end
|