datadog 2.31.0 → 2.32.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/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +17 -7
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +11 -4
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +6 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +5 -4
- data/ext/datadog_profiling_native_extension/http_transport.c +10 -5
- data/ext/libdatadog_api/di.c +48 -0
- data/ext/libdatadog_api/extconf.rb +7 -4
- data/ext/libdatadog_extconf_helpers.rb +37 -0
- data/lib/datadog/ai_guard/configuration.rb +105 -2
- data/lib/datadog/ai_guard/evaluation.rb +1 -0
- data/lib/datadog/ai_guard/ext.rb +1 -0
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +1 -1
- data/lib/datadog/appsec/configuration.rb +414 -1
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
- data/lib/datadog/appsec/metrics/telemetry.rb +13 -1
- data/lib/datadog/appsec/security_engine/runner.rb +1 -1
- data/lib/datadog/appsec/trace_keeper.rb +18 -6
- data/lib/datadog/appsec/utils/http/url_encoded.rb +2 -2
- data/lib/datadog/core/configuration/components.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +3 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/core/contrib/rails/utils.rb +1 -1
- data/lib/datadog/core/crashtracking/component.rb +3 -3
- data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
- data/lib/datadog/core/environment/container.rb +2 -2
- data/lib/datadog/core/feature_flags.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +5 -5
- data/lib/datadog/core/remote/client.rb +1 -1
- data/lib/datadog/core/remote/component.rb +2 -2
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/emitter.rb +1 -1
- data/lib/datadog/core/telemetry/event/app_started.rb +2 -2
- data/lib/datadog/core/transport/http.rb +2 -0
- data/lib/datadog/core/utils.rb +1 -1
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core.rb +1 -1
- data/lib/datadog/data_streams/configuration.rb +40 -1
- data/lib/datadog/data_streams/pathway_context.rb +1 -1
- data/lib/datadog/data_streams/processor.rb +1 -1
- data/lib/datadog/data_streams.rb +1 -1
- data/lib/datadog/di/base.rb +8 -5
- data/lib/datadog/di/code_tracker.rb +179 -1
- data/lib/datadog/di/component.rb +1 -1
- data/lib/datadog/di/configuration.rb +235 -2
- data/lib/datadog/di/instrumenter.rb +46 -26
- data/lib/datadog/di/probe_builder.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +2 -2
- data/lib/datadog/di/probe_manager.rb +6 -6
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/probe_notifier_worker.rb +2 -2
- data/lib/datadog/di/remote.rb +6 -6
- data/lib/datadog/di/serializer.rb +1 -1
- data/lib/datadog/di/transport/input.rb +3 -3
- data/lib/datadog/error_tracking/configuration.rb +55 -2
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/open_feature/component.rb +18 -1
- data/lib/datadog/open_feature/evaluation_engine.rb +3 -3
- data/lib/datadog/open_feature/exposures/reporter.rb +1 -1
- data/lib/datadog/open_feature/exposures/worker.rb +1 -1
- data/lib/datadog/open_feature/hooks/flag_eval_hook.rb +49 -0
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
- data/lib/datadog/open_feature/provider.rb +19 -1
- data/lib/datadog/open_feature/remote.rb +1 -1
- data/lib/datadog/open_feature/transport.rb +1 -1
- data/lib/datadog/opentelemetry/metrics.rb +3 -3
- data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +1 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +35 -9
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +31 -2
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +8 -2
- data/lib/datadog/profiling/collectors/info.rb +16 -3
- data/lib/datadog/profiling/component.rb +3 -5
- data/lib/datadog/profiling/exporter.rb +37 -12
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +21 -12
- data/lib/datadog/profiling/http_transport.rb +12 -1
- data/lib/datadog/profiling/load_native_extension.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +13 -1
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +8 -3
- data/lib/datadog/profiling/tasks/help.rb +1 -0
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/symbol_database/configuration.rb +65 -0
- data/lib/datadog/symbol_database/extractor.rb +915 -0
- data/lib/datadog/symbol_database/file_hash.rb +46 -0
- data/lib/datadog/symbol_database/logger.rb +43 -0
- data/lib/datadog/symbol_database/scope.rb +98 -0
- data/lib/datadog/symbol_database/service_version.rb +57 -0
- data/lib/datadog/symbol_database/symbol.rb +66 -0
- data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
- data/lib/datadog/symbol_database/transport/http.rb +45 -0
- data/lib/datadog/symbol_database/transport.rb +54 -0
- data/lib/datadog/symbol_database/uploader.rb +166 -0
- data/lib/datadog/symbol_database.rb +49 -0
- data/lib/datadog/tracing/buffer.rb +3 -3
- data/lib/datadog/tracing/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -3
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/component.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -4
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/extensions.rb +9 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +2 -2
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +2 -2
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +3 -3
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
- data/lib/datadog/tracing/contrib.rb +8 -0
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
- data/lib/datadog/tracing/distributed/baggage.rb +59 -5
- data/lib/datadog/tracing/distributed/datadog.rb +11 -11
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -1
- data/lib/datadog/tracing/distributed/propagation.rb +2 -2
- data/lib/datadog/tracing/distributed/trace_context.rb +74 -32
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/metadata/tagging.rb +2 -2
- data/lib/datadog/tracing/pipeline.rb +1 -1
- data/lib/datadog/tracing/remote.rb +1 -1
- data/lib/datadog/tracing/sampling/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +3 -3
- data/lib/datadog/tracing/trace_operation.rb +4 -4
- data/lib/datadog/tracing/tracer.rb +5 -5
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/workers.rb +2 -1
- data/lib/datadog/version.rb +1 -1
- metadata +18 -9
- data/lib/datadog/ai_guard/configuration/settings.rb +0 -113
- data/lib/datadog/appsec/configuration/settings.rb +0 -423
- data/lib/datadog/data_streams/configuration/settings.rb +0 -49
- data/lib/datadog/di/configuration/settings.rb +0 -243
- data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
|
@@ -30,7 +30,7 @@ module Datadog
|
|
|
30
30
|
Process.setrlimit(:CORE, maximum_size)
|
|
31
31
|
rescue => e
|
|
32
32
|
Kernel.warn(
|
|
33
|
-
"[datadog] Failed to enable core dumps. Cause: #{e.class}: #{e} " \
|
|
33
|
+
"[datadog] Failed to enable core dumps. Cause: #{e.class}: #{e.message} " \
|
|
34
34
|
"Location: #{Array(e.backtrace).first}"
|
|
35
35
|
)
|
|
36
36
|
return
|
|
@@ -6,12 +6,13 @@ require_relative 'exposures/buffer'
|
|
|
6
6
|
require_relative 'exposures/worker'
|
|
7
7
|
require_relative 'exposures/deduplicator'
|
|
8
8
|
require_relative 'exposures/reporter'
|
|
9
|
+
require_relative 'metrics/flag_eval_metrics'
|
|
9
10
|
|
|
10
11
|
module Datadog
|
|
11
12
|
module OpenFeature
|
|
12
13
|
# This class is the entry point for the OpenFeature component
|
|
13
14
|
class Component
|
|
14
|
-
attr_reader :engine
|
|
15
|
+
attr_reader :engine, :flag_eval_hook
|
|
15
16
|
|
|
16
17
|
def self.build(settings, agent_settings, logger:, telemetry:)
|
|
17
18
|
return unless settings.respond_to?(:open_feature) && settings.open_feature.enabled
|
|
@@ -50,11 +51,27 @@ module Datadog
|
|
|
50
51
|
|
|
51
52
|
reporter = Exposures::Reporter.new(@worker, telemetry: telemetry, logger: logger)
|
|
52
53
|
@engine = EvaluationEngine.new(reporter, telemetry: telemetry, logger: logger)
|
|
54
|
+
|
|
55
|
+
@telemetry = telemetry
|
|
56
|
+
@logger = logger
|
|
57
|
+
@flag_eval_hook = create_flag_eval_hook
|
|
53
58
|
end
|
|
54
59
|
|
|
55
60
|
def shutdown!
|
|
56
61
|
@worker.graceful_shutdown
|
|
57
62
|
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def create_flag_eval_hook
|
|
67
|
+
require_relative 'hooks/flag_eval_hook'
|
|
68
|
+
return unless Hooks::FlagEvalHook.available?
|
|
69
|
+
|
|
70
|
+
metrics = Metrics::FlagEvalMetrics.new(telemetry: @telemetry, logger: @logger)
|
|
71
|
+
Hooks::FlagEvalHook.new(metrics)
|
|
72
|
+
rescue LoadError
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
58
75
|
end
|
|
59
76
|
end
|
|
60
77
|
end
|
|
@@ -42,7 +42,7 @@ module Datadog
|
|
|
42
42
|
@telemetry.report(e, description: 'OpenFeature: Failed to fetch flag value')
|
|
43
43
|
|
|
44
44
|
ResolutionDetails.build_error(
|
|
45
|
-
value: default_value, error_code: Ext::GENERAL, error_message: e.message
|
|
45
|
+
value: default_value, error_code: Ext::GENERAL, error_message: "#{e.class}: #{e.message}"
|
|
46
46
|
)
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -60,10 +60,10 @@ module Datadog
|
|
|
60
60
|
rescue => e
|
|
61
61
|
message = 'OpenFeature: Failed to reconfigure, reverting to the previous configuration'
|
|
62
62
|
|
|
63
|
-
@logger.error("#{message}, #{e.class}: #{e}")
|
|
63
|
+
@logger.error("#{message}, #{e.class}: #{e.message}")
|
|
64
64
|
@telemetry.report(e, description: "#{message} (#{e.class})")
|
|
65
65
|
|
|
66
|
-
raise ReconfigurationError, e.message
|
|
66
|
+
raise ReconfigurationError, "#{e.class}: #{e.message}"
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
end
|
|
@@ -29,7 +29,7 @@ module Datadog
|
|
|
29
29
|
event = Event.build(result, flag_key: flag_key, context: context)
|
|
30
30
|
@worker.enqueue(event)
|
|
31
31
|
rescue => e
|
|
32
|
-
@logger.debug { "OpenFeature: Failed to report resolution details: #{e.class}: #{e}" }
|
|
32
|
+
@logger.debug { "OpenFeature: Failed to report resolution details: #{e.class}: #{e.message}" }
|
|
33
33
|
@telemetry.report(e, description: 'OpenFeature: Failed to report resolution details')
|
|
34
34
|
|
|
35
35
|
false
|
|
@@ -105,7 +105,7 @@ module Datadog
|
|
|
105
105
|
|
|
106
106
|
response
|
|
107
107
|
rescue => e
|
|
108
|
-
@logger.debug { "OpenFeature: Failed to flush resolution details events: #{e.class}: #{e}" }
|
|
108
|
+
@logger.debug { "OpenFeature: Failed to flush resolution details events: #{e.class}: #{e.message}" }
|
|
109
109
|
@telemetry.report(e, description: 'OpenFeature: Failed to flush resolution details events')
|
|
110
110
|
|
|
111
111
|
nil
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module OpenFeature
|
|
5
|
+
module Hooks
|
|
6
|
+
# Records flag evaluation metrics via OpenTelemetry hook
|
|
7
|
+
#
|
|
8
|
+
# Compatible with OpenFeature SDK >= 0.5.0 which provides the Hooks::Hook module,
|
|
9
|
+
# but also works with older versions since the SDK uses respond_to?(:finally)
|
|
10
|
+
# to detect hook capabilities.
|
|
11
|
+
class FlagEvalHook
|
|
12
|
+
# Include the Hook module if available (SDK >= 0.5.0) for interface documentation
|
|
13
|
+
# and default implementations of other hook methods (before, after, error)
|
|
14
|
+
include ::OpenFeature::SDK::Hooks::Hook if defined?(::OpenFeature::SDK::Hooks::Hook)
|
|
15
|
+
|
|
16
|
+
# Returns true if the OpenFeature SDK supports hooks (>= 0.5.0)
|
|
17
|
+
def self.available?
|
|
18
|
+
!!defined?(::OpenFeature::SDK::Hooks::Hook)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize(metrics)
|
|
22
|
+
@metrics = metrics
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def finally(hook_context:, evaluation_details:, **_opts)
|
|
26
|
+
metrics = @metrics
|
|
27
|
+
return unless metrics
|
|
28
|
+
|
|
29
|
+
metrics.record(
|
|
30
|
+
hook_context.flag_key,
|
|
31
|
+
variant: evaluation_details.variant,
|
|
32
|
+
reason: evaluation_details.reason,
|
|
33
|
+
error_code: evaluation_details.error_code,
|
|
34
|
+
allocation_key: extract_allocation_key(evaluation_details),
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def extract_allocation_key(evaluation_details)
|
|
41
|
+
metadata = evaluation_details.flag_metadata
|
|
42
|
+
return unless metadata.is_a?(Hash)
|
|
43
|
+
|
|
44
|
+
metadata['__dd_allocation_key']
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module OpenFeature
|
|
5
|
+
module Metrics
|
|
6
|
+
# Records flag evaluation metrics via OpenTelemetry
|
|
7
|
+
class FlagEvalMetrics
|
|
8
|
+
METER_NAME = 'ddtrace.openfeature'
|
|
9
|
+
METRIC_NAME = 'feature_flag.evaluations'
|
|
10
|
+
METRIC_UNIT = '{evaluation}'
|
|
11
|
+
METRIC_DESCRIPTION = 'Number of feature flag evaluations'
|
|
12
|
+
|
|
13
|
+
ATTR_FLAG_KEY = 'feature_flag.key'
|
|
14
|
+
ATTR_VARIANT = 'feature_flag.result.variant'
|
|
15
|
+
ATTR_REASON = 'feature_flag.result.reason'
|
|
16
|
+
ATTR_ALLOCATION_KEY = 'feature_flag.result.allocation_key'
|
|
17
|
+
ATTR_ERROR_TYPE = 'error.type'
|
|
18
|
+
|
|
19
|
+
DEFAULT_ERROR_TYPE = 'general'
|
|
20
|
+
|
|
21
|
+
ERROR_TYPE_MAP = {
|
|
22
|
+
'FLAG_NOT_FOUND' => 'flag_not_found',
|
|
23
|
+
'TYPE_MISMATCH' => 'type_mismatch',
|
|
24
|
+
'PARSE_ERROR' => 'parse_error',
|
|
25
|
+
'PROVIDER_NOT_READY' => 'provider_not_ready',
|
|
26
|
+
'TARGETING_KEY_MISSING' => 'targeting_key_missing',
|
|
27
|
+
'INVALID_CONTEXT' => 'invalid_context',
|
|
28
|
+
'PROVIDER_FATAL' => 'provider_fatal',
|
|
29
|
+
'GENERAL' => DEFAULT_ERROR_TYPE,
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
# Reasons that should not include allocation_key in metrics
|
|
33
|
+
EXCLUDE_ALLOCATION_KEY_REASONS = %w[error default disabled].freeze
|
|
34
|
+
|
|
35
|
+
def initialize(telemetry:, logger:)
|
|
36
|
+
@telemetry = telemetry
|
|
37
|
+
@logger = logger
|
|
38
|
+
@enabled = Datadog.configuration.opentelemetry.metrics.enabled
|
|
39
|
+
@counter = nil
|
|
40
|
+
@mutex = Mutex.new
|
|
41
|
+
|
|
42
|
+
unless @enabled
|
|
43
|
+
@logger.debug { 'OpenFeature: OTel metrics not enabled (DD_METRICS_OTEL_ENABLED=false), flag evaluation metrics disabled' }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def record(flag_key, variant:, reason:, error_code: nil, allocation_key: nil)
|
|
48
|
+
return unless @enabled
|
|
49
|
+
|
|
50
|
+
counter = get_or_create_counter
|
|
51
|
+
return unless counter
|
|
52
|
+
|
|
53
|
+
attributes = build_attributes(
|
|
54
|
+
flag_key,
|
|
55
|
+
variant: variant,
|
|
56
|
+
reason: reason,
|
|
57
|
+
error_code: error_code,
|
|
58
|
+
allocation_key: allocation_key,
|
|
59
|
+
)
|
|
60
|
+
counter.add(1, attributes: attributes)
|
|
61
|
+
rescue => e
|
|
62
|
+
@logger.debug { "OpenFeature: Failed to record evaluation metric: #{e.class}: #{e.message}" }
|
|
63
|
+
@telemetry.report(e, description: 'OpenFeature: Failed to record evaluation metric')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
# Counter is created lazily because OTel SDK may not be initialized
|
|
69
|
+
# when the OpenFeature component is created.
|
|
70
|
+
def get_or_create_counter
|
|
71
|
+
@mutex.synchronize do
|
|
72
|
+
return @counter if @counter
|
|
73
|
+
|
|
74
|
+
meter_provider = get_or_initialize_meter_provider
|
|
75
|
+
return unless meter_provider
|
|
76
|
+
|
|
77
|
+
meter = meter_provider.meter(METER_NAME)
|
|
78
|
+
@counter = meter.create_counter(
|
|
79
|
+
METRIC_NAME,
|
|
80
|
+
unit: METRIC_UNIT,
|
|
81
|
+
description: METRIC_DESCRIPTION
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
rescue => e
|
|
85
|
+
@logger.debug { "OpenFeature: Failed to create metrics counter: #{e.class}: #{e.message}" }
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Fetch an available OTel meter provider, initializing if needed.
|
|
90
|
+
# Returns the meter provider if available, nil otherwise.
|
|
91
|
+
def get_or_initialize_meter_provider
|
|
92
|
+
meter_provider = defined?(::OpenTelemetry) ? ::OpenTelemetry.meter_provider : nil
|
|
93
|
+
return meter_provider if sdk_meter_provider?(meter_provider)
|
|
94
|
+
|
|
95
|
+
@logger.debug { 'OpenFeature: Initializing OTel meter provider directly' }
|
|
96
|
+
require 'opentelemetry-metrics-sdk'
|
|
97
|
+
require 'datadog/opentelemetry/metrics'
|
|
98
|
+
Datadog::OpenTelemetry::Metrics.initialize!(Datadog.send(:components))
|
|
99
|
+
|
|
100
|
+
meter_provider = ::OpenTelemetry.meter_provider
|
|
101
|
+
sdk_meter_provider?(meter_provider) ? meter_provider : nil
|
|
102
|
+
rescue LoadError => e
|
|
103
|
+
@logger.debug { "OpenFeature: Failed to initialize OTel metrics: #{e.class}: #{e.message}" }
|
|
104
|
+
nil
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def sdk_meter_provider?(meter_provider)
|
|
108
|
+
return false if meter_provider.nil?
|
|
109
|
+
return false unless defined?(::OpenTelemetry::SDK::Metrics::MeterProvider)
|
|
110
|
+
|
|
111
|
+
meter_provider.is_a?(::OpenTelemetry::SDK::Metrics::MeterProvider)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def build_attributes(flag_key, variant:, reason:, error_code:, allocation_key:)
|
|
115
|
+
reason_downcase = normalize_reason(reason)
|
|
116
|
+
|
|
117
|
+
attrs = {
|
|
118
|
+
ATTR_FLAG_KEY => flag_key,
|
|
119
|
+
ATTR_VARIANT => variant.to_s,
|
|
120
|
+
ATTR_REASON => reason_downcase,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if allocation_key && !allocation_key.empty? && !exclude_allocation_key?(reason_downcase)
|
|
124
|
+
attrs[ATTR_ALLOCATION_KEY] = allocation_key
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
if error_code
|
|
128
|
+
attrs[ATTR_ERROR_TYPE] = normalize_error_type(error_code)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
attrs
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def normalize_reason(reason)
|
|
135
|
+
reason = reason.to_s
|
|
136
|
+
reason.empty? ? 'unknown' : reason.downcase
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def normalize_error_type(error_code)
|
|
140
|
+
ERROR_TYPE_MAP.fetch(error_code.to_s, DEFAULT_ERROR_TYPE)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def exclude_allocation_key?(reason_downcase)
|
|
144
|
+
EXCLUDE_ALLOCATION_KEY_REASONS.include?(reason_downcase)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
@@ -7,6 +7,8 @@ module Datadog
|
|
|
7
7
|
module OpenFeature
|
|
8
8
|
# OpenFeature feature flagging provider backed by Datadog Remote Configuration.
|
|
9
9
|
#
|
|
10
|
+
# Requires openfeature-sdk >= 0.5.1 for flag evaluation metrics support.
|
|
11
|
+
#
|
|
10
12
|
# Implementation follows the OpenFeature contract of Provider SDK.
|
|
11
13
|
# For details see:
|
|
12
14
|
# - https://github.com/open-feature/ruby-sdk/blob/v0.4.1/README.md#develop-a-provider
|
|
@@ -67,6 +69,11 @@ module Datadog
|
|
|
67
69
|
# no-op
|
|
68
70
|
end
|
|
69
71
|
|
|
72
|
+
def hooks
|
|
73
|
+
hook = Datadog.send(:components).open_feature&.flag_eval_hook
|
|
74
|
+
[hook].compact
|
|
75
|
+
end
|
|
76
|
+
|
|
70
77
|
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
|
|
71
78
|
evaluate(flag_key, default_value: default_value, expected_type: :boolean, evaluation_context: evaluation_context)
|
|
72
79
|
end
|
|
@@ -117,7 +124,7 @@ module Datadog
|
|
|
117
124
|
value: result.value,
|
|
118
125
|
variant: result.variant,
|
|
119
126
|
reason: result.reason,
|
|
120
|
-
flag_metadata: result
|
|
127
|
+
flag_metadata: build_flag_metadata(result),
|
|
121
128
|
)
|
|
122
129
|
rescue => e
|
|
123
130
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
@@ -128,6 +135,17 @@ module Datadog
|
|
|
128
135
|
)
|
|
129
136
|
end
|
|
130
137
|
|
|
138
|
+
def build_flag_metadata(result)
|
|
139
|
+
metadata = result.flag_metadata || {}
|
|
140
|
+
allocation_key = result.allocation_key
|
|
141
|
+
if allocation_key && !allocation_key.empty?
|
|
142
|
+
metadata = metadata.dup
|
|
143
|
+
metadata['__dd_allocation_key'] = allocation_key
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
metadata
|
|
147
|
+
end
|
|
148
|
+
|
|
131
149
|
def component_not_configured_default(value)
|
|
132
150
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
133
151
|
value: value,
|
|
@@ -41,7 +41,7 @@ module Datadog
|
|
|
41
41
|
engine.reconfigure!(read_content(content))
|
|
42
42
|
content.applied
|
|
43
43
|
rescue EvaluationEngine::ReconfigurationError => e
|
|
44
|
-
content.errored("Error applying OpenFeature configuration: #{e.class}: #{e}")
|
|
44
|
+
content.errored("Error applying OpenFeature configuration: #{e.class}: #{e.message}")
|
|
45
45
|
end
|
|
46
46
|
when :delete
|
|
47
47
|
# NOTE: For now, we treat deletion as clearing the configuration
|
|
@@ -55,7 +55,7 @@ module Datadog
|
|
|
55
55
|
@api.call(env)
|
|
56
56
|
end
|
|
57
57
|
rescue => e
|
|
58
|
-
message = "Internal error during request. Cause: #{e.class}: #{e} " \
|
|
58
|
+
message = "Internal error during request. Cause: #{e.class}: #{e.message} " \
|
|
59
59
|
"Location: #{Array(e.backtrace).first}"
|
|
60
60
|
@logger.debug(message)
|
|
61
61
|
|
|
@@ -11,7 +11,7 @@ module Datadog
|
|
|
11
11
|
new(components).configure_metrics_sdk
|
|
12
12
|
true
|
|
13
13
|
rescue => exc
|
|
14
|
-
components.logger.error("Failed to initialize OpenTelemetry metrics: #{exc.class}: #{exc}: #{exc.backtrace.join("\n")}")
|
|
14
|
+
components.logger.error("Failed to initialize OpenTelemetry metrics: #{exc.class}: #{exc.message}: #{exc.backtrace.join("\n")}")
|
|
15
15
|
false
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -67,7 +67,7 @@ module Datadog
|
|
|
67
67
|
|
|
68
68
|
configure_otlp_exporter(provider)
|
|
69
69
|
rescue => e
|
|
70
|
-
@logger.warn("Failed to configure OTLP metrics exporter: #{e.class}: #{e}")
|
|
70
|
+
@logger.warn("Failed to configure OTLP metrics exporter: #{e.class}: #{e.message}")
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def default_metrics_endpoint
|
|
@@ -101,7 +101,7 @@ module Datadog
|
|
|
101
101
|
)
|
|
102
102
|
provider.add_metric_reader(reader)
|
|
103
103
|
rescue LoadError => e
|
|
104
|
-
@logger.warn("Could not load OTLP metrics exporter: #{e.class}: #{e}")
|
|
104
|
+
@logger.warn("Could not load OTLP metrics exporter: #{e.class}: #{e.message}")
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
# Returns metrics config value if explicitly set, otherwise falls back to exporter config or computed default value.
|
|
@@ -37,7 +37,7 @@ module Datadog
|
|
|
37
37
|
begin
|
|
38
38
|
require 'opentelemetry-metrics-sdk'
|
|
39
39
|
rescue LoadError => exc
|
|
40
|
-
components.logger.warn("Failed to load OpenTelemetry metrics gems: #{exc.class}: #{exc}")
|
|
40
|
+
components.logger.warn("Failed to load OpenTelemetry metrics gems: #{exc.class}: #{exc.message}")
|
|
41
41
|
return super
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -19,7 +19,7 @@ module Datadog
|
|
|
19
19
|
telemetry&.inc(TELEMETRY_NAMESPACE, metric_name, 1, tags: TELEMETRY_TAGS)
|
|
20
20
|
result
|
|
21
21
|
rescue => e
|
|
22
|
-
Datadog.logger.error("Failed to export OpenTelemetry Metrics: #{e.class}: #{e}")
|
|
22
|
+
Datadog.logger.error("Failed to export OpenTelemetry Metrics: #{e.class}: #{e.message}")
|
|
23
23
|
telemetry&.inc(TELEMETRY_NAMESPACE, METRIC_EXPORT_FAILURES, 1, tags: TELEMETRY_TAGS)
|
|
24
24
|
raise
|
|
25
25
|
end
|
|
@@ -14,6 +14,9 @@ module Datadog
|
|
|
14
14
|
#
|
|
15
15
|
# This class acts both as a collector (collecting data) as well as a recorder (records/serializes it)
|
|
16
16
|
class CodeProvenance
|
|
17
|
+
# @rbs standard_library_path: ::String
|
|
18
|
+
# @rbs ruby_native_filename: ::String?
|
|
19
|
+
# @rbs return: void
|
|
17
20
|
def initialize(
|
|
18
21
|
standard_library_path: RbConfig::CONFIG.fetch("rubylibdir"),
|
|
19
22
|
ruby_native_filename: Datadog::Profiling::Collectors::Stack._native_ruby_native_filename
|
|
@@ -35,6 +38,9 @@ module Datadog
|
|
|
35
38
|
)
|
|
36
39
|
end
|
|
37
40
|
|
|
41
|
+
# @rbs loaded_files: ::Array[::String]
|
|
42
|
+
# @rbs loaded_specs: ::Array[::Gem::BasicSpecification]
|
|
43
|
+
# @rbs return: self
|
|
38
44
|
def refresh(loaded_files: $LOADED_FEATURES, loaded_specs: Gem.loaded_specs.values)
|
|
39
45
|
record_loaded_specs(loaded_specs)
|
|
40
46
|
record_loaded_files(loaded_files)
|
|
@@ -42,19 +48,20 @@ module Datadog
|
|
|
42
48
|
self
|
|
43
49
|
end
|
|
44
50
|
|
|
51
|
+
#: () -> ::String
|
|
45
52
|
def generate_json
|
|
46
53
|
JSON.generate(v1: seen_libraries.to_a)
|
|
47
54
|
end
|
|
48
55
|
|
|
49
56
|
private
|
|
50
57
|
|
|
51
|
-
attr_reader
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
:executable_paths
|
|
58
|
+
attr_reader :libraries_by_name #: ::Hash[::String, Library]
|
|
59
|
+
attr_reader :libraries_by_path #: ::Hash[::String, Library]
|
|
60
|
+
attr_reader :seen_files #: ::Set[::String]
|
|
61
|
+
attr_reader :seen_libraries #: ::Set[Library]
|
|
62
|
+
attr_reader :executable_paths #: ::Array[::String]
|
|
57
63
|
|
|
64
|
+
#: (Library) -> void
|
|
58
65
|
def record_library(library)
|
|
59
66
|
libraries_by_name[library.name] = library
|
|
60
67
|
libraries_by_path[library.path] = library
|
|
@@ -71,10 +78,12 @@ module Datadog
|
|
|
71
78
|
#
|
|
72
79
|
# Alternatively/in the future we could instead use a trie to match paths, but I doubt for the data sizes we're
|
|
73
80
|
# looking at that a trie is that much faster than using Ruby's built-in native collections.
|
|
81
|
+
#: () -> void
|
|
74
82
|
def sort_libraries_by_longest_path_first
|
|
75
83
|
@libraries_by_path = @libraries_by_path.sort.reverse!.to_h
|
|
76
84
|
end
|
|
77
85
|
|
|
86
|
+
#: (::Array[::Gem::BasicSpecification]) -> void
|
|
78
87
|
def record_loaded_specs(loaded_specs)
|
|
79
88
|
recorded_library = false
|
|
80
89
|
|
|
@@ -103,6 +112,7 @@ module Datadog
|
|
|
103
112
|
sort_libraries_by_longest_path_first if recorded_library
|
|
104
113
|
end
|
|
105
114
|
|
|
115
|
+
#: (::Array[::String]) -> void
|
|
106
116
|
def record_loaded_files(loaded_files)
|
|
107
117
|
loaded_files.each do |file_path|
|
|
108
118
|
next if seen_files.include?(file_path)
|
|
@@ -125,6 +135,7 @@ module Datadog
|
|
|
125
135
|
# bundler complaints here impacting the application. (Bundler tends to go "something is wrong, raise!" which
|
|
126
136
|
# I think makes a lot of sense given how bundler is intended to be used, but for this our kind of "ask a few
|
|
127
137
|
# questions usage" it's not what we want.)
|
|
138
|
+
#: () -> ::String?
|
|
128
139
|
def bundler_bin_path
|
|
129
140
|
return unless defined?(Bundler)
|
|
130
141
|
|
|
@@ -135,7 +146,7 @@ module Datadog
|
|
|
135
146
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
136
147
|
Datadog.logger.debug(
|
|
137
148
|
"CodeProvenance#bundler_bin_path failed. " \
|
|
138
|
-
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
149
|
+
"Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
139
150
|
)
|
|
140
151
|
nil
|
|
141
152
|
end
|
|
@@ -149,8 +160,21 @@ module Datadog
|
|
|
149
160
|
# Thus, this class was setup to match the JSON output. Take this into consideration if you are adding new
|
|
150
161
|
# fields. (Also, we have a spec for this)
|
|
151
162
|
class Library
|
|
152
|
-
|
|
153
|
-
|
|
163
|
+
# @rbs @kind: ::String
|
|
164
|
+
# @rbs @name: ::String
|
|
165
|
+
# @rbs @version: ::String
|
|
166
|
+
# @rbs @paths: ::Array[::String]
|
|
167
|
+
|
|
168
|
+
attr_reader :kind #: ::String
|
|
169
|
+
attr_reader :name #: ::String
|
|
170
|
+
attr_reader :version #: ::String
|
|
171
|
+
|
|
172
|
+
# @rbs kind: ::String
|
|
173
|
+
# @rbs name: ::String
|
|
174
|
+
# @rbs version: ::String | ::Gem::Version
|
|
175
|
+
# @rbs path: ::String
|
|
176
|
+
# @rbs extra_paths: ::Array[::String?]
|
|
177
|
+
# @rbs return: void
|
|
154
178
|
def initialize(kind:, name:, version:, path:, extra_paths:)
|
|
155
179
|
extra_paths = Array(extra_paths).compact.reject(&:empty?).map { |p| p.dup.freeze }
|
|
156
180
|
@kind = kind.freeze
|
|
@@ -160,10 +184,12 @@ module Datadog
|
|
|
160
184
|
freeze
|
|
161
185
|
end
|
|
162
186
|
|
|
187
|
+
#: (?::JSON::State?) -> ::String
|
|
163
188
|
def to_json(arg = nil)
|
|
164
189
|
{kind: @kind, name: @name, version: @version, paths: @paths}.to_json(arg)
|
|
165
190
|
end
|
|
166
191
|
|
|
192
|
+
#: () -> ::String
|
|
167
193
|
def path
|
|
168
194
|
@paths.first
|
|
169
195
|
end
|
|
@@ -9,12 +9,32 @@ module Datadog
|
|
|
9
9
|
#
|
|
10
10
|
# Methods prefixed with _native_ are implemented in `collectors_cpu_and_wall_time_worker.c`
|
|
11
11
|
class CpuAndWallTimeWorker
|
|
12
|
+
# @rbs @worker_thread: untyped
|
|
13
|
+
# @rbs @start_stop_mutex: ::Thread::Mutex
|
|
14
|
+
# @rbs @failure_exception: ::Exception?
|
|
15
|
+
# @rbs @idle_sampling_helper: IdleSamplingHelper
|
|
16
|
+
# @rbs @wait_until_running_mutex: ::Thread::Mutex
|
|
17
|
+
# @rbs @wait_until_running_condition: ::Thread::ConditionVariable
|
|
18
|
+
|
|
12
19
|
private
|
|
13
20
|
|
|
14
|
-
attr_accessor :failure_exception
|
|
21
|
+
attr_accessor :failure_exception #: ::Exception?
|
|
15
22
|
|
|
16
23
|
public
|
|
17
24
|
|
|
25
|
+
# @rbs gc_profiling_enabled: bool
|
|
26
|
+
# @rbs no_signals_workaround_enabled: bool
|
|
27
|
+
# @rbs thread_context_collector: Datadog::Profiling::Collectors::ThreadContext
|
|
28
|
+
# @rbs dynamic_sampling_rate_overhead_target_percentage: Float
|
|
29
|
+
# @rbs cpu_sampling_interval_ms: ::Integer
|
|
30
|
+
# @rbs idle_sampling_helper: Datadog::Profiling::Collectors::IdleSamplingHelper
|
|
31
|
+
# @rbs dynamic_sampling_rate_enabled: bool
|
|
32
|
+
# @rbs allocation_profiling_enabled: bool
|
|
33
|
+
# @rbs allocation_counting_enabled: bool
|
|
34
|
+
# @rbs gvl_profiling_enabled: bool
|
|
35
|
+
# @rbs sighandler_sampling_enabled: bool
|
|
36
|
+
# @rbs skip_idle_samples_for_testing: false
|
|
37
|
+
# @rbs return: void
|
|
18
38
|
def initialize(
|
|
19
39
|
gc_profiling_enabled:,
|
|
20
40
|
no_signals_workaround_enabled:,
|
|
@@ -67,6 +87,8 @@ module Datadog
|
|
|
67
87
|
@wait_until_running_condition = ConditionVariable.new
|
|
68
88
|
end
|
|
69
89
|
|
|
90
|
+
# @rbs on_failure_proc: (^(?log_failure: bool) -> void)?
|
|
91
|
+
# @rbs return: bool?
|
|
70
92
|
def start(on_failure_proc: nil)
|
|
71
93
|
@start_stop_mutex.synchronize do
|
|
72
94
|
return if @worker_thread&.alive?
|
|
@@ -93,7 +115,7 @@ module Datadog
|
|
|
93
115
|
operation_name = self.class._native_failure_exception_during_operation(self).inspect
|
|
94
116
|
Datadog.logger.warn(
|
|
95
117
|
"CpuAndWallTimeWorker thread error. " \
|
|
96
|
-
"Operation: #{operation_name} Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
118
|
+
"Operation: #{operation_name} Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
97
119
|
)
|
|
98
120
|
on_failure_proc&.call
|
|
99
121
|
Datadog::Core::Telemetry::Logger.report(e, description: "CpuAndWallTimeWorker thread error: #{operation_name}")
|
|
@@ -105,6 +127,7 @@ module Datadog
|
|
|
105
127
|
true
|
|
106
128
|
end
|
|
107
129
|
|
|
130
|
+
#: () -> void
|
|
108
131
|
def stop
|
|
109
132
|
@start_stop_mutex.synchronize do
|
|
110
133
|
Datadog.logger.debug("Requesting CpuAndWallTimeWorker thread shut down")
|
|
@@ -121,14 +144,17 @@ module Datadog
|
|
|
121
144
|
end
|
|
122
145
|
end
|
|
123
146
|
|
|
147
|
+
#: () -> true
|
|
124
148
|
def reset_after_fork
|
|
125
149
|
self.class._native_reset_after_fork(self)
|
|
126
150
|
end
|
|
127
151
|
|
|
152
|
+
#: () -> ::Hash[::Symbol, untyped]
|
|
128
153
|
def stats
|
|
129
154
|
self.class._native_stats(self)
|
|
130
155
|
end
|
|
131
156
|
|
|
157
|
+
#: () -> ::Hash[::Symbol, untyped]
|
|
132
158
|
def stats_and_reset_not_thread_safe
|
|
133
159
|
stats = self.stats
|
|
134
160
|
self.class._native_stats_reset_not_thread_safe(self)
|
|
@@ -136,6 +162,8 @@ module Datadog
|
|
|
136
162
|
end
|
|
137
163
|
|
|
138
164
|
# Useful for testing, to e.g. make sure the profiler is running before we start running some code we want to observe
|
|
165
|
+
# @rbs timeout_seconds: ::Integer?
|
|
166
|
+
# @rbs return: true
|
|
139
167
|
def wait_until_running(timeout_seconds: 5)
|
|
140
168
|
@wait_until_running_mutex.synchronize do
|
|
141
169
|
return true if self.class._native_is_running?(self)
|
|
@@ -152,6 +180,7 @@ module Datadog
|
|
|
152
180
|
|
|
153
181
|
private
|
|
154
182
|
|
|
183
|
+
#: () -> void
|
|
155
184
|
def signal_running
|
|
156
185
|
@wait_until_running_mutex.synchronize { @wait_until_running_condition.broadcast }
|
|
157
186
|
end
|
|
@@ -8,17 +8,22 @@ module Datadog
|
|
|
8
8
|
#
|
|
9
9
|
# Methods prefixed with _native_ are implemented in `collectors_idle_sampling_helper.c`
|
|
10
10
|
class IdleSamplingHelper
|
|
11
|
+
# @rbs @worker_thread: untyped
|
|
12
|
+
# @rbs @start_stop_mutex: ::Thread::Mutex
|
|
13
|
+
|
|
11
14
|
private
|
|
12
15
|
|
|
13
|
-
attr_accessor :failure_exception
|
|
16
|
+
attr_accessor :failure_exception #: ::Exception?
|
|
14
17
|
|
|
15
18
|
public
|
|
16
19
|
|
|
20
|
+
#: () -> void
|
|
17
21
|
def initialize
|
|
18
22
|
@worker_thread = nil
|
|
19
23
|
@start_stop_mutex = Mutex.new
|
|
20
24
|
end
|
|
21
25
|
|
|
26
|
+
#: () -> (nil | true)
|
|
22
27
|
def start
|
|
23
28
|
@start_stop_mutex.synchronize do
|
|
24
29
|
return if @worker_thread&.alive?
|
|
@@ -39,7 +44,7 @@ module Datadog
|
|
|
39
44
|
@failure_exception = e
|
|
40
45
|
Datadog.logger.warn(
|
|
41
46
|
"IdleSamplingHelper thread error. " \
|
|
42
|
-
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
47
|
+
"Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
43
48
|
)
|
|
44
49
|
Datadog::Core::Telemetry::Logger.report(e, description: "IdleSamplingHelper thread error")
|
|
45
50
|
end
|
|
@@ -50,6 +55,7 @@ module Datadog
|
|
|
50
55
|
true
|
|
51
56
|
end
|
|
52
57
|
|
|
58
|
+
#: () -> void
|
|
53
59
|
def stop
|
|
54
60
|
@start_stop_mutex.synchronize do
|
|
55
61
|
Datadog.logger.debug("Requesting IdleSamplingHelper thread shut down")
|