datadog 2.22.0 → 2.24.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 +100 -1
- data/ext/LIBDATADOG_DEVELOPMENT.md +1 -58
- data/ext/datadog_profiling_native_extension/collectors_stack.c +21 -5
- data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +9 -4
- data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +12 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +4 -0
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
- data/ext/libdatadog_api/feature_flags.c +554 -0
- data/ext/libdatadog_api/feature_flags.h +5 -0
- data/ext/libdatadog_api/init.c +2 -0
- data/ext/libdatadog_api/library_config.c +12 -11
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/api_security/route_extractor.rb +23 -6
- data/lib/datadog/appsec/api_security/sampler.rb +7 -4
- data/lib/datadog/appsec/assets/blocked.html +8 -0
- data/lib/datadog/appsec/assets/blocked.json +1 -1
- data/lib/datadog/appsec/assets/blocked.text +3 -1
- data/lib/datadog/appsec/assets.rb +1 -1
- data/lib/datadog/appsec/context.rb +2 -1
- data/lib/datadog/appsec/remote.rb +5 -9
- data/lib/datadog/appsec/response.rb +18 -4
- data/lib/datadog/appsec/security_engine/result.rb +2 -1
- data/lib/datadog/core/configuration/components.rb +30 -3
- data/lib/datadog/core/configuration/config_helper.rb +2 -2
- data/lib/datadog/core/configuration/deprecations.rb +2 -2
- data/lib/datadog/core/configuration/option_definition.rb +4 -2
- data/lib/datadog/core/configuration/options.rb +8 -5
- data/lib/datadog/core/configuration/settings.rb +28 -3
- data/lib/datadog/core/configuration/supported_configurations.rb +332 -302
- data/lib/datadog/core/ddsketch.rb +0 -2
- data/lib/datadog/core/environment/cgroup.rb +52 -25
- data/lib/datadog/core/environment/container.rb +140 -46
- data/lib/datadog/core/environment/ext.rb +7 -0
- data/lib/datadog/core/environment/process.rb +87 -0
- data/lib/datadog/core/feature_flags.rb +61 -0
- data/lib/datadog/core/rate_limiter.rb +9 -1
- data/lib/datadog/core/remote/client/capabilities.rb +7 -0
- data/lib/datadog/core/remote/client.rb +14 -6
- data/lib/datadog/core/remote/component.rb +6 -4
- data/lib/datadog/core/remote/configuration/content.rb +15 -2
- data/lib/datadog/core/remote/configuration/digest.rb +14 -7
- data/lib/datadog/core/remote/configuration/repository.rb +1 -1
- data/lib/datadog/core/remote/configuration/target.rb +13 -6
- data/lib/datadog/core/remote/transport/config.rb +4 -25
- data/lib/datadog/core/remote/transport/http/config.rb +10 -50
- data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
- data/lib/datadog/core/remote/transport/http.rb +15 -24
- data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
- data/lib/datadog/core/remote/worker.rb +25 -37
- data/lib/datadog/core/tag_builder.rb +0 -4
- data/lib/datadog/core/tag_normalizer.rb +84 -0
- data/lib/datadog/core/telemetry/component.rb +59 -16
- data/lib/datadog/core/telemetry/event/app_started.rb +86 -49
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
- data/lib/datadog/core/telemetry/logger.rb +2 -2
- data/lib/datadog/core/telemetry/logging.rb +2 -8
- data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
- data/lib/datadog/core/telemetry/request.rb +17 -3
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +3 -34
- data/lib/datadog/core/telemetry/transport/http.rb +21 -16
- data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -11
- data/lib/datadog/core/telemetry/worker.rb +88 -32
- data/lib/datadog/core/transport/ext.rb +2 -0
- data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
- data/lib/datadog/core/transport/http/api/instance.rb +4 -21
- data/lib/datadog/core/transport/http/builder.rb +9 -5
- data/lib/datadog/core/transport/http/client.rb +80 -0
- data/lib/datadog/core/transport/http.rb +22 -19
- data/lib/datadog/core/transport/response.rb +9 -0
- data/lib/datadog/core/transport/transport.rb +90 -0
- data/lib/datadog/core/utils/array.rb +29 -0
- data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
- data/lib/datadog/core/utils/network.rb +3 -1
- data/lib/datadog/core/utils/only_once_successful.rb +8 -2
- data/lib/datadog/core/utils/time.rb +1 -1
- data/lib/datadog/core/utils.rb +2 -0
- data/lib/datadog/core/workers/async.rb +10 -1
- data/lib/datadog/core/workers/interval_loop.rb +44 -3
- data/lib/datadog/core/workers/polling.rb +2 -0
- data/lib/datadog/core/workers/queue.rb +100 -1
- data/lib/datadog/data_streams/configuration/settings.rb +49 -0
- data/lib/datadog/data_streams/configuration.rb +11 -0
- data/lib/datadog/data_streams/ext.rb +11 -0
- data/lib/datadog/data_streams/extensions.rb +16 -0
- data/lib/datadog/data_streams/pathway_context.rb +169 -0
- data/lib/datadog/data_streams/processor.rb +509 -0
- data/lib/datadog/data_streams/transport/http/stats.rb +52 -0
- data/lib/datadog/data_streams/transport/http.rb +40 -0
- data/lib/datadog/data_streams/transport/stats.rb +46 -0
- data/lib/datadog/data_streams.rb +100 -0
- data/lib/datadog/di/component.rb +0 -16
- data/lib/datadog/di/contrib/active_record.rb +31 -5
- data/lib/datadog/di/el/compiler.rb +8 -4
- data/lib/datadog/di/el/evaluator.rb +1 -1
- data/lib/datadog/di/error.rb +9 -0
- data/lib/datadog/di/instrumenter.rb +93 -34
- data/lib/datadog/di/probe.rb +20 -0
- data/lib/datadog/di/probe_builder.rb +2 -1
- data/lib/datadog/di/probe_manager.rb +47 -33
- data/lib/datadog/di/probe_notification_builder.rb +77 -25
- data/lib/datadog/di/proc_responder.rb +32 -0
- data/lib/datadog/di/remote.rb +89 -84
- data/lib/datadog/di/transport/diagnostics.rb +8 -36
- data/lib/datadog/di/transport/http/diagnostics.rb +1 -33
- data/lib/datadog/di/transport/http/input.rb +1 -33
- data/lib/datadog/di/transport/http.rb +32 -17
- data/lib/datadog/di/transport/input.rb +67 -34
- data/lib/datadog/di.rb +61 -5
- data/lib/datadog/open_feature/component.rb +60 -0
- data/lib/datadog/open_feature/configuration.rb +27 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
- data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
- data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
- data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
- data/lib/datadog/open_feature/exposures/event.rb +60 -0
- data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
- data/lib/datadog/open_feature/exposures/worker.rb +116 -0
- data/lib/datadog/open_feature/ext.rb +14 -0
- data/lib/datadog/open_feature/native_evaluator.rb +38 -0
- data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
- data/lib/datadog/open_feature/provider.rb +141 -0
- data/lib/datadog/open_feature/remote.rb +67 -0
- data/lib/datadog/open_feature/resolution_details.rb +35 -0
- data/lib/datadog/open_feature/transport.rb +70 -0
- data/lib/datadog/open_feature.rb +19 -0
- data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
- data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
- data/lib/datadog/opentelemetry/metrics.rb +117 -0
- data/lib/datadog/opentelemetry/sdk/configurator.rb +25 -1
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +35 -0
- data/lib/datadog/opentelemetry.rb +3 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +41 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +2 -1
- data/lib/datadog/profiling/component.rb +12 -11
- data/lib/datadog/profiling/http_transport.rb +4 -1
- data/lib/datadog/profiling/profiler.rb +4 -0
- data/lib/datadog/profiling/tag_builder.rb +36 -3
- data/lib/datadog/profiling.rb +1 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/tracing/configuration/ext.rb +9 -0
- data/lib/datadog/tracing/configuration/settings.rb +74 -0
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
- data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/extensions.rb +10 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +22 -17
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
- data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +9 -1
- data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +3 -1
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
- data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
- data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
- data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
- data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/tracing/metadata/ext.rb +1 -1
- data/lib/datadog/tracing/remote.rb +1 -9
- data/lib/datadog/tracing/span_event.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +9 -4
- data/lib/datadog/tracing/trace_operation.rb +44 -6
- data/lib/datadog/tracing/tracer.rb +42 -16
- data/lib/datadog/tracing/transport/http/client.rb +12 -26
- data/lib/datadog/tracing/transport/http/traces.rb +2 -50
- data/lib/datadog/tracing/transport/http.rb +15 -9
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
- data/lib/datadog/tracing/transport/traces.rb +9 -71
- data/lib/datadog/tracing/workers/trace_writer.rb +5 -0
- data/lib/datadog/tracing/writer.rb +1 -0
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -0
- metadata +78 -21
- data/lib/datadog/core/remote/transport/http/api.rb +0 -53
- data/lib/datadog/core/remote/transport/http/client.rb +0 -49
- data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
- data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
- data/lib/datadog/core/transport/http/api/spec.rb +0 -36
- data/lib/datadog/di/transport/http/api.rb +0 -42
- data/lib/datadog/di/transport/http/client.rb +0 -47
- data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
- data/lib/datadog/tracing/transport/http/api.rb +0 -44
|
@@ -24,10 +24,21 @@ module Datadog
|
|
|
24
24
|
class InvalidHashTypeError < StandardError; end
|
|
25
25
|
attr_reader :type, :hexdigest
|
|
26
26
|
|
|
27
|
-
DIGEST_CHUNK = 1024
|
|
28
|
-
|
|
29
27
|
class << self
|
|
30
28
|
def hexdigest(type, data)
|
|
29
|
+
unless String === data
|
|
30
|
+
# This class (Digest) passes +data+ to the Ruby standard
|
|
31
|
+
# library Digest routines without validating its type.
|
|
32
|
+
# The stdlib Digest requires a String, and the previous
|
|
33
|
+
# implementation of this class that used StringIO
|
|
34
|
+
# unconditionally read from +data+ without validating the
|
|
35
|
+
# type. Meaning, passing +nil+ as +data+ has never worked.
|
|
36
|
+
# It still doesn't work in the present implementation.
|
|
37
|
+
# Flag the nil data now to get earlier diagnostics when
|
|
38
|
+
# developing tests for example.
|
|
39
|
+
raise ArgumentError, "Invalid type for data: #{data.class}: expected String"
|
|
40
|
+
end
|
|
41
|
+
|
|
31
42
|
d = case type
|
|
32
43
|
when :sha256
|
|
33
44
|
::Digest::SHA256.new
|
|
@@ -37,13 +48,9 @@ module Datadog
|
|
|
37
48
|
raise InvalidHashTypeError, type
|
|
38
49
|
end
|
|
39
50
|
|
|
40
|
-
|
|
41
|
-
d.update(buf)
|
|
42
|
-
end
|
|
51
|
+
d.update(data)
|
|
43
52
|
|
|
44
53
|
d.hexdigest
|
|
45
|
-
ensure
|
|
46
|
-
data.rewind
|
|
47
54
|
end
|
|
48
55
|
end
|
|
49
56
|
|
|
@@ -11,8 +11,15 @@ module Datadog
|
|
|
11
11
|
class TargetMap < Hash
|
|
12
12
|
class << self
|
|
13
13
|
def parse(hash)
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
signed = hash.fetch('signed')
|
|
15
|
+
# Note that the +dig+ call permits +hash['signed']+ to be
|
|
16
|
+
# missing the +custom+ subtree entirely.
|
|
17
|
+
# Previously the subtree was required but +opaque_backend_state+
|
|
18
|
+
# could still be missing (and obtained here as nil).
|
|
19
|
+
opaque_backend_state = signed.dig('custom', 'opaque_backend_state')
|
|
20
|
+
# The version appears to be optional to the rest of this class,
|
|
21
|
+
# and we have tests that do not provide it.
|
|
22
|
+
version = signed['version']
|
|
16
23
|
|
|
17
24
|
map = new
|
|
18
25
|
|
|
@@ -21,7 +28,7 @@ module Datadog
|
|
|
21
28
|
@version = version
|
|
22
29
|
end
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
signed.fetch('targets').each_with_object(map) do |(p, t), m|
|
|
25
32
|
path = Configuration::Path.parse(p)
|
|
26
33
|
target = Configuration::Target.parse(t)
|
|
27
34
|
|
|
@@ -46,9 +53,9 @@ module Datadog
|
|
|
46
53
|
class Target
|
|
47
54
|
class << self
|
|
48
55
|
def parse(hash)
|
|
49
|
-
length = Integer(hash
|
|
50
|
-
digests = Configuration::DigestList.parse(hash
|
|
51
|
-
version = Integer(hash
|
|
56
|
+
length = Integer(hash.fetch('length'))
|
|
57
|
+
digests = Configuration::DigestList.parse(hash.fetch('hashes'))
|
|
58
|
+
version = Integer(hash.dig('custom', 'v'))
|
|
52
59
|
|
|
53
60
|
new(digests: digests, length: length, version: version)
|
|
54
61
|
end
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative '../../../core/transport/request'
|
|
4
4
|
require_relative '../../../core/transport/parcel'
|
|
5
|
+
require_relative '../../../core/transport/transport'
|
|
6
|
+
require_relative 'http/config'
|
|
5
7
|
|
|
6
8
|
module Datadog
|
|
7
9
|
module Core
|
|
@@ -21,37 +23,14 @@ module Datadog
|
|
|
21
23
|
class Request < Datadog::Core::Transport::Request
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
# Config response
|
|
25
|
-
module Response
|
|
26
|
-
attr_reader :roots, :targets, :target_files, :client_configs
|
|
27
|
-
|
|
28
|
-
def empty?
|
|
29
|
-
@empty
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
26
|
# Config transport
|
|
34
|
-
class Transport
|
|
35
|
-
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
|
36
|
-
|
|
37
|
-
def initialize(apis, default_api, logger: Datadog.logger)
|
|
38
|
-
@apis = apis
|
|
39
|
-
@logger = logger
|
|
40
|
-
|
|
41
|
-
@client = HTTP::Client.new(current_api, logger: logger)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
##### there is only one transport! it's negotiation!
|
|
27
|
+
class Transport < Core::Transport::Transport
|
|
45
28
|
def send_config(payload)
|
|
46
29
|
json = JSON.dump(payload)
|
|
47
30
|
parcel = EncodedParcel.new(json)
|
|
48
31
|
request = Request.new(parcel)
|
|
49
32
|
|
|
50
|
-
@client.
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def current_api
|
|
54
|
-
@apis[HTTP::API::V7]
|
|
33
|
+
@client.send_request(:config, request)
|
|
55
34
|
end
|
|
56
35
|
end
|
|
57
36
|
end
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative '
|
|
5
|
+
require_relative '../../../transport/http/api/endpoint'
|
|
6
|
+
require_relative '../../../transport/http/response'
|
|
7
7
|
require_relative '../../../utils/base64'
|
|
8
8
|
require_relative '../../../utils/truncation'
|
|
9
|
-
require_relative '../../../transport/http/response'
|
|
10
|
-
require_relative '../../../transport/http/api/endpoint'
|
|
11
9
|
|
|
12
10
|
module Datadog
|
|
13
11
|
module Core
|
|
@@ -18,8 +16,7 @@ module Datadog
|
|
|
18
16
|
module Config
|
|
19
17
|
# Response from HTTP transport for remote configuration
|
|
20
18
|
class Response
|
|
21
|
-
include
|
|
22
|
-
include Core::Remote::Transport::Config::Response
|
|
19
|
+
include Core::Transport::HTTP::Response
|
|
23
20
|
|
|
24
21
|
def initialize(http_response, options = {}) # standard:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
25
22
|
super(http_response)
|
|
@@ -103,7 +100,7 @@ module Datadog
|
|
|
103
100
|
|
|
104
101
|
{
|
|
105
102
|
path: h[:path].freeze,
|
|
106
|
-
content:
|
|
103
|
+
content: content.freeze,
|
|
107
104
|
}
|
|
108
105
|
end.freeze
|
|
109
106
|
|
|
@@ -114,6 +111,12 @@ module Datadog
|
|
|
114
111
|
end.freeze
|
|
115
112
|
end
|
|
116
113
|
|
|
114
|
+
attr_reader :roots, :targets, :target_files, :client_configs
|
|
115
|
+
|
|
116
|
+
def empty?
|
|
117
|
+
@empty
|
|
118
|
+
end
|
|
119
|
+
|
|
117
120
|
def inspect
|
|
118
121
|
"#{super}, #{
|
|
119
122
|
{
|
|
@@ -174,46 +177,7 @@ module Datadog
|
|
|
174
177
|
end
|
|
175
178
|
end
|
|
176
179
|
|
|
177
|
-
# Extensions for HTTP client
|
|
178
|
-
module Client
|
|
179
|
-
def send_config_payload(request)
|
|
180
|
-
send_request(request) do |api, env|
|
|
181
|
-
api.send_config(env)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
180
|
module API
|
|
187
|
-
# Extensions for HTTP API Spec
|
|
188
|
-
module Spec
|
|
189
|
-
attr_reader :config
|
|
190
|
-
|
|
191
|
-
def config=(endpoint)
|
|
192
|
-
@config = endpoint
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def send_config(env, &block)
|
|
196
|
-
raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('config', self) if config.nil?
|
|
197
|
-
|
|
198
|
-
config.call(env, &block)
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# Extensions for HTTP API Instance
|
|
203
|
-
module Instance
|
|
204
|
-
def send_config(env)
|
|
205
|
-
unless spec.is_a?(Config::API::Spec)
|
|
206
|
-
raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
|
|
207
|
-
'config', self
|
|
208
|
-
)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
spec.send_config(env) do |request_env|
|
|
212
|
-
call(request_env)
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
181
|
# Endpoint for remote configuration
|
|
218
182
|
class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
|
|
219
183
|
HEADER_CONTENT_TYPE = 'Content-Type'
|
|
@@ -240,10 +204,6 @@ module Datadog
|
|
|
240
204
|
end
|
|
241
205
|
end
|
|
242
206
|
end
|
|
243
|
-
|
|
244
|
-
# Add remote configuration behavior to transport components
|
|
245
|
-
###### overrides send_payload! which calls send_<endpoint>! kills any other possible endpoint!
|
|
246
|
-
HTTP::Client.include(Config::Client)
|
|
247
207
|
end
|
|
248
208
|
end
|
|
249
209
|
end
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative 'client'
|
|
5
|
+
require_relative '../../../transport/http/client'
|
|
7
6
|
require_relative '../../../transport/http/response'
|
|
8
7
|
require_relative '../../../transport/http/api/endpoint'
|
|
9
8
|
|
|
@@ -17,7 +16,6 @@ module Datadog
|
|
|
17
16
|
# Response from HTTP transport for agent feature negotiation
|
|
18
17
|
class Response
|
|
19
18
|
include Datadog::Core::Transport::HTTP::Response
|
|
20
|
-
include Core::Remote::Transport::Negotiation::Response
|
|
21
19
|
|
|
22
20
|
def initialize(http_response, options = {})
|
|
23
21
|
super(http_response)
|
|
@@ -29,48 +27,23 @@ module Datadog
|
|
|
29
27
|
@config = options[:config]
|
|
30
28
|
@span_events = options[:span_events]
|
|
31
29
|
end
|
|
32
|
-
end
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
# @!attribute [r] version
|
|
32
|
+
# The version of the agent.
|
|
33
|
+
# @return [String]
|
|
34
|
+
# @!attribute [r] endpoints
|
|
35
|
+
# The HTTP endpoints the agent supports.
|
|
36
|
+
# @return [Array<String>]
|
|
37
|
+
# @!attribute [r] config
|
|
38
|
+
# The agent configuration. These are configured by the user when starting the agent, as well as any defaults.
|
|
39
|
+
# @return [Hash]
|
|
40
|
+
# @!attribute [r] span_events
|
|
41
|
+
# Whether the agent supports the top-level span events field in flushed spans.
|
|
42
|
+
# @return [Boolean,nil]
|
|
43
|
+
attr_reader :version, :endpoints, :config, :span_events
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
module API
|
|
44
|
-
# Extensions for HTTP API Spec
|
|
45
|
-
module Spec
|
|
46
|
-
attr_reader :info
|
|
47
|
-
|
|
48
|
-
def info=(endpoint)
|
|
49
|
-
@info = endpoint
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def send_info(env, &block)
|
|
53
|
-
raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('info', self) if info.nil?
|
|
54
|
-
|
|
55
|
-
info.call(env, &block)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Extensions for HTTP API Instance
|
|
60
|
-
module Instance
|
|
61
|
-
def send_info(env)
|
|
62
|
-
unless spec.is_a?(Negotiation::API::Spec)
|
|
63
|
-
raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
|
|
64
|
-
'info', self
|
|
65
|
-
)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
spec.send_info(env) do |request_env|
|
|
69
|
-
call(request_env)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
47
|
# Endpoint for negotiation
|
|
75
48
|
class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
|
|
76
49
|
def initialize(path)
|
|
@@ -92,9 +65,6 @@ module Datadog
|
|
|
92
65
|
end
|
|
93
66
|
end
|
|
94
67
|
end
|
|
95
|
-
|
|
96
|
-
# Add negotiation behavior to transport components
|
|
97
|
-
HTTP::Client.include(Negotiation::Client)
|
|
98
68
|
end
|
|
99
69
|
end
|
|
100
70
|
end
|
|
@@ -4,16 +4,8 @@ require_relative '../../environment/container'
|
|
|
4
4
|
require_relative '../../environment/ext'
|
|
5
5
|
require_relative '../../transport/ext'
|
|
6
6
|
require_relative '../../transport/http'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
# Since endpoint negotiation happens at the `API::Spec` level there can not be
|
|
11
|
-
# a mix of endpoints at various versions or versionless without describing all
|
|
12
|
-
# the possible combinations as specs. See http/api.
|
|
13
|
-
#
|
|
14
|
-
# Below should be:
|
|
15
|
-
# require_relative '../../transport/http/api'
|
|
16
|
-
require_relative 'http/api'
|
|
7
|
+
require_relative 'config'
|
|
8
|
+
require_relative 'negotiation'
|
|
17
9
|
|
|
18
10
|
# TODO: Decouple transport/http
|
|
19
11
|
#
|
|
@@ -27,26 +19,30 @@ module Datadog
|
|
|
27
19
|
module Transport
|
|
28
20
|
# Namespace for HTTP transport components
|
|
29
21
|
module HTTP
|
|
22
|
+
ROOT = Negotiation::API::Endpoint.new(
|
|
23
|
+
'/info',
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
V7 = Config::API::Endpoint.new(
|
|
27
|
+
'/v0.7/config',
|
|
28
|
+
Core::Encoding::JSONEncoder,
|
|
29
|
+
)
|
|
30
|
+
|
|
30
31
|
module_function
|
|
31
32
|
|
|
32
33
|
# Builds a new Transport::HTTP::Client with default settings
|
|
33
34
|
# Pass a block to override any settings.
|
|
34
35
|
def root(
|
|
35
36
|
agent_settings:,
|
|
36
|
-
logger
|
|
37
|
-
api_version: nil,
|
|
37
|
+
logger:,
|
|
38
38
|
headers: nil
|
|
39
39
|
)
|
|
40
40
|
Core::Transport::HTTP.build(
|
|
41
|
-
api_instance_class: API::Instance,
|
|
42
41
|
agent_settings: agent_settings,
|
|
43
42
|
logger: logger,
|
|
44
|
-
api_version: api_version,
|
|
45
43
|
headers: headers
|
|
46
44
|
) do |transport|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
transport.api API::ROOT, apis[API::ROOT]
|
|
45
|
+
transport.api 'root', ROOT
|
|
50
46
|
|
|
51
47
|
# Call block to apply any customization, if provided
|
|
52
48
|
yield(transport) if block_given?
|
|
@@ -57,20 +53,15 @@ module Datadog
|
|
|
57
53
|
# Pass a block to override any settings.
|
|
58
54
|
def v7(
|
|
59
55
|
agent_settings:,
|
|
60
|
-
logger
|
|
61
|
-
api_version: nil,
|
|
56
|
+
logger:,
|
|
62
57
|
headers: nil
|
|
63
58
|
)
|
|
64
59
|
Core::Transport::HTTP.build(
|
|
65
|
-
api_instance_class: API::Instance,
|
|
66
60
|
agent_settings: agent_settings,
|
|
67
61
|
logger: logger,
|
|
68
|
-
api_version: api_version,
|
|
69
62
|
headers: headers
|
|
70
63
|
) do |transport|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
transport.api API::V7, apis[API::V7]
|
|
64
|
+
transport.api 'v7', V7
|
|
74
65
|
|
|
75
66
|
# Call block to apply any customization, if provided
|
|
76
67
|
yield(transport) if block_given?
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative '../../../core/transport/request'
|
|
4
|
+
require_relative '../../../core/transport/transport'
|
|
5
|
+
require_relative 'http/negotiation'
|
|
4
6
|
|
|
5
7
|
# TODO: Resolve conceptual conundrum
|
|
6
8
|
#
|
|
@@ -30,42 +32,15 @@ module Datadog
|
|
|
30
32
|
class Request < Datadog::Core::Transport::Request
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
# Negotiation response
|
|
34
|
-
module Response
|
|
35
|
-
# @!attribute [r] version
|
|
36
|
-
# The version of the agent.
|
|
37
|
-
# @return [String]
|
|
38
|
-
# @!attribute [r] endpoints
|
|
39
|
-
# The HTTP endpoints the agent supports.
|
|
40
|
-
# @return [Array<String>]
|
|
41
|
-
# @!attribute [r] config
|
|
42
|
-
# The agent configuration. These are configured by the user when starting the agent, as well as any defaults.
|
|
43
|
-
# @return [Hash]
|
|
44
|
-
# @!attribute [r] span_events
|
|
45
|
-
# Whether the agent supports the top-level span events field in flushed spans.
|
|
46
|
-
# @return [Boolean,nil]
|
|
47
|
-
attr_reader :version, :endpoints, :config, :span_events
|
|
48
|
-
end
|
|
49
|
-
|
|
50
35
|
# Negotiation transport
|
|
51
|
-
class Transport
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@logger = logger
|
|
57
|
-
|
|
58
|
-
@client = HTTP::Client.new(current_api, logger: logger)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def send_info
|
|
36
|
+
class Transport < Core::Transport::Transport
|
|
37
|
+
# TODO steep is complaining about this method, I tried to make
|
|
38
|
+
# it work but between module inclusions and steep diagnostics
|
|
39
|
+
# I don't understand what the problem is or what the steep wants.
|
|
40
|
+
def send_info # steep:ignore
|
|
62
41
|
request = Request.new
|
|
63
42
|
|
|
64
|
-
@client.
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def current_api
|
|
68
|
-
@apis[HTTP::API::ROOT]
|
|
43
|
+
@client.send_request(:info, request)
|
|
69
44
|
end
|
|
70
45
|
end
|
|
71
46
|
end
|
|
@@ -23,51 +23,47 @@ module Datadog
|
|
|
23
23
|
attr_reader :logger
|
|
24
24
|
|
|
25
25
|
def start
|
|
26
|
-
logger.debug {
|
|
26
|
+
logger.debug { "remote worker starting (pid: #{Process.pid})" }
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
@mutex.synchronize do
|
|
29
|
+
if @stopped
|
|
30
|
+
logger.debug('remote worker: refusing to restart after previous stop')
|
|
31
|
+
return
|
|
32
|
+
end
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
logger.debug('remote worker: refusing to restart after previous stop')
|
|
32
|
-
return
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
return if @starting || @started
|
|
34
|
+
return if @starting || @started
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
@starting = true
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
thread = Thread.new { poll(@interval) }
|
|
39
|
+
thread.name = self.class.name
|
|
40
|
+
thread.thread_variable_set(:fork_safe, true)
|
|
41
|
+
@thr = thread
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
@started = true
|
|
44
|
+
@starting = false
|
|
45
|
+
end
|
|
46
46
|
|
|
47
47
|
logger.debug { 'remote worker started' }
|
|
48
|
-
ensure
|
|
49
|
-
release_lock
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def stop
|
|
53
|
-
logger.debug {
|
|
51
|
+
logger.debug { "remote worker stopping (pid: #{Process.pid})" }
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
@mutex.synchronize do
|
|
54
|
+
thread = @thr
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
if thread
|
|
57
|
+
thread.kill
|
|
58
|
+
thread.join
|
|
59
|
+
end
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
@started = false
|
|
62
|
+
@thr = nil
|
|
63
|
+
@stopped = true
|
|
62
64
|
end
|
|
63
65
|
|
|
64
|
-
@started = false
|
|
65
|
-
@thr = nil
|
|
66
|
-
@stopped = true
|
|
67
|
-
|
|
68
66
|
logger.debug { 'remote worker stopped' }
|
|
69
|
-
ensure
|
|
70
|
-
release_lock
|
|
71
67
|
end
|
|
72
68
|
|
|
73
69
|
def started?
|
|
@@ -76,14 +72,6 @@ module Datadog
|
|
|
76
72
|
|
|
77
73
|
private
|
|
78
74
|
|
|
79
|
-
def acquire_lock
|
|
80
|
-
@mutex.lock
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def release_lock
|
|
84
|
-
@mutex.unlock
|
|
85
|
-
end
|
|
86
|
-
|
|
87
75
|
def poll(interval)
|
|
88
76
|
loop do
|
|
89
77
|
break unless @mutex.synchronize { @starting || @started }
|
|
@@ -8,10 +8,6 @@ module Datadog
|
|
|
8
8
|
module Core
|
|
9
9
|
# This module builds a hash of tags.
|
|
10
10
|
#
|
|
11
|
-
# When changing or adding the tags, make sure they are kept in sync with
|
|
12
|
-
# https://docs.google.com/spreadsheets/d/1LOGMf4c4Avbtn36uZ2SWvhIGKRPLM1BoWkUP4JYj7hA/
|
|
13
|
-
# (Datadog internal link).
|
|
14
|
-
#
|
|
15
11
|
# @api private
|
|
16
12
|
module TagBuilder
|
|
17
13
|
def self.fixed_environment_tags
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'utils'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Core
|
|
7
|
+
# @api private
|
|
8
|
+
module TagNormalizer
|
|
9
|
+
# Normalization logic used for tag keys and values that the Trace Agent has for traces
|
|
10
|
+
# Useful for ensuring that tag keys and values are normalized consistently
|
|
11
|
+
# An use case for now is Process Tags which need to be sent across various intakes (profiling, tracing, etc.) consistently
|
|
12
|
+
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
INVALID_TAG_CHARACTERS = %r{[^\p{L}0-9_\-:./]}
|
|
16
|
+
LEADING_INVALID_CHARS_NO_DIGITS = %r{\A[^\p{L}:]++}
|
|
17
|
+
LEADING_INVALID_CHARS_WITH_DIGITS = %r{\A[^\p{L}0-9:./]++}
|
|
18
|
+
MAX_BYTE_SIZE = 200 # Represents the general max tag length
|
|
19
|
+
MAX_PROCESS_VALUE_BYTE_SIZE = 100 # Represents the max tag length for process tags
|
|
20
|
+
VALID_ASCII_TAG = %r{\A[a-z:][a-z0-9:./-]*\z}
|
|
21
|
+
|
|
22
|
+
# Based on https://github.com/DataDog/datadog-agent/blob/45799c842bbd216bcda208737f9f11cade6fdd95/pkg/trace/traceutil/normalize.go#L131
|
|
23
|
+
# Specifically for general normalization:
|
|
24
|
+
# - Must be valid UTF-8
|
|
25
|
+
# - Invalid characters are replaced with an underscore
|
|
26
|
+
# - Leading non-letter characters are removed but colons are kept
|
|
27
|
+
# - Trailing non-letter characters are removed
|
|
28
|
+
# - Trailing underscores are removed
|
|
29
|
+
# - Consecutive underscores are merged into a single underscore
|
|
30
|
+
# - Maximum length is 200 characters
|
|
31
|
+
# If it's a tag value, allow it to start with a digit
|
|
32
|
+
# @param original_value [String] The original string
|
|
33
|
+
# @param remove_digit_start_char [Boolean] - whether to remove the leading digit (currently only used for tag values)
|
|
34
|
+
# @return [String] The normalized string
|
|
35
|
+
def self.normalize(original_value, remove_digit_start_char: false)
|
|
36
|
+
# DEV-3.0: Ideally this encode call should be replaced with Datadog::Core::Utils.utf8_encode once it
|
|
37
|
+
# is safe to modify the default behavior.
|
|
38
|
+
value = original_value.to_s.encode('UTF-8', invalid: :replace, undef: :replace)
|
|
39
|
+
value.strip!
|
|
40
|
+
return "" if value.empty?
|
|
41
|
+
|
|
42
|
+
return value if value.bytesize <= MAX_BYTE_SIZE &&
|
|
43
|
+
value.match?(VALID_ASCII_TAG)
|
|
44
|
+
|
|
45
|
+
if value.bytesize > MAX_BYTE_SIZE
|
|
46
|
+
value = value.byteslice(0, MAX_BYTE_SIZE)
|
|
47
|
+
value.scrub!("")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
value.downcase!
|
|
51
|
+
value.gsub!(INVALID_TAG_CHARACTERS, '_')
|
|
52
|
+
|
|
53
|
+
# The Trace Agent allows tag values to start with a number so this logic is here too
|
|
54
|
+
leading_invalid_regex = remove_digit_start_char ? LEADING_INVALID_CHARS_NO_DIGITS : LEADING_INVALID_CHARS_WITH_DIGITS
|
|
55
|
+
value.sub!(leading_invalid_regex, "")
|
|
56
|
+
|
|
57
|
+
value.squeeze!('_') if value.include?('__')
|
|
58
|
+
value.delete_suffix!('_')
|
|
59
|
+
|
|
60
|
+
value
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Process tags values follow an additional piece of normalization:
|
|
64
|
+
# - must not be more than 100 bytes
|
|
65
|
+
# - and must not contain colons
|
|
66
|
+
# @param value [String] The original string
|
|
67
|
+
# @return [String] The normalized string
|
|
68
|
+
def self.normalize_process_value(value)
|
|
69
|
+
value = normalize(value)
|
|
70
|
+
return value if value.empty?
|
|
71
|
+
|
|
72
|
+
value.tr!(':', '_')
|
|
73
|
+
value.squeeze!('_') if value.include?('__')
|
|
74
|
+
|
|
75
|
+
if value.bytesize > MAX_PROCESS_VALUE_BYTE_SIZE
|
|
76
|
+
value = value.byteslice(0, MAX_PROCESS_VALUE_BYTE_SIZE) || value
|
|
77
|
+
value.scrub!("")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
value
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|