ddtrace 1.23.2 → 1.23.3
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 +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
|