datadog 2.33.0 → 2.34.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 +30 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +20 -0
- data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
- data/lib/datadog/appsec/component.rb +4 -1
- data/lib/datadog/appsec/compressed_json.rb +2 -2
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
- data/lib/datadog/core/configuration/components.rb +8 -1
- data/lib/datadog/core/configuration/settings.rb +6 -1
- data/lib/datadog/core/configuration/supported_configurations.rb +10 -0
- data/lib/datadog/core/environment/ext.rb +4 -0
- data/lib/datadog/core/environment/identity.rb +15 -1
- data/lib/datadog/core/environment/process.rb +48 -27
- data/lib/datadog/core/remote/client/capabilities.rb +11 -2
- data/lib/datadog/core/remote/transport/http/config.rb +5 -5
- data/lib/datadog/core/telemetry/request.rb +0 -2
- data/lib/datadog/core/transport/response.rb +1 -1
- data/lib/datadog/core/utils/{base64.rb → base64_codec.rb} +3 -2
- data/lib/datadog/core/utils/hash.rb +0 -23
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +46 -16
- data/lib/datadog/data_streams/pathway_context.rb +3 -3
- data/lib/datadog/di/code_tracker.rb +43 -22
- data/lib/datadog/di/contrib/active_record.rb +6 -2
- data/lib/datadog/di/instrumenter.rb +24 -4
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/remote.rb +4 -4
- data/lib/datadog/di/serializer.rb +5 -5
- data/lib/datadog/di/utils.rb +42 -14
- data/lib/datadog/opentelemetry/configuration/settings.rb +65 -0
- data/lib/datadog/opentelemetry/ext.rb +9 -0
- data/lib/datadog/opentelemetry/logs.rb +98 -0
- data/lib/datadog/opentelemetry/metrics.rb +10 -46
- data/lib/datadog/opentelemetry/sdk/configurator.rb +40 -0
- data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +37 -0
- data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
- data/lib/datadog/opentelemetry.rb +1 -0
- data/lib/datadog/symbol_database/component.rb +409 -0
- data/lib/datadog/symbol_database/configuration.rb +2 -2
- data/lib/datadog/symbol_database/extractor.rb +29 -1
- data/lib/datadog/symbol_database/remote.rb +175 -0
- data/lib/datadog/symbol_database/scope_batcher.rb +8 -0
- data/lib/datadog/symbol_database/service_version.rb +11 -2
- data/lib/datadog/symbol_database/symbol.rb +6 -3
- data/lib/datadog/symbol_database/uploader.rb +62 -8
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +8 -0
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -4
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +0 -4
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -4
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +0 -5
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +0 -5
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -8
- data/lib/datadog/tracing/contrib/excon/middleware.rb +0 -5
- data/lib/datadog/tracing/contrib/ext.rb +2 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +0 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +0 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +0 -5
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +0 -5
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +0 -5
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
- data/lib/datadog/tracing/contrib/redis/tags.rb +0 -5
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +0 -5
- data/lib/datadog/tracing/contrib/sequel/utils.rb +0 -5
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +0 -5
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -13
- data/lib/datadog/tracing/distributed/trace_context.rb +0 -28
- data/lib/datadog/tracing/metadata/ext.rb +3 -0
- data/lib/datadog/tracing/span_operation.rb +13 -0
- data/lib/datadog/tracing/trace_operation.rb +22 -0
- data/lib/datadog/tracing/tracer.rb +6 -0
- data/lib/datadog/version.rb +1 -1
- metadata +12 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa3ddf8f18dda4b503c654911332fb5cdc50356d4fa8223d43a993be204618ac
|
|
4
|
+
data.tar.gz: d917e203823268d36fc01c086969052160a6afdfb2c3cfdc29a081d8ce23a384
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4fda14c3e26b82d5b93e3581acfa939d9ac3be695c2ad26ca720b4873127f05e949dc78f0cb1b8922ed87cd114881e9191fa36463cd86f3dcbf5d969da0da932
|
|
7
|
+
data.tar.gz: ca53286a2a5ad436e460ede12148faed98b9904d0823715954f602cdf292cb03966cde1f96dd2c227581b1ccd814c30fdd0236dfaa1903f59a87ae2873f40dd0
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [2.34.0] - 2026-05-27
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* Dynamic Instrumentation: Enable Symbol Database upload so Ruby services populate Live Debugger UI autocomplete when creating probes ([#5717][])
|
|
10
|
+
* Open Telemetry: Add OpenTelemetry logs support with OTLP export. Enable using `DD_LOGS_OTEL_ENABLED=true`; supports standard `OTEL_EXPORTER_OTLP_*` settings ([#5446][])
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
* Dynamic Instrumentation: Improve request latency under load by throttling symbol database extraction CPU usage during background processing ([#5776][])
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
* Core: Fix Remote configuration `TransportError` messages removing wrapper response object memory addresses ([#5762][])
|
|
19
|
+
* Core: Fix `TypeError` from `Process.spawn` when passing an environment Hash ([#5773][], [#5634][])
|
|
20
|
+
* AppSec: Prevent host application crashes when AppSec fails to initialize ([#5768][])
|
|
21
|
+
* Dynamic Instrumentation: Fix off-by-one in `max_capture_depth` so snapshots respect the configured nesting limit exactly ([#5753][])
|
|
22
|
+
* Dynamic Instrumentation: Improve line probes to match `sourceFile` case-insensitively and support Windows-style backslashes for correct installation ([#5754][])
|
|
23
|
+
|
|
5
24
|
## [2.31.0] - 2026-04-20
|
|
6
25
|
|
|
7
26
|
### Added
|
|
@@ -3567,7 +3586,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
|
3567
3586
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
3568
3587
|
|
|
3569
3588
|
|
|
3570
|
-
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.
|
|
3589
|
+
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.34.0...master
|
|
3590
|
+
[2.34.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.33.0...v2.34.0
|
|
3571
3591
|
[2.31.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.30.0...v2.31.0
|
|
3572
3592
|
[2.30.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.29.0...v2.30.0
|
|
3573
3593
|
[2.29.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.28.0...v2.29.0
|
|
@@ -5278,6 +5298,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
|
5278
5298
|
[#5434]: https://github.com/DataDog/dd-trace-rb/issues/5434
|
|
5279
5299
|
[#5435]: https://github.com/DataDog/dd-trace-rb/issues/5435
|
|
5280
5300
|
[#5436]: https://github.com/DataDog/dd-trace-rb/issues/5436
|
|
5301
|
+
[#5446]: https://github.com/DataDog/dd-trace-rb/issues/5446
|
|
5281
5302
|
[#5448]: https://github.com/DataDog/dd-trace-rb/issues/5448
|
|
5282
5303
|
[#5449]: https://github.com/DataDog/dd-trace-rb/issues/5449
|
|
5283
5304
|
[#5461]: https://github.com/DataDog/dd-trace-rb/issues/5461
|
|
@@ -5295,6 +5316,14 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
|
5295
5316
|
[#5580]: https://github.com/DataDog/dd-trace-rb/issues/5580
|
|
5296
5317
|
[#5587]: https://github.com/DataDog/dd-trace-rb/issues/5587
|
|
5297
5318
|
[#5594]: https://github.com/DataDog/dd-trace-rb/issues/5594
|
|
5319
|
+
[#5634]: https://github.com/DataDog/dd-trace-rb/issues/5634
|
|
5320
|
+
[#5717]: https://github.com/DataDog/dd-trace-rb/issues/5717
|
|
5321
|
+
[#5753]: https://github.com/DataDog/dd-trace-rb/issues/5753
|
|
5322
|
+
[#5754]: https://github.com/DataDog/dd-trace-rb/issues/5754
|
|
5323
|
+
[#5762]: https://github.com/DataDog/dd-trace-rb/issues/5762
|
|
5324
|
+
[#5768]: https://github.com/DataDog/dd-trace-rb/issues/5768
|
|
5325
|
+
[#5773]: https://github.com/DataDog/dd-trace-rb/issues/5773
|
|
5326
|
+
[#5776]: https://github.com/DataDog/dd-trace-rb/issues/5776
|
|
5298
5327
|
[@AdrianLC]: https://github.com/AdrianLC
|
|
5299
5328
|
[@Azure7111]: https://github.com/Azure7111
|
|
5300
5329
|
[@BabyGroot]: https://github.com/BabyGroot
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
#include "setup_signal_handler.h"
|
|
18
18
|
#include "time_helpers.h"
|
|
19
19
|
|
|
20
|
+
#ifdef __APPLE__
|
|
21
|
+
#include "macos_sampler_thread.h"
|
|
22
|
+
#endif
|
|
23
|
+
|
|
20
24
|
// Used to trigger the execution of Collectors::ThreadContext, which implements all of the sampling logic
|
|
21
25
|
// itself; this class only implements the "when to do it" part.
|
|
22
26
|
//
|
|
@@ -535,6 +539,14 @@ static VALUE _native_sampling_loop(DDTRACE_UNUSED VALUE _self, VALUE instance) {
|
|
|
535
539
|
|
|
536
540
|
block_sigprof_signal_handler_from_running_in_current_thread(); // We want to interrupt the thread with the global VM lock, never this one
|
|
537
541
|
|
|
542
|
+
#ifdef __APPLE__
|
|
543
|
+
// Promote the native thread that will run the sampling loop to a realtime scheduling policy so
|
|
544
|
+
// its periodic wake-ups are not subject to the default ~1-2ms timeshare wake latency. The matching
|
|
545
|
+
// demote happens below in this same function, alongside the SIGPROF unblock dance, so both per-thread
|
|
546
|
+
// policy changes are reverted before Ruby reuses this native thread for an unrelated Ruby thread.
|
|
547
|
+
promote_sampler_thread_to_realtime(MILLIS_AS_NS(state->cpu_sampling_interval_ms));
|
|
548
|
+
#endif
|
|
549
|
+
|
|
538
550
|
// Release GVL, get to the actual work!
|
|
539
551
|
int exception_state;
|
|
540
552
|
rb_protect(release_gvl_and_run_sampling_trigger_loop, instance, &exception_state);
|
|
@@ -556,6 +568,14 @@ static VALUE _native_sampling_loop(DDTRACE_UNUSED VALUE _self, VALUE instance) {
|
|
|
556
568
|
// had SIGPROF delivery blocked. :hide_the_pain_harold:
|
|
557
569
|
unblock_sigprof_signal_handler_from_running_in_current_thread();
|
|
558
570
|
|
|
571
|
+
#ifdef __APPLE__
|
|
572
|
+
// Pairs with promote_sampler_thread_to_realtime above. Same reasoning as the SIGPROF unblock:
|
|
573
|
+
// Ruby may reuse this native thread for an unrelated Ruby thread that would otherwise inherit
|
|
574
|
+
// our scheduler policy. Doing it here also covers the exception path, since grab_gvl_and_sample
|
|
575
|
+
// can raise and unwind out of the sampling loop.
|
|
576
|
+
demote_sampler_thread_from_realtime();
|
|
577
|
+
#endif
|
|
578
|
+
|
|
559
579
|
// Why replace and not use remove the signal handler? We do this because when a process receives a SIGPROF without
|
|
560
580
|
// having an explicit signal handler set up, the process will instantly terminate with a confusing
|
|
561
581
|
// "Profiling timer expired" message left behind. (This message doesn't come from us -- it's the default message for
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <mach/mach.h>
|
|
4
|
+
#include <mach/mach_time.h>
|
|
5
|
+
#include <mach/thread_policy.h>
|
|
6
|
+
#include <pthread.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
|
|
9
|
+
#include "time_helpers.h"
|
|
10
|
+
|
|
11
|
+
// On macOS the default scheduler wake latency for a timeshare thread is ~1-2ms,
|
|
12
|
+
// so nanosleep regularly overshoots a 10ms request by ~2ms. Marking the worker
|
|
13
|
+
// thread with THREAD_TIME_CONSTRAINT_POLICY tells the scheduler this thread has
|
|
14
|
+
// a periodic deadline; the kernel then wakes it close to the requested time.
|
|
15
|
+
//
|
|
16
|
+
// This only affects the sampler worker thread. We pair it with a demote call
|
|
17
|
+
// before the thread can be reused by Ruby for unrelated Ruby threads (see the
|
|
18
|
+
// SIGPROF unblock dance in _native_sampling_loop).
|
|
19
|
+
static inline void promote_sampler_thread_to_realtime(uint64_t period_ns) {
|
|
20
|
+
mach_timebase_info_data_t timebase = (mach_timebase_info_data_t) {};
|
|
21
|
+
mach_timebase_info(&timebase);
|
|
22
|
+
|
|
23
|
+
// ns -> mach ticks: each mach tick is (numer/denom) ns, so divide by that.
|
|
24
|
+
#define NS_TO_MACH_TICKS(ns) ((uint32_t) (((uint64_t)(ns) * (uint64_t) timebase.denom) / (uint64_t) timebase.numer))
|
|
25
|
+
|
|
26
|
+
struct thread_time_constraint_policy policy = {
|
|
27
|
+
.period = NS_TO_MACH_TICKS(period_ns),
|
|
28
|
+
.computation = NS_TO_MACH_TICKS(MICROS_AS_NS(200)), // 200us upper bound on the work we do per period
|
|
29
|
+
.constraint = NS_TO_MACH_TICKS(MILLIS_AS_NS(1)), // wake us within 1ms of the deadline
|
|
30
|
+
.preemptible = TRUE,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
#undef NS_TO_MACH_TICKS
|
|
34
|
+
|
|
35
|
+
kern_return_t kr = thread_policy_set(
|
|
36
|
+
pthread_mach_thread_np(pthread_self()),
|
|
37
|
+
THREAD_TIME_CONSTRAINT_POLICY,
|
|
38
|
+
(thread_policy_t) &policy,
|
|
39
|
+
THREAD_TIME_CONSTRAINT_POLICY_COUNT
|
|
40
|
+
);
|
|
41
|
+
if (kr != KERN_SUCCESS) {
|
|
42
|
+
// Non-fatal: we'll fall back to the default scheduler behavior (overshoot ~2ms).
|
|
43
|
+
fprintf(stderr, "[ddtrace] Failed to set real-time policy on profiler sampler thread (kr=%d); sample cadence may be imprecise\n", kr);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static inline void demote_sampler_thread_from_realtime(void) {
|
|
48
|
+
struct thread_standard_policy policy = {.no_data = 0};
|
|
49
|
+
thread_policy_set(
|
|
50
|
+
pthread_mach_thread_np(pthread_self()),
|
|
51
|
+
THREAD_STANDARD_POLICY,
|
|
52
|
+
(thread_policy_t) &policy,
|
|
53
|
+
THREAD_STANDARD_POLICY_COUNT
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -46,7 +46,10 @@ module Datadog
|
|
|
46
46
|
|
|
47
47
|
security_engine = SecurityEngine::Engine.new(appsec_settings: settings.appsec, telemetry: telemetry)
|
|
48
48
|
new(security_engine: security_engine)
|
|
49
|
-
|
|
49
|
+
# NOTE: At this point we should capture all possible exceptions and
|
|
50
|
+
# gracefully fail component initialization, preventing propagation
|
|
51
|
+
# into the host application code.
|
|
52
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
50
53
|
Datadog.logger.warn("AppSec is disabled: #{e.class}: #{e.message}; there may be additional logged errors above")
|
|
51
54
|
|
|
52
55
|
# Not reporting to telemetry here because some of the rescued exceptions
|
|
@@ -4,7 +4,7 @@ require 'json'
|
|
|
4
4
|
require 'zlib'
|
|
5
5
|
require 'stringio'
|
|
6
6
|
|
|
7
|
-
require_relative '../core/utils/
|
|
7
|
+
require_relative '../core/utils/base64_codec'
|
|
8
8
|
|
|
9
9
|
module Datadog
|
|
10
10
|
module AppSec
|
|
@@ -27,7 +27,7 @@ module Datadog
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
private_class_method def self.compress_and_encode(payload)
|
|
30
|
-
Core::Utils::
|
|
30
|
+
Core::Utils::Base64Codec.strict_encode64(
|
|
31
31
|
Zlib.gzip(payload, level: Zlib::BEST_SPEED, strategy: Zlib::DEFAULT_STRATEGY)
|
|
32
32
|
)
|
|
33
33
|
rescue Zlib::Error, TypeError => e
|
|
@@ -4,7 +4,7 @@ require 'uri'
|
|
|
4
4
|
|
|
5
5
|
require_relative '../../utils/http/media_type'
|
|
6
6
|
require_relative '../../utils/http/body'
|
|
7
|
-
require_relative '../../../core/utils/
|
|
7
|
+
require_relative '../../../core/utils/base64_codec'
|
|
8
8
|
require_relative '../../../core/header_collection'
|
|
9
9
|
require_relative '../../../tracing/client_ip'
|
|
10
10
|
|
|
@@ -42,7 +42,7 @@ module Datadog
|
|
|
42
42
|
|
|
43
43
|
headers = parse_headers(payload)
|
|
44
44
|
data = {
|
|
45
|
-
'server.response.status' => payload['
|
|
45
|
+
'server.response.status' => payload['status_code']&.to_s,
|
|
46
46
|
'server.response.headers' => headers,
|
|
47
47
|
'server.response.headers.no_cookies' => headers.dup.tap { |h| h.delete('set-cookie') }
|
|
48
48
|
}
|
|
@@ -94,7 +94,7 @@ module Datadog
|
|
|
94
94
|
body = payload['body']
|
|
95
95
|
return unless body
|
|
96
96
|
|
|
97
|
-
body = Core::Utils::
|
|
97
|
+
body = Core::Utils::Base64Codec.strict_decode64(body) if payload['base64_encoded']
|
|
98
98
|
|
|
99
99
|
content_type = headers['content-type']
|
|
100
100
|
return unless content_type
|
|
@@ -19,6 +19,8 @@ require_relative '../../profiling/component'
|
|
|
19
19
|
require_relative '../../appsec/component'
|
|
20
20
|
require_relative '../../ai_guard/component'
|
|
21
21
|
require_relative '../../di/component'
|
|
22
|
+
require_relative '../../symbol_database'
|
|
23
|
+
require_relative '../../symbol_database/component'
|
|
22
24
|
require_relative '../../open_feature/component'
|
|
23
25
|
require_relative '../../error_tracking/component'
|
|
24
26
|
require_relative '../crashtracking/component'
|
|
@@ -120,6 +122,7 @@ module Datadog
|
|
|
120
122
|
:ai_guard,
|
|
121
123
|
:agent_info,
|
|
122
124
|
:data_streams,
|
|
125
|
+
:symbol_database,
|
|
123
126
|
:open_feature
|
|
124
127
|
|
|
125
128
|
def initialize(settings)
|
|
@@ -133,7 +136,7 @@ module Datadog
|
|
|
133
136
|
self.class::PATCH_ONLY_ONCE.run do
|
|
134
137
|
Utils::AtForkMonkeyPatch.apply!
|
|
135
138
|
Utils::SpawnMonkeyPatch.apply!(
|
|
136
|
-
|
|
139
|
+
env_provider: Core::Environment::Identity.method(:runtime_propagation_envs),
|
|
137
140
|
)
|
|
138
141
|
|
|
139
142
|
# Register callback that calls Components.after_fork
|
|
@@ -171,6 +174,7 @@ module Datadog
|
|
|
171
174
|
@ai_guard = Datadog::AIGuard::Component.build(settings, logger: @logger, telemetry: telemetry)
|
|
172
175
|
@open_feature = OpenFeature::Component.build(settings, agent_settings, logger: @logger, telemetry: telemetry)
|
|
173
176
|
@dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
|
|
177
|
+
@symbol_database = Datadog::SymbolDatabase::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
|
|
174
178
|
@error_tracking = Datadog::ErrorTracking::Component.build(settings, @tracer, @logger)
|
|
175
179
|
@data_streams = self.class.build_data_streams(settings, agent_settings, @logger, @agent_info)
|
|
176
180
|
@environment_logger_extra[:dynamic_instrumentation_enabled] = !!@dynamic_instrumentation
|
|
@@ -241,6 +245,9 @@ module Datadog
|
|
|
241
245
|
# Shutdown DI after remote, since remote config triggers DI operations.
|
|
242
246
|
dynamic_instrumentation&.shutdown!
|
|
243
247
|
|
|
248
|
+
# Shutdown Symbol Database
|
|
249
|
+
symbol_database&.shutdown!
|
|
250
|
+
|
|
244
251
|
# Shutdown OpenFeature component
|
|
245
252
|
open_feature&.shutdown!
|
|
246
253
|
|
|
@@ -6,6 +6,7 @@ require_relative 'base'
|
|
|
6
6
|
require_relative 'ext'
|
|
7
7
|
require_relative '../environment/execution'
|
|
8
8
|
require_relative '../environment/ext'
|
|
9
|
+
require_relative '../environment/process'
|
|
9
10
|
require_relative '../runtime/ext'
|
|
10
11
|
require_relative '../telemetry/ext'
|
|
11
12
|
require_relative '../remote/ext'
|
|
@@ -692,12 +693,16 @@ module Datadog
|
|
|
692
693
|
o.env Core::Environment::Ext::ENV_SERVICE
|
|
693
694
|
o.default Core::Environment::Ext::FALLBACK_SERVICE_NAME
|
|
694
695
|
|
|
696
|
+
o.after_set do |service_name|
|
|
697
|
+
Core::Environment::Process.set_service(service_name, user_configured: !using_default?(:service))
|
|
698
|
+
end
|
|
699
|
+
|
|
695
700
|
# There's a few cases where we don't want to use the fallback service name, so this helper allows us to get a
|
|
696
701
|
# nil instead so that one can do
|
|
697
702
|
# nice_service_name = Datadog.configuration.service_without_fallback || nice_service_name_default
|
|
698
703
|
o.helper(:service_without_fallback) do
|
|
699
704
|
service_name = service
|
|
700
|
-
service_name unless
|
|
705
|
+
service_name unless using_default?(:service)
|
|
701
706
|
end
|
|
702
707
|
end
|
|
703
708
|
|
|
@@ -70,6 +70,7 @@ module Datadog
|
|
|
70
70
|
"DD_INSTRUMENTATION_TELEMETRY_ENABLED",
|
|
71
71
|
"DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD",
|
|
72
72
|
"DD_LOGS_INJECTION",
|
|
73
|
+
"DD_LOGS_OTEL_ENABLED",
|
|
73
74
|
"DD_METRICS_OTEL_ENABLED",
|
|
74
75
|
"DD_METRIC_AGENT_PORT",
|
|
75
76
|
"DD_PROFILING_ALLOCATION_ENABLED",
|
|
@@ -350,8 +351,16 @@ module Datadog
|
|
|
350
351
|
"DD_TRACE_WATERDROP_ENABLED",
|
|
351
352
|
"DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH",
|
|
352
353
|
"DD_VERSION",
|
|
354
|
+
"OTEL_BLRP_EXPORT_TIMEOUT",
|
|
355
|
+
"OTEL_BLRP_MAX_EXPORT_BATCH_SIZE",
|
|
356
|
+
"OTEL_BLRP_MAX_QUEUE_SIZE",
|
|
357
|
+
"OTEL_BLRP_SCHEDULE_DELAY",
|
|
353
358
|
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
|
354
359
|
"OTEL_EXPORTER_OTLP_HEADERS",
|
|
360
|
+
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
|
|
361
|
+
"OTEL_EXPORTER_OTLP_LOGS_HEADERS",
|
|
362
|
+
"OTEL_EXPORTER_OTLP_LOGS_PROTOCOL",
|
|
363
|
+
"OTEL_EXPORTER_OTLP_LOGS_TIMEOUT",
|
|
355
364
|
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
|
|
356
365
|
"OTEL_EXPORTER_OTLP_METRICS_HEADERS",
|
|
357
366
|
"OTEL_EXPORTER_OTLP_METRICS_PROTOCOL",
|
|
@@ -359,6 +368,7 @@ module Datadog
|
|
|
359
368
|
"OTEL_EXPORTER_OTLP_METRICS_TIMEOUT",
|
|
360
369
|
"OTEL_EXPORTER_OTLP_PROTOCOL",
|
|
361
370
|
"OTEL_EXPORTER_OTLP_TIMEOUT",
|
|
371
|
+
"OTEL_LOGS_EXPORTER",
|
|
362
372
|
"OTEL_LOG_LEVEL",
|
|
363
373
|
"OTEL_METRICS_EXPORTER",
|
|
364
374
|
"OTEL_METRIC_EXPORT_INTERVAL",
|
|
@@ -45,6 +45,10 @@ module Datadog
|
|
|
45
45
|
TAG_RAILS_APPLICATION = "rails.application"
|
|
46
46
|
TAG_PROCESS_TAGS = "_dd.tags.process"
|
|
47
47
|
TAG_SERVICE = 'service'
|
|
48
|
+
# Service name was automatically populated by this library
|
|
49
|
+
TAG_SVC_AUTO = 'svc.auto'
|
|
50
|
+
# Service name was explicitly configured by the library user
|
|
51
|
+
TAG_SVC_USER = 'svc.user'
|
|
48
52
|
TAG_VERSION = 'version'
|
|
49
53
|
|
|
50
54
|
GEM_DATADOG_VERSION = Datadog::VERSION::STRING
|
|
@@ -76,7 +76,21 @@ module Datadog
|
|
|
76
76
|
Core::Environment::Ext::GEM_DATADOG_VERSION
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
# Returns tracer version
|
|
79
|
+
# Returns the tracer version in SemVer-2 form (https://semver.org/spec/v2.0.0.html).
|
|
80
|
+
#
|
|
81
|
+
# Converts the RubyGems-style version returned by {.gem_datadog_version}
|
|
82
|
+
# (dot-separated prerelease/build segments, e.g. "2.34.0.dev") into the
|
|
83
|
+
# SemVer-2 form expected by cross-language Datadog consumers (hyphen-separated
|
|
84
|
+
# prerelease, "+" build metadata, e.g. "2.34.0-dev").
|
|
85
|
+
#
|
|
86
|
+
# Called by reporters that emit a tracer version on the wire and must match
|
|
87
|
+
# the format used by other-language tracers:
|
|
88
|
+
# - process discovery memfd (`Core::ProcessDiscovery.get_metadata` → `tracer_version`)
|
|
89
|
+
# - telemetry payloads (`Core::Telemetry::Request#application`)
|
|
90
|
+
# - remote configuration client identification (`Core::Remote::Client#tracer_version`)
|
|
91
|
+
#
|
|
92
|
+
# Use {.gem_datadog_version} (not this method) when a RubyGems-style string is
|
|
93
|
+
# required (e.g. gem-internal contexts, gemspec interop).
|
|
80
94
|
def gem_datadog_version_semver2
|
|
81
95
|
major, minor, patch, rest = gem_datadog_version.split('.', 4)
|
|
82
96
|
|
|
@@ -10,18 +10,17 @@ module Datadog
|
|
|
10
10
|
#
|
|
11
11
|
# @api private
|
|
12
12
|
module Process
|
|
13
|
-
#
|
|
14
|
-
#
|
|
13
|
+
# Returns a comma-separated string of normalized key:value pairs.
|
|
14
|
+
# Includes svc.user or svc.auto based on whether the service was explicitly configured.
|
|
15
|
+
# @return [String]
|
|
15
16
|
def self.serialized
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@serialized = tags.join(',').freeze
|
|
17
|
+
tags.join(',').freeze
|
|
19
18
|
end
|
|
20
19
|
|
|
21
|
-
#
|
|
22
|
-
#
|
|
20
|
+
# Returns an array of normalized key:value pair strings.
|
|
21
|
+
# Includes svc.user or svc.auto based on whether the service was explicitly configured.
|
|
22
|
+
# @return [Array<String>]
|
|
23
23
|
def self.tags
|
|
24
|
-
return @tags if defined?(@tags)
|
|
25
24
|
tags = []
|
|
26
25
|
|
|
27
26
|
workdir = TagNormalizer.normalize_process_value(entrypoint_workdir.to_s)
|
|
@@ -35,17 +34,44 @@ module Datadog
|
|
|
35
34
|
|
|
36
35
|
tags << "#{Environment::Ext::TAG_ENTRYPOINT_TYPE}:#{TagNormalizer.normalize(entrypoint_type, remove_digit_start_char: false)}"
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
tags << "#{Environment::Ext::TAG_RAILS_APPLICATION}:#{
|
|
37
|
+
rails_name = TagNormalizer.normalize_process_value(@rails_application_name.to_s)
|
|
38
|
+
tags << "#{Environment::Ext::TAG_RAILS_APPLICATION}:#{rails_name}" unless rails_name.empty?
|
|
39
|
+
|
|
40
|
+
if defined?(@service_user_configured)
|
|
41
|
+
if @service_user_configured
|
|
42
|
+
tags << "#{Environment::Ext::TAG_SVC_USER}:true"
|
|
43
|
+
else
|
|
44
|
+
svc = TagNormalizer.normalize_process_value(@service_name.to_s)
|
|
45
|
+
tags << "#{Environment::Ext::TAG_SVC_AUTO}:#{svc}" unless svc.empty?
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
tags.freeze
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Called via after_set on option :service in settings.rb whenever the service value changes.
|
|
53
|
+
# @param name [String] the service name
|
|
54
|
+
# @param user_configured [Boolean] whether the service was explicitly set by the user
|
|
55
|
+
# @return [void]
|
|
56
|
+
def self.set_service(name, user_configured:)
|
|
57
|
+
@service_name = name
|
|
58
|
+
@service_user_configured = user_configured
|
|
59
|
+
end
|
|
40
60
|
|
|
41
|
-
|
|
61
|
+
# Sets the rails application name from other places in code
|
|
62
|
+
# @param name [String] the rails application name
|
|
63
|
+
# @return [void]
|
|
64
|
+
def self.rails_application_name=(name)
|
|
65
|
+
@rails_application_name = name
|
|
42
66
|
end
|
|
43
67
|
|
|
44
68
|
# Returns the last segment of the working directory of the process
|
|
45
69
|
# Example: /app/myapp -> myapp
|
|
46
70
|
# @return [String] the last segment of the working directory
|
|
47
71
|
def self.entrypoint_workdir
|
|
48
|
-
|
|
72
|
+
return @entrypoint_workdir if defined?(@entrypoint_workdir)
|
|
73
|
+
|
|
74
|
+
@entrypoint_workdir = File.basename(Dir.pwd)
|
|
49
75
|
end
|
|
50
76
|
|
|
51
77
|
# Returns the entrypoint type of the process
|
|
@@ -55,10 +81,10 @@ module Datadog
|
|
|
55
81
|
Environment::Ext::PROCESS_TYPE
|
|
56
82
|
end
|
|
57
83
|
|
|
58
|
-
# Returns the
|
|
84
|
+
# Returns the basename of the script being run
|
|
59
85
|
# Example 1: /bin/mybin -> mybin
|
|
60
|
-
# Example 2: ruby /test/myapp.rb -> myapp
|
|
61
|
-
# @return [String] the
|
|
86
|
+
# Example 2: ruby /test/myapp.rb -> myapp.rb
|
|
87
|
+
# @return [String] the basename of the script
|
|
62
88
|
#
|
|
63
89
|
# @note Determining true entrypoint name is rather complicated. This method
|
|
64
90
|
# is the initial implementation but it does not produce optimal output in all cases.
|
|
@@ -66,12 +92,14 @@ module Datadog
|
|
|
66
92
|
# as their entrypoint name.
|
|
67
93
|
# We might improve the behavior in the future if there is customer demand for it.
|
|
68
94
|
def self.entrypoint_name
|
|
69
|
-
|
|
95
|
+
return @entrypoint_name if defined?(@entrypoint_name)
|
|
96
|
+
|
|
97
|
+
@entrypoint_name = File.basename($0)
|
|
70
98
|
end
|
|
71
99
|
|
|
72
|
-
# Returns the last segment of the
|
|
100
|
+
# Returns the last segment of the directory containing the script
|
|
73
101
|
# Example 1: /bin/mybin -> bin
|
|
74
|
-
# Example 2: ruby /test/myapp.
|
|
102
|
+
# Example 2: ruby /test/myapp.rb -> test
|
|
75
103
|
# @return [String] the last segment of the base directory of the script
|
|
76
104
|
#
|
|
77
105
|
# @note As with entrypoint name, determining true entrypoint directory is complicated.
|
|
@@ -80,16 +108,9 @@ module Datadog
|
|
|
80
108
|
# the entrypoint basedir is `bin` which is not very helpful.
|
|
81
109
|
# We might improve this in the future if there is customer demand.
|
|
82
110
|
def self.entrypoint_basedir
|
|
83
|
-
|
|
84
|
-
end
|
|
111
|
+
return @entrypoint_basedir if defined?(@entrypoint_basedir)
|
|
85
112
|
|
|
86
|
-
|
|
87
|
-
# @param name [String] the rails application name
|
|
88
|
-
# @return [void]
|
|
89
|
-
def self.rails_application_name=(name)
|
|
90
|
-
@rails_application_name = name
|
|
91
|
-
remove_instance_variable(:@tags) if instance_variable_defined?(:@tags)
|
|
92
|
-
remove_instance_variable(:@serialized) if instance_variable_defined?(:@serialized)
|
|
113
|
+
@entrypoint_basedir = File.basename(File.expand_path(File.dirname($0)))
|
|
93
114
|
end
|
|
94
115
|
|
|
95
116
|
private_class_method :entrypoint_workdir, :entrypoint_type, :entrypoint_name, :entrypoint_basedir
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../../utils/
|
|
3
|
+
require_relative '../../utils/base64_codec'
|
|
4
4
|
require_relative '../../../appsec/remote'
|
|
5
5
|
require_relative '../../../tracing/remote'
|
|
6
|
+
require_relative '../../../di/remote'
|
|
7
|
+
require_relative '../../../symbol_database/remote'
|
|
6
8
|
require_relative '../../../open_feature/remote'
|
|
7
9
|
|
|
8
10
|
module Datadog
|
|
@@ -37,6 +39,13 @@ module Datadog
|
|
|
37
39
|
register_capabilities(Datadog::DI::Remote.capabilities)
|
|
38
40
|
register_products(Datadog::DI::Remote.products)
|
|
39
41
|
register_receivers(Datadog::DI::Remote.receivers(@telemetry))
|
|
42
|
+
|
|
43
|
+
# Symbol Database
|
|
44
|
+
if settings.respond_to?(:symbol_database) && settings.symbol_database.enabled
|
|
45
|
+
register_capabilities(Datadog::SymbolDatabase::Remote.capabilities)
|
|
46
|
+
register_products(Datadog::SymbolDatabase::Remote.products)
|
|
47
|
+
register_receivers(Datadog::SymbolDatabase::Remote.receivers(@telemetry))
|
|
48
|
+
end
|
|
40
49
|
end
|
|
41
50
|
|
|
42
51
|
if settings.respond_to?(:open_feature) && settings.open_feature.enabled
|
|
@@ -68,7 +77,7 @@ module Datadog
|
|
|
68
77
|
cap_to_hexs = capabilities.reduce(:|).to_s(16).tap { |s| s.size.odd? && s.prepend('0') }.scan(/\h\h/)
|
|
69
78
|
binary = cap_to_hexs.each_with_object([]) { |hex, acc| acc << hex }.map { |e| e.to_i(16) }.pack('C*')
|
|
70
79
|
|
|
71
|
-
Datadog::Core::Utils::
|
|
80
|
+
Datadog::Core::Utils::Base64Codec.strict_encode64(binary)
|
|
72
81
|
end
|
|
73
82
|
end
|
|
74
83
|
end
|
|
@@ -4,7 +4,7 @@ require 'json'
|
|
|
4
4
|
|
|
5
5
|
require_relative '../../../transport/http/api/endpoint'
|
|
6
6
|
require_relative '../../../transport/http/response'
|
|
7
|
-
require_relative '../../../utils/
|
|
7
|
+
require_relative '../../../utils/base64_codec'
|
|
8
8
|
require_relative '../../../utils/truncation'
|
|
9
9
|
|
|
10
10
|
module Datadog
|
|
@@ -35,7 +35,7 @@ module Datadog
|
|
|
35
35
|
|
|
36
36
|
# TODO: these fallbacks should be improved
|
|
37
37
|
roots = payload[:roots] || []
|
|
38
|
-
targets = payload[:targets] || Datadog::Core::Utils::
|
|
38
|
+
targets = payload[:targets] || Datadog::Core::Utils::Base64Codec.strict_encode64('{}')
|
|
39
39
|
target_files = payload[:target_files] || []
|
|
40
40
|
client_configs = payload[:client_configs] || []
|
|
41
41
|
|
|
@@ -45,7 +45,7 @@ module Datadog
|
|
|
45
45
|
raise TypeError.new(String, root) unless root.is_a?(String)
|
|
46
46
|
|
|
47
47
|
decoded = begin
|
|
48
|
-
Datadog::Core::Utils::
|
|
48
|
+
Datadog::Core::Utils::Base64Codec.strict_decode64(root) # TODO: unprocessed, don't symbolize_names
|
|
49
49
|
rescue ArgumentError
|
|
50
50
|
raise DecodeError.new(:roots, root)
|
|
51
51
|
end
|
|
@@ -65,7 +65,7 @@ module Datadog
|
|
|
65
65
|
|
|
66
66
|
@targets = begin
|
|
67
67
|
decoded = begin
|
|
68
|
-
Datadog::Core::Utils::
|
|
68
|
+
Datadog::Core::Utils::Base64Codec.strict_decode64(targets)
|
|
69
69
|
rescue ArgumentError
|
|
70
70
|
raise DecodeError.new(:targets, targets)
|
|
71
71
|
end
|
|
@@ -93,7 +93,7 @@ module Datadog
|
|
|
93
93
|
raise TypeError.new(String, raw) unless raw.is_a?(String)
|
|
94
94
|
|
|
95
95
|
content = begin
|
|
96
|
-
Datadog::Core::Utils::
|
|
96
|
+
Datadog::Core::Utils::Base64Codec.strict_decode64(raw)
|
|
97
97
|
rescue ArgumentError
|
|
98
98
|
raise DecodeError.new(:target_files, raw)
|
|
99
99
|
end
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
module Datadog
|
|
4
4
|
module Core
|
|
5
5
|
module Utils
|
|
6
|
-
#
|
|
7
|
-
|
|
6
|
+
# Base64 encoding/decoding without using the `base64` gem,
|
|
7
|
+
# which is no longer a default gem since Ruby 3.4.
|
|
8
|
+
module Base64Codec
|
|
8
9
|
def self.encode64(bin)
|
|
9
10
|
[bin].pack('m')
|
|
10
11
|
end
|
|
@@ -3,30 +3,7 @@
|
|
|
3
3
|
module Datadog
|
|
4
4
|
module Core
|
|
5
5
|
module Utils
|
|
6
|
-
# Refinements for {Hash}.
|
|
7
6
|
module Hash
|
|
8
|
-
# This refinement ensures modern rubies are allowed to use newer,
|
|
9
|
-
# simpler, and more performant APIs.
|
|
10
|
-
module Refinement
|
|
11
|
-
# Introduced in Ruby 2.4
|
|
12
|
-
unless ::Hash.method_defined?(:compact)
|
|
13
|
-
refine ::Hash do
|
|
14
|
-
def compact
|
|
15
|
-
reject { |_k, v| v.nil? }
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Introduced in Ruby 2.4
|
|
21
|
-
unless ::Hash.method_defined?(:compact!)
|
|
22
|
-
refine ::Hash do
|
|
23
|
-
def compact!
|
|
24
|
-
reject! { |_k, v| v.nil? }
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
7
|
# A minimal {Hash} wrapper that provides case-insensitive access
|
|
31
8
|
# to hash keys, without the overhead of copying the original hash.
|
|
32
9
|
#
|