ddtrace 1.23.2 → 1.23.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/lib/datadog/core/configuration/components.rb +4 -3
- data/lib/datadog/core/configuration.rb +3 -17
- data/lib/datadog/core/telemetry/component.rb +66 -0
- data/lib/datadog/core/telemetry/event.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
- data/lib/datadog/core/telemetry/worker.rb +158 -0
- data/lib/datadog/core/utils/only_once_successful.rb +76 -0
- data/lib/ddtrace/version.rb +1 -1
- metadata +18 -10
- data/lib/datadog/core/telemetry/client.rb +0 -95
- data/lib/datadog/core/telemetry/heartbeat.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e52d825fdd7cb0391c1e529a979862f24f8ec0412cbd1952f0ae21f3129b83f
|
4
|
+
data.tar.gz: 27ab67ddd6bd0c21a0f7de60c022c143ae2367051b4b1a744f33f01453c1d8e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0c94e18051c3fe9522493daf7321ae77246d9e5cf6d5888fd3b9c565668c882e684d3156d58867104743c6769f07437c4bc68f69f4884d0609c92279d1ea3bb
|
7
|
+
data.tar.gz: 83bab49e211de5749555906b2f59b0ee8cb8a501c2363ea625a52e6f2c318714be26dc0226e51aabfd8461b96f3036b15a856eb372729ce69bd29df7baa06ef8
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [1.23.3] - 2024-07-01
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
* Add post install message about 2.x upgrade ([#3723][])
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
* Fix telemetry events blocking main thread ([#3740][])
|
14
|
+
* Fix deadlock from telemetry threads ([#3745][])
|
15
|
+
|
5
16
|
## [1.23.2] - 2024-06-13
|
6
17
|
|
7
18
|
### Fixed
|
@@ -2826,7 +2837,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
2826
2837
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
2827
2838
|
|
2828
2839
|
|
2829
|
-
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.23.
|
2840
|
+
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.23.3...1.x-stable
|
2841
|
+
[1.23.3]: https://github.com/DataDog/dd-trace-rb/compare/v1.23.2...v1.23.3
|
2830
2842
|
[1.23.2]: https://github.com/DataDog/dd-trace-rb/compare/v1.23.1...v1.23.2
|
2831
2843
|
[1.23.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.23.0...v1.23.1
|
2832
2844
|
[1.23.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.22.0...v1.23.0
|
@@ -4142,6 +4154,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
4142
4154
|
[#3623]: https://github.com/DataDog/dd-trace-rb/issues/3623
|
4143
4155
|
[#3650]: https://github.com/DataDog/dd-trace-rb/issues/3650
|
4144
4156
|
[#3683]: https://github.com/DataDog/dd-trace-rb/issues/3683
|
4157
|
+
[#3745]: https://github.com/DataDog/dd-trace-rb/issues/3745
|
4145
4158
|
[@AdrianLC]: https://github.com/AdrianLC
|
4146
4159
|
[@Azure7111]: https://github.com/Azure7111
|
4147
4160
|
[@BabyGroot]: https://github.com/BabyGroot
|
@@ -4,7 +4,7 @@ require_relative '../diagnostics/environment_logger'
|
|
4
4
|
require_relative '../diagnostics/health'
|
5
5
|
require_relative '../logger'
|
6
6
|
require_relative '../runtime/metrics'
|
7
|
-
require_relative '../telemetry/
|
7
|
+
require_relative '../telemetry/component'
|
8
8
|
require_relative '../workers/runtime_metrics'
|
9
9
|
|
10
10
|
require_relative '../remote/component'
|
@@ -60,7 +60,7 @@ module Datadog
|
|
60
60
|
logger.debug { "Telemetry disabled. Agent network adapter not supported: #{agent_settings.adapter}" }
|
61
61
|
end
|
62
62
|
|
63
|
-
Telemetry::
|
63
|
+
Telemetry::Component.new(
|
64
64
|
enabled: enabled,
|
65
65
|
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
|
66
66
|
dependency_collection: settings.telemetry.dependency_collection
|
@@ -165,8 +165,9 @@ module Datadog
|
|
165
165
|
unused_statsd = (old_statsd - (old_statsd & new_statsd))
|
166
166
|
unused_statsd.each(&:close)
|
167
167
|
|
168
|
-
telemetry
|
168
|
+
# enqueue closing event before stopping telemetry so it will be send out on shutdown
|
169
169
|
telemetry.emit_closing! unless replacement
|
170
|
+
telemetry.stop!
|
170
171
|
end
|
171
172
|
end
|
172
173
|
end
|
@@ -81,23 +81,16 @@ module Datadog
|
|
81
81
|
configuration = self.configuration
|
82
82
|
yield(configuration)
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
components = safely_synchronize do |write_components|
|
84
|
+
safely_synchronize do |write_components|
|
87
85
|
write_components.call(
|
88
86
|
if components?
|
89
87
|
replace_components!(configuration, @components)
|
90
88
|
else
|
91
|
-
|
92
|
-
built_components = true
|
93
|
-
components
|
89
|
+
build_components(configuration)
|
94
90
|
end
|
95
91
|
)
|
96
92
|
end
|
97
93
|
|
98
|
-
# Should only be called the first time components are built
|
99
|
-
components.telemetry.started! if built_components
|
100
|
-
|
101
94
|
configuration
|
102
95
|
end
|
103
96
|
|
@@ -197,20 +190,13 @@ module Datadog
|
|
197
190
|
current_components = COMPONENTS_READ_LOCK.synchronize { defined?(@components) && @components }
|
198
191
|
return current_components if current_components || !allow_initialization
|
199
192
|
|
200
|
-
|
201
|
-
|
202
|
-
components = safely_synchronize do |write_components|
|
193
|
+
safely_synchronize do |write_components|
|
203
194
|
if defined?(@components) && @components
|
204
195
|
@components
|
205
196
|
else
|
206
|
-
built_components = true
|
207
197
|
write_components.call(build_components(configuration))
|
208
198
|
end
|
209
199
|
end
|
210
|
-
|
211
|
-
# Should only be called the first time components are built
|
212
|
-
components.telemetry.started! if built_components && components && components.telemetry
|
213
|
-
components
|
214
200
|
end
|
215
201
|
|
216
202
|
private
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'emitter'
|
4
|
+
require_relative 'event'
|
5
|
+
require_relative 'worker'
|
6
|
+
require_relative '../utils/forking'
|
7
|
+
|
8
|
+
module Datadog
|
9
|
+
module Core
|
10
|
+
module Telemetry
|
11
|
+
# Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
|
12
|
+
class Component
|
13
|
+
attr_reader :enabled
|
14
|
+
|
15
|
+
include Core::Utils::Forking
|
16
|
+
|
17
|
+
# @param enabled [Boolean] Determines whether telemetry events should be sent to the API
|
18
|
+
# @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
|
19
|
+
# @param [Boolean] dependency_collection Whether to send the `app-dependencies-loaded` event
|
20
|
+
def initialize(heartbeat_interval_seconds:, dependency_collection:, enabled: true)
|
21
|
+
@enabled = enabled
|
22
|
+
@stopped = false
|
23
|
+
|
24
|
+
@worker = Telemetry::Worker.new(
|
25
|
+
enabled: @enabled,
|
26
|
+
heartbeat_interval_seconds: heartbeat_interval_seconds,
|
27
|
+
emitter: Emitter.new,
|
28
|
+
dependency_collection: dependency_collection
|
29
|
+
)
|
30
|
+
@worker.start
|
31
|
+
end
|
32
|
+
|
33
|
+
def disable!
|
34
|
+
@enabled = false
|
35
|
+
@worker.enabled = false
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop!
|
39
|
+
return if @stopped
|
40
|
+
|
41
|
+
@worker.stop(true)
|
42
|
+
@stopped = true
|
43
|
+
end
|
44
|
+
|
45
|
+
def emit_closing!
|
46
|
+
return if !@enabled || forked?
|
47
|
+
|
48
|
+
@worker.enqueue(Event::AppClosing.new)
|
49
|
+
end
|
50
|
+
|
51
|
+
def integrations_change!
|
52
|
+
return if !@enabled || forked?
|
53
|
+
|
54
|
+
@worker.enqueue(Event::AppIntegrationsChange.new)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Report configuration changes caused by Remote Configuration.
|
58
|
+
def client_configuration_change!(changes)
|
59
|
+
return if !@enabled || forked?
|
60
|
+
|
61
|
+
@worker.enqueue(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'event'
|
4
|
+
|
5
|
+
require_relative '../utils/only_once_successful'
|
6
|
+
require_relative '../workers/polling'
|
7
|
+
require_relative '../workers/queue'
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module Core
|
11
|
+
module Telemetry
|
12
|
+
# Accumulates events and sends them to the API at a regular interval, including heartbeat event.
|
13
|
+
class Worker
|
14
|
+
include Core::Workers::Queue
|
15
|
+
include Core::Workers::Polling
|
16
|
+
|
17
|
+
DEFAULT_BUFFER_MAX_SIZE = 1000
|
18
|
+
APP_STARTED_EVENT_RETRIES = 10
|
19
|
+
|
20
|
+
TELEMETRY_STARTED_ONCE = Utils::OnlyOnceSuccessful.new(APP_STARTED_EVENT_RETRIES)
|
21
|
+
|
22
|
+
def initialize(
|
23
|
+
heartbeat_interval_seconds:,
|
24
|
+
emitter:,
|
25
|
+
dependency_collection:,
|
26
|
+
enabled: true,
|
27
|
+
shutdown_timeout: Workers::Polling::DEFAULT_SHUTDOWN_TIMEOUT,
|
28
|
+
buffer_size: DEFAULT_BUFFER_MAX_SIZE
|
29
|
+
)
|
30
|
+
@emitter = emitter
|
31
|
+
@dependency_collection = dependency_collection
|
32
|
+
|
33
|
+
# Workers::Polling settings
|
34
|
+
self.enabled = enabled
|
35
|
+
# Workers::IntervalLoop settings
|
36
|
+
self.loop_base_interval = heartbeat_interval_seconds
|
37
|
+
self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_STOP
|
38
|
+
|
39
|
+
@shutdown_timeout = shutdown_timeout
|
40
|
+
@buffer_size = buffer_size
|
41
|
+
|
42
|
+
self.buffer = buffer_klass.new(@buffer_size)
|
43
|
+
end
|
44
|
+
|
45
|
+
def start
|
46
|
+
return if !enabled? || forked?
|
47
|
+
|
48
|
+
# starts async worker
|
49
|
+
perform
|
50
|
+
end
|
51
|
+
|
52
|
+
def stop(force_stop = false, timeout = @shutdown_timeout)
|
53
|
+
buffer.close if running?
|
54
|
+
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
def enqueue(event)
|
59
|
+
return if !enabled? || forked?
|
60
|
+
|
61
|
+
buffer.push(event)
|
62
|
+
end
|
63
|
+
|
64
|
+
def sent_started_event?
|
65
|
+
TELEMETRY_STARTED_ONCE.success?
|
66
|
+
end
|
67
|
+
|
68
|
+
def failed_to_start?
|
69
|
+
TELEMETRY_STARTED_ONCE.failed?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def perform(*events)
|
75
|
+
return if !enabled? || forked?
|
76
|
+
|
77
|
+
started! unless sent_started_event?
|
78
|
+
|
79
|
+
heartbeat!
|
80
|
+
|
81
|
+
flush_events(events)
|
82
|
+
end
|
83
|
+
|
84
|
+
def flush_events(events)
|
85
|
+
return if events.nil?
|
86
|
+
return if !enabled? || !sent_started_event?
|
87
|
+
|
88
|
+
Datadog.logger.debug { "Sending #{events.count} telemetry events" }
|
89
|
+
events.each do |event|
|
90
|
+
send_event(event)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def heartbeat!
|
95
|
+
return if !enabled? || !sent_started_event?
|
96
|
+
|
97
|
+
send_event(Event::AppHeartbeat.new)
|
98
|
+
end
|
99
|
+
|
100
|
+
def started!
|
101
|
+
return unless enabled?
|
102
|
+
|
103
|
+
if failed_to_start?
|
104
|
+
Datadog.logger.debug('Telemetry app-started event exhausted retries, disabling telemetry worker')
|
105
|
+
self.enabled = false
|
106
|
+
return
|
107
|
+
end
|
108
|
+
|
109
|
+
TELEMETRY_STARTED_ONCE.run do
|
110
|
+
res = send_event(Event::AppStarted.new)
|
111
|
+
|
112
|
+
if res.ok?
|
113
|
+
Datadog.logger.debug('Telemetry app-started event is successfully sent')
|
114
|
+
|
115
|
+
send_event(Event::AppDependenciesLoaded.new) if @dependency_collection
|
116
|
+
|
117
|
+
true
|
118
|
+
else
|
119
|
+
Datadog.logger.debug('Error sending telemetry app-started event, retry after heartbeat interval...')
|
120
|
+
false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def send_event(event)
|
126
|
+
res = @emitter.request(event)
|
127
|
+
|
128
|
+
disable_on_not_found!(res)
|
129
|
+
|
130
|
+
res
|
131
|
+
end
|
132
|
+
|
133
|
+
def dequeue
|
134
|
+
buffer.pop
|
135
|
+
end
|
136
|
+
|
137
|
+
def work_pending?
|
138
|
+
run_loop? || !buffer.empty?
|
139
|
+
end
|
140
|
+
|
141
|
+
def buffer_klass
|
142
|
+
if Core::Environment::Ext::RUBY_ENGINE == 'ruby'
|
143
|
+
Core::Buffer::CRuby
|
144
|
+
else
|
145
|
+
Core::Buffer::ThreadSafe
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def disable_on_not_found!(response)
|
150
|
+
return unless response.not_found?
|
151
|
+
|
152
|
+
Datadog.logger.debug('Agent does not support telemetry; disabling future telemetry events.')
|
153
|
+
self.enabled = false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'only_once'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module Core
|
7
|
+
module Utils
|
8
|
+
# Helper class to execute something with only one success.
|
9
|
+
#
|
10
|
+
# This is useful for cases where we want to ensure that a block of code is only executed once, and only if it
|
11
|
+
# succeeds. One such example is sending app-started telemetry event.
|
12
|
+
#
|
13
|
+
# Successful execution is determined by the return value of the block: any truthy value is considered success.
|
14
|
+
#
|
15
|
+
# Thread-safe when used correctly (e.g. be careful of races when lazily initializing instances of this class).
|
16
|
+
#
|
17
|
+
# Note: In its current state, this class is not Ractor-safe.
|
18
|
+
# In https://github.com/DataDog/dd-trace-rb/pull/1398#issuecomment-797378810 we have a discussion of alternatives,
|
19
|
+
# including an alternative implementation that is Ractor-safe once spent.
|
20
|
+
class OnlyOnceSuccessful < OnlyOnce
|
21
|
+
def initialize(limit = 0)
|
22
|
+
super()
|
23
|
+
|
24
|
+
@limit = limit
|
25
|
+
@failed = false
|
26
|
+
@retries = 0
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
@mutex.synchronize do
|
31
|
+
return if @ran_once
|
32
|
+
|
33
|
+
result = yield
|
34
|
+
@ran_once = !!result
|
35
|
+
|
36
|
+
if !@ran_once && limited?
|
37
|
+
@retries += 1
|
38
|
+
check_limit!
|
39
|
+
end
|
40
|
+
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def success?
|
46
|
+
@mutex.synchronize { @ran_once && !@failed }
|
47
|
+
end
|
48
|
+
|
49
|
+
def failed?
|
50
|
+
@mutex.synchronize { @ran_once && @failed }
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def check_limit!
|
56
|
+
if @retries >= @limit
|
57
|
+
@failed = true
|
58
|
+
@ran_once = true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def limited?
|
63
|
+
!@limit.nil? && @limit > 0
|
64
|
+
end
|
65
|
+
|
66
|
+
def reset_ran_once_state_for_tests
|
67
|
+
@mutex.synchronize do
|
68
|
+
@ran_once = false
|
69
|
+
@failed = false
|
70
|
+
@retries = 0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/ddtrace/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddtrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.23.
|
4
|
+
version: 1.23.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -296,17 +296,17 @@ files:
|
|
296
296
|
- lib/datadog/core/remote/worker.rb
|
297
297
|
- lib/datadog/core/runtime/ext.rb
|
298
298
|
- lib/datadog/core/runtime/metrics.rb
|
299
|
-
- lib/datadog/core/telemetry/
|
299
|
+
- lib/datadog/core/telemetry/component.rb
|
300
300
|
- lib/datadog/core/telemetry/emitter.rb
|
301
301
|
- lib/datadog/core/telemetry/event.rb
|
302
302
|
- lib/datadog/core/telemetry/ext.rb
|
303
|
-
- lib/datadog/core/telemetry/heartbeat.rb
|
304
303
|
- lib/datadog/core/telemetry/http/adapters/net.rb
|
305
304
|
- lib/datadog/core/telemetry/http/env.rb
|
306
305
|
- lib/datadog/core/telemetry/http/ext.rb
|
307
306
|
- lib/datadog/core/telemetry/http/response.rb
|
308
307
|
- lib/datadog/core/telemetry/http/transport.rb
|
309
308
|
- lib/datadog/core/telemetry/request.rb
|
309
|
+
- lib/datadog/core/telemetry/worker.rb
|
310
310
|
- lib/datadog/core/transport/ext.rb
|
311
311
|
- lib/datadog/core/transport/http/adapters/net.rb
|
312
312
|
- lib/datadog/core/transport/http/adapters/registry.rb
|
@@ -327,6 +327,7 @@ files:
|
|
327
327
|
- lib/datadog/core/utils/hash.rb
|
328
328
|
- lib/datadog/core/utils/network.rb
|
329
329
|
- lib/datadog/core/utils/only_once.rb
|
330
|
+
- lib/datadog/core/utils/only_once_successful.rb
|
330
331
|
- lib/datadog/core/utils/safe_dup.rb
|
331
332
|
- lib/datadog/core/utils/sequence.rb
|
332
333
|
- lib/datadog/core/utils/time.rb
|
@@ -880,9 +881,16 @@ licenses:
|
|
880
881
|
- Apache-2.0
|
881
882
|
metadata:
|
882
883
|
allowed_push_host: https://rubygems.org
|
883
|
-
changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v1.23.
|
884
|
-
source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v1.23.
|
885
|
-
post_install_message:
|
884
|
+
changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v1.23.3/CHANGELOG.md
|
885
|
+
source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v1.23.3
|
886
|
+
post_install_message: |2
|
887
|
+
Thank you for installing ddtrace. We have released our next major version!
|
888
|
+
|
889
|
+
As of version 2, `ddtrace` gem has been renamed to `datadog`.
|
890
|
+
The 1.x series will now only receive maintenance updates for security and critical bug fixes.
|
891
|
+
|
892
|
+
To upgrade, please replace gem `ddtrace` with gem `datadog`.
|
893
|
+
For detailed instructions on migration, see: https://dtdg.co/ruby-v2-upgrade
|
886
894
|
rdoc_options: []
|
887
895
|
require_paths:
|
888
896
|
- lib
|
@@ -900,8 +908,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
900
908
|
- !ruby/object:Gem::Version
|
901
909
|
version: 2.0.0
|
902
910
|
requirements: []
|
903
|
-
rubygems_version: 3.4.
|
904
|
-
signing_key:
|
911
|
+
rubygems_version: 3.4.21
|
912
|
+
signing_key:
|
905
913
|
specification_version: 4
|
906
914
|
summary: Datadog tracing code for your Ruby applications
|
907
915
|
test_files: []
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'emitter'
|
4
|
-
require_relative 'event'
|
5
|
-
require_relative 'heartbeat'
|
6
|
-
require_relative '../utils/forking'
|
7
|
-
|
8
|
-
module Datadog
|
9
|
-
module Core
|
10
|
-
module Telemetry
|
11
|
-
# Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
|
12
|
-
class Client
|
13
|
-
attr_reader \
|
14
|
-
:enabled,
|
15
|
-
:unsupported
|
16
|
-
|
17
|
-
include Core::Utils::Forking
|
18
|
-
|
19
|
-
# @param enabled [Boolean] Determines whether telemetry events should be sent to the API
|
20
|
-
# @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
|
21
|
-
# @param [Boolean] dependency_collection Whether to send the `app-dependencies-loaded` event
|
22
|
-
def initialize(heartbeat_interval_seconds:, dependency_collection:, enabled: true)
|
23
|
-
@enabled = enabled
|
24
|
-
@emitter = Emitter.new
|
25
|
-
@stopped = false
|
26
|
-
@unsupported = false
|
27
|
-
@started = false
|
28
|
-
@dependency_collection = dependency_collection
|
29
|
-
|
30
|
-
@worker = Telemetry::Heartbeat.new(enabled: @enabled, heartbeat_interval_seconds: heartbeat_interval_seconds) do
|
31
|
-
next unless @started # `started!` should be the first event, thus ensure that `heartbeat!` is not sent first.
|
32
|
-
|
33
|
-
heartbeat!
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def disable!
|
38
|
-
@enabled = false
|
39
|
-
@worker.enabled = false
|
40
|
-
end
|
41
|
-
|
42
|
-
def started!
|
43
|
-
return if !@enabled || forked?
|
44
|
-
|
45
|
-
res = @emitter.request(Event::AppStarted.new)
|
46
|
-
|
47
|
-
if res.not_found? # Telemetry is only supported by agent versions 7.34 and up
|
48
|
-
Datadog.logger.debug('Agent does not support telemetry; disabling future telemetry events.')
|
49
|
-
disable!
|
50
|
-
@unsupported = true # Prevent telemetry from getting re-enabled
|
51
|
-
return res
|
52
|
-
end
|
53
|
-
|
54
|
-
@emitter.request(Event::AppDependenciesLoaded.new) if @dependency_collection
|
55
|
-
|
56
|
-
@started = true
|
57
|
-
end
|
58
|
-
|
59
|
-
def emit_closing!
|
60
|
-
return if !@enabled || forked?
|
61
|
-
|
62
|
-
@emitter.request(Event::AppClosing.new)
|
63
|
-
end
|
64
|
-
|
65
|
-
def stop!
|
66
|
-
return if @stopped
|
67
|
-
|
68
|
-
@worker.stop(true, 0)
|
69
|
-
@stopped = true
|
70
|
-
end
|
71
|
-
|
72
|
-
def integrations_change!
|
73
|
-
return if !@enabled || forked?
|
74
|
-
|
75
|
-
@emitter.request(Event::AppIntegrationsChange.new)
|
76
|
-
end
|
77
|
-
|
78
|
-
# Report configuration changes caused by Remote Configuration.
|
79
|
-
def client_configuration_change!(changes)
|
80
|
-
return if !@enabled || forked?
|
81
|
-
|
82
|
-
@emitter.request(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
def heartbeat!
|
88
|
-
return if !@enabled || forked?
|
89
|
-
|
90
|
-
@emitter.request(Event::AppHeartbeat.new)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../worker'
|
4
|
-
require_relative '../workers/polling'
|
5
|
-
|
6
|
-
module Datadog
|
7
|
-
module Core
|
8
|
-
module Telemetry
|
9
|
-
# Periodically (every DEFAULT_INTERVAL_SECONDS) sends a heartbeat event to the telemetry API.
|
10
|
-
class Heartbeat < Core::Worker
|
11
|
-
include Core::Workers::Polling
|
12
|
-
|
13
|
-
def initialize(heartbeat_interval_seconds:, enabled: true, &block)
|
14
|
-
# Workers::Polling settings
|
15
|
-
self.enabled = enabled
|
16
|
-
# Workers::IntervalLoop settings
|
17
|
-
self.loop_base_interval = heartbeat_interval_seconds
|
18
|
-
self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_STOP
|
19
|
-
super(&block)
|
20
|
-
start
|
21
|
-
end
|
22
|
-
|
23
|
-
def loop_wait_before_first_iteration?; end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def start
|
28
|
-
perform
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|