datadog 2.30.0 → 2.31.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 +44 -1
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +18 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +2 -0
- data/ext/libdatadog_api/crashtracker.c +5 -8
- data/ext/libdatadog_api/datadog_ruby_common.c +18 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/di.c +79 -0
- data/ext/libdatadog_api/extconf.rb +2 -0
- data/ext/libdatadog_api/init.c +5 -2
- data/ext/libdatadog_extconf_helpers.rb +9 -1
- data/lib/datadog/ai_guard/component.rb +2 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +41 -3
- data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
- data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +3 -1
- data/lib/datadog/ai_guard/evaluation/request.rb +14 -9
- data/lib/datadog/ai_guard/evaluation/result.rb +3 -1
- data/lib/datadog/ai_guard/evaluation.rb +36 -7
- data/lib/datadog/ai_guard.rb +26 -8
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +11 -7
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +6 -7
- data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
- data/lib/datadog/appsec/instrumentation/gateway.rb +0 -13
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +2 -0
- data/lib/datadog/appsec/utils/http/media_type.rb +1 -2
- data/lib/datadog/appsec/utils/http/url_encoded.rb +2 -2
- data/lib/datadog/appsec.rb +5 -9
- data/lib/datadog/core/configuration/base.rb +17 -5
- data/lib/datadog/core/configuration/components.rb +21 -8
- data/lib/datadog/core/configuration/config_helper.rb +9 -0
- data/lib/datadog/core/configuration/option.rb +30 -5
- data/lib/datadog/core/configuration/option_definition.rb +38 -12
- data/lib/datadog/core/configuration/options.rb +40 -6
- data/lib/datadog/core/configuration/settings.rb +15 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +1 -0
- data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
- data/lib/datadog/core/contrib/rails/utils.rb +7 -3
- data/lib/datadog/core/crashtracking/component.rb +3 -3
- data/lib/datadog/core/environment/container.rb +2 -2
- data/lib/datadog/core/environment/ext.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +25 -3
- data/lib/datadog/core/environment/process.rb +12 -0
- data/lib/datadog/core/metrics/client.rb +5 -5
- data/lib/datadog/core/remote/component.rb +38 -21
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/component.rb +3 -0
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +2 -3
- data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +151 -169
- data/lib/datadog/core/telemetry/event.rb +1 -7
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -0
- data/lib/datadog/core/telemetry/worker.rb +20 -0
- data/lib/datadog/core/utils/only_once.rb +1 -1
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +36 -0
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core.rb +0 -1
- data/lib/datadog/data_streams/pathway_context.rb +1 -1
- data/lib/datadog/di/boot.rb +2 -4
- data/lib/datadog/di/component.rb +4 -0
- data/lib/datadog/di/instrumenter.rb +10 -4
- data/lib/datadog/di/probe_notification_builder.rb +109 -1
- data/lib/datadog/di/serializer.rb +1 -1
- data/lib/datadog/di.rb +81 -0
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/open_feature/evaluation_engine.rb +1 -1
- 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/remote.rb +1 -1
- data/lib/datadog/open_feature/transport.rb +1 -1
- data/lib/datadog/opentelemetry/configuration/settings.rb +2 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +2 -3
- 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/component.rb +11 -1
- data/lib/datadog/profiling/load_native_extension.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +0 -4
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +2 -2
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/profiling.rb +1 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/tracing/buffer.rb +3 -3
- data/lib/datadog/tracing/component.rb +11 -0
- data/lib/datadog/tracing/configuration/settings.rb +2 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +20 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +3 -1
- 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/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/configurable.rb +18 -3
- 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/faraday/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/patcher.rb +0 -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/tags.rb +1 -1
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +4 -0
- data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
- data/lib/datadog/tracing/distributed/datadog.rb +4 -2
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/remote.rb +1 -1
- data/lib/datadog/tracing/sampling/ext.rb +2 -0
- data/lib/datadog/tracing/sampling/priority_sampler.rb +13 -0
- data/lib/datadog/tracing/sampling/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/rule_sampler.rb +54 -25
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +1 -1
- data/lib/datadog/tracing/span_operation.rb +1 -1
- data/lib/datadog/tracing/trace_operation.rb +50 -6
- data/lib/datadog/tracing/tracer.rb +25 -0
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +1 -1
- data/lib/datadog/version.rb +1 -1
- metadata +13 -7
|
@@ -16,17 +16,47 @@ module Datadog
|
|
|
16
16
|
# Class behavior for a configuration object with options
|
|
17
17
|
# @public_api
|
|
18
18
|
module ClassMethods
|
|
19
|
+
def settings_path
|
|
20
|
+
defined?(@settings_path) ? @settings_path : nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Registry of nested settings classes keyed by the option name declared
|
|
24
|
+
# via `Base.settings`. This lets us propagate a new settings path down the
|
|
25
|
+
# tree without storing parent references on the nested class or on the
|
|
26
|
+
# option definition itself.
|
|
27
|
+
def settings_children
|
|
28
|
+
@settings_children ||= if superclass <= Options
|
|
29
|
+
superclass.settings_children.dup
|
|
30
|
+
else
|
|
31
|
+
{}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def settings_path=(path)
|
|
36
|
+
@settings_path = path
|
|
37
|
+
|
|
38
|
+
# Keep nested settings paths in sync when a parent settings path is
|
|
39
|
+
# assigned later, which is how contrib integrations inject
|
|
40
|
+
# "tracing.<integration>" into their configuration classes.
|
|
41
|
+
settings_children.each do |name, settings_class|
|
|
42
|
+
nested_settings_path = path ? "#{path}.#{name}" : name.to_s
|
|
43
|
+
settings_class.settings_path = nested_settings_path
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
19
47
|
def options
|
|
20
48
|
# Allows for class inheritance of option definitions
|
|
21
|
-
@options ||=
|
|
49
|
+
@options ||= if superclass <= Options
|
|
50
|
+
superclass.options.dup
|
|
51
|
+
else
|
|
52
|
+
{}
|
|
53
|
+
end
|
|
22
54
|
end
|
|
23
55
|
|
|
24
56
|
protected
|
|
25
57
|
|
|
26
|
-
def option(name,
|
|
27
|
-
|
|
28
|
-
option_name = settings_name ? "#{settings_name}.#{name}" : name
|
|
29
|
-
builder = OptionDefinition::Builder.new(option_name, meta, &block)
|
|
58
|
+
def option(name, attributes = {}, &block)
|
|
59
|
+
builder = OptionDefinition::Builder.new(name, attributes, &block)
|
|
30
60
|
options[name] = builder.to_definition.tap do
|
|
31
61
|
# Resolve and define helper functions
|
|
32
62
|
helpers = default_helpers(name)
|
|
@@ -75,7 +105,11 @@ module Datadog
|
|
|
75
105
|
end
|
|
76
106
|
|
|
77
107
|
def set_option(name, value, precedence: Configuration::Option::Precedence::PROGRAMMATIC)
|
|
78
|
-
resolve_option(name)
|
|
108
|
+
option = resolve_option(name)
|
|
109
|
+
# Populate lower-precedence values so telemetry and `unset` can
|
|
110
|
+
# still observe the fallback chain after a first programmatic set.
|
|
111
|
+
option.get
|
|
112
|
+
option.set(value, precedence: precedence)
|
|
79
113
|
end
|
|
80
114
|
|
|
81
115
|
def unset_option(name, precedence: Configuration::Option::Precedence::PROGRAMMATIC)
|
|
@@ -221,6 +221,8 @@ module Datadog
|
|
|
221
221
|
#
|
|
222
222
|
# @return Logger::Severity
|
|
223
223
|
option :instance do |o|
|
|
224
|
+
# Telemetry for this option is manually modified and added in the AppStarted event.
|
|
225
|
+
o.skip_telemetry true
|
|
224
226
|
o.after_set { |value| set_option(:level, value.level) unless value.nil? }
|
|
225
227
|
end
|
|
226
228
|
|
|
@@ -912,6 +914,19 @@ module Datadog
|
|
|
912
914
|
o.default 60.0
|
|
913
915
|
end
|
|
914
916
|
|
|
917
|
+
# The interval in seconds when extended heartbeat must be sent.
|
|
918
|
+
#
|
|
919
|
+
# This method is used internally, for testing purposes only.
|
|
920
|
+
#
|
|
921
|
+
# @default `DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL` environment variable, otherwise `86400`.
|
|
922
|
+
# @return [Integer]
|
|
923
|
+
# @!visibility private
|
|
924
|
+
option :extended_heartbeat_interval_seconds do |o|
|
|
925
|
+
o.type :int
|
|
926
|
+
o.env Core::Telemetry::Ext::ENV_EXTENDED_HEARTBEAT_INTERVAL
|
|
927
|
+
o.default 86400
|
|
928
|
+
end
|
|
929
|
+
|
|
915
930
|
# The interval in seconds when telemetry metrics are aggregated.
|
|
916
931
|
# Should be a denominator of `heartbeat_interval_seconds`.
|
|
917
932
|
#
|
|
@@ -107,6 +107,7 @@ module Datadog
|
|
|
107
107
|
"DD_TAGS",
|
|
108
108
|
"DD_TELEMETRY_AGENTLESS_URL",
|
|
109
109
|
"DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED",
|
|
110
|
+
"DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL",
|
|
110
111
|
"DD_TELEMETRY_HEARTBEAT_INTERVAL",
|
|
111
112
|
"DD_TELEMETRY_LOG_COLLECTION_ENABLED",
|
|
112
113
|
"DD_TELEMETRY_METRICS_AGGREGATION_INTERVAL",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'utils'
|
|
4
|
+
require_relative '../../environment/process'
|
|
5
|
+
require_relative '../../process_discovery'
|
|
6
|
+
|
|
7
|
+
module Datadog
|
|
8
|
+
module Core
|
|
9
|
+
module Contrib
|
|
10
|
+
module Rails
|
|
11
|
+
# Railtie for core Rails setup that benefits all Datadog products.
|
|
12
|
+
class Railtie < ::Rails::Railtie
|
|
13
|
+
def self.after_initialize
|
|
14
|
+
if Datadog.configuration.experimental_propagate_process_tags_enabled
|
|
15
|
+
Datadog::Core::Environment::Process.rails_application_name =
|
|
16
|
+
Datadog::Core::Contrib::Rails::Utils.app_name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Process Discovery should always publish after_initialize since it has access to more information
|
|
20
|
+
Datadog::Core::ProcessDiscovery.publish(Datadog.configuration)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Registered after the method definition so the method exists if on_load fires immediately
|
|
24
|
+
# (which happens when the Railtie is loaded into an already-initialized Rails app).
|
|
25
|
+
::ActiveSupport.on_load(:after_initialize) do
|
|
26
|
+
Datadog::Core::Contrib::Rails::Railtie.after_initialize
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -7,11 +7,15 @@ module Datadog
|
|
|
7
7
|
# common utilities for Rails
|
|
8
8
|
module Utils
|
|
9
9
|
def self.app_name
|
|
10
|
-
if ::Rails::VERSION::MAJOR >= 6
|
|
11
|
-
::Rails.application.class.module_parent_name
|
|
10
|
+
application_name = if ::Rails::VERSION::MAJOR >= 6
|
|
11
|
+
::Rails.application.class.module_parent_name
|
|
12
12
|
else
|
|
13
|
-
::Rails.application.class.parent_name
|
|
13
|
+
::Rails.application.class.parent_name
|
|
14
14
|
end
|
|
15
|
+
application_name&.underscore
|
|
16
|
+
rescue => e
|
|
17
|
+
Datadog.logger.debug("Failed to extract Rails application name: #{e.class}: #{e}")
|
|
18
|
+
nil
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
def self.railtie_supported?
|
|
@@ -55,7 +55,7 @@ module Datadog
|
|
|
55
55
|
# Unhandled exception report triggering means that the application is already in a bad state
|
|
56
56
|
# We don't want to swallow non-StandardError exceptions here; we would rather just let the
|
|
57
57
|
# application crash
|
|
58
|
-
Datadog.logger.debug
|
|
58
|
+
Datadog.logger.debug { "Crashtracker failed to report unhandled exception: #{e.class}: #{e}" }
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -130,7 +130,7 @@ module Datadog
|
|
|
130
130
|
self.class._native_stop
|
|
131
131
|
logger.debug('Crash tracking stopped successfully')
|
|
132
132
|
rescue => e
|
|
133
|
-
logger.error("Failed to stop crash tracking: #{e.
|
|
133
|
+
logger.error("Failed to stop crash tracking: #{e.class}: #{e}")
|
|
134
134
|
end
|
|
135
135
|
|
|
136
136
|
private
|
|
@@ -149,7 +149,7 @@ module Datadog
|
|
|
149
149
|
)
|
|
150
150
|
logger.debug("Crash tracking action: #{action} successful")
|
|
151
151
|
rescue => e
|
|
152
|
-
logger.error("Failed to #{action} crash tracking: #{e.
|
|
152
|
+
logger.error("Failed to #{action} crash tracking: #{e.class}: #{e}")
|
|
153
153
|
end
|
|
154
154
|
end
|
|
155
155
|
end
|
|
@@ -108,7 +108,7 @@ module Datadog
|
|
|
108
108
|
end
|
|
109
109
|
rescue => e
|
|
110
110
|
Datadog.logger.debug(
|
|
111
|
-
"Error while checking cgroup namespace. Cause: #{e.class
|
|
111
|
+
"Error while checking cgroup namespace. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
112
112
|
)
|
|
113
113
|
false
|
|
114
114
|
end
|
|
@@ -172,7 +172,7 @@ module Datadog
|
|
|
172
172
|
@entry = Entry.new # Empty entry if no valid cgroup entry is found
|
|
173
173
|
rescue => e
|
|
174
174
|
Datadog.logger.debug(
|
|
175
|
-
"Error while reading container entry. Cause: #{e.class
|
|
175
|
+
"Error while reading container entry. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
176
176
|
)
|
|
177
177
|
@entry = Entry.new unless defined?(@entry)
|
|
178
178
|
@entry
|
|
@@ -41,6 +41,7 @@ module Datadog
|
|
|
41
41
|
TAG_ENTRYPOINT_NAME = "entrypoint.name"
|
|
42
42
|
TAG_ENTRYPOINT_WORKDIR = "entrypoint.workdir"
|
|
43
43
|
TAG_ENTRYPOINT_TYPE = "entrypoint.type"
|
|
44
|
+
TAG_RAILS_APPLICATION = "rails.application"
|
|
44
45
|
TAG_PROCESS_TAGS = "_dd.tags.process"
|
|
45
46
|
TAG_SERVICE = 'service'
|
|
46
47
|
TAG_VERSION = 'version'
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'securerandom'
|
|
4
4
|
|
|
5
|
+
require_relative '../configuration/config_helper'
|
|
5
6
|
require_relative 'ext'
|
|
6
7
|
require_relative '../utils/forking'
|
|
7
8
|
|
|
@@ -13,18 +14,39 @@ module Datadog
|
|
|
13
14
|
module Identity
|
|
14
15
|
extend Core::Utils::Forking
|
|
15
16
|
|
|
17
|
+
ENV_ROOT_SESSION_ID = '_DD_ROOT_RB_SESSION_ID'
|
|
18
|
+
ENV_PARENT_SESSION_ID = '_DD_PARENT_RB_SESSION_ID'
|
|
19
|
+
|
|
16
20
|
module_function
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
@root_runtime_id = DATADOG_ENV[ENV_ROOT_SESSION_ID]&.freeze
|
|
23
|
+
@parent_runtime_id = DATADOG_ENV[ENV_PARENT_SESSION_ID]&.freeze
|
|
24
|
+
|
|
19
25
|
def id
|
|
20
26
|
@id ||= ::SecureRandom.uuid.freeze
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
after_fork! do
|
|
29
|
+
# Order matters: capture @id before overwriting
|
|
30
|
+
@parent_runtime_id = @id
|
|
31
|
+
@root_runtime_id ||= @id
|
|
32
|
+
@id = ::SecureRandom.uuid.freeze
|
|
33
|
+
end
|
|
24
34
|
|
|
25
35
|
@id
|
|
26
36
|
end
|
|
27
37
|
|
|
38
|
+
def root_runtime_id
|
|
39
|
+
@root_runtime_id
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def parent_runtime_id
|
|
43
|
+
@parent_runtime_id
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def runtime_propagation_envs
|
|
47
|
+
{ENV_ROOT_SESSION_ID => root_runtime_id || id, ENV_PARENT_SESSION_ID => id}.freeze
|
|
48
|
+
end
|
|
49
|
+
|
|
28
50
|
def pid
|
|
29
51
|
::Process.pid
|
|
30
52
|
end
|
|
@@ -35,6 +35,9 @@ module Datadog
|
|
|
35
35
|
|
|
36
36
|
tags << "#{Environment::Ext::TAG_ENTRYPOINT_TYPE}:#{TagNormalizer.normalize(entrypoint_type, remove_digit_start_char: false)}"
|
|
37
37
|
|
|
38
|
+
rails_application_name = TagNormalizer.normalize_process_value(@rails_application_name.to_s)
|
|
39
|
+
tags << "#{Environment::Ext::TAG_RAILS_APPLICATION}:#{rails_application_name}" unless rails_application_name.empty?
|
|
40
|
+
|
|
38
41
|
@tags = tags.freeze
|
|
39
42
|
end
|
|
40
43
|
|
|
@@ -80,6 +83,15 @@ module Datadog
|
|
|
80
83
|
File.basename(File.expand_path(File.dirname($0)))
|
|
81
84
|
end
|
|
82
85
|
|
|
86
|
+
# Sets the rails application name from other places in code
|
|
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)
|
|
93
|
+
end
|
|
94
|
+
|
|
83
95
|
private_class_method :entrypoint_workdir, :entrypoint_type, :entrypoint_name, :entrypoint_basedir
|
|
84
96
|
end
|
|
85
97
|
end
|
|
@@ -101,7 +101,7 @@ module Datadog
|
|
|
101
101
|
statsd.count(stat, value, metric_options(options))
|
|
102
102
|
rescue => e
|
|
103
103
|
logger.error(
|
|
104
|
-
"Failed to send count stat. Cause: #{e.class
|
|
104
|
+
"Failed to send count stat. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
105
105
|
)
|
|
106
106
|
telemetry.report(e, description: 'Failed to send count stat')
|
|
107
107
|
end
|
|
@@ -115,7 +115,7 @@ module Datadog
|
|
|
115
115
|
statsd.distribution(stat, value, metric_options(options))
|
|
116
116
|
rescue => e
|
|
117
117
|
logger.error(
|
|
118
|
-
"Failed to send distribution stat. Cause: #{e.class
|
|
118
|
+
"Failed to send distribution stat. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
119
119
|
)
|
|
120
120
|
telemetry.report(e, description: 'Failed to send distribution stat')
|
|
121
121
|
end
|
|
@@ -128,7 +128,7 @@ module Datadog
|
|
|
128
128
|
statsd.increment(stat, metric_options(options))
|
|
129
129
|
rescue => e
|
|
130
130
|
logger.error(
|
|
131
|
-
"Failed to send increment stat. Cause: #{e.class
|
|
131
|
+
"Failed to send increment stat. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
132
132
|
)
|
|
133
133
|
telemetry.report(e, description: 'Failed to send increment stat')
|
|
134
134
|
end
|
|
@@ -142,7 +142,7 @@ module Datadog
|
|
|
142
142
|
statsd.gauge(stat, value, metric_options(options))
|
|
143
143
|
rescue => e
|
|
144
144
|
logger.error(
|
|
145
|
-
"Failed to send gauge stat. Cause: #{e.class
|
|
145
|
+
"Failed to send gauge stat. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
146
146
|
)
|
|
147
147
|
telemetry.report(e, description: 'Failed to send gauge stat')
|
|
148
148
|
end
|
|
@@ -162,7 +162,7 @@ module Datadog
|
|
|
162
162
|
rescue => e
|
|
163
163
|
# TODO: Likely to be redundant, since `distribution` handles its own errors.
|
|
164
164
|
logger.error(
|
|
165
|
-
"Failed to send time stat. Cause: #{e.class
|
|
165
|
+
"Failed to send time stat. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
166
166
|
)
|
|
167
167
|
telemetry.report(e, description: 'Failed to send time stat')
|
|
168
168
|
end
|
|
@@ -45,7 +45,7 @@ module Datadog
|
|
|
45
45
|
rescue Client::SyncError => e
|
|
46
46
|
# Transient errors due to network or agent. Logged the error but not via telemetry
|
|
47
47
|
logger.error do
|
|
48
|
-
"remote worker client sync error: #{e.
|
|
48
|
+
"remote worker client sync error: #{e.class}: #{e} location: #{Array(e.backtrace).first}. skipping sync"
|
|
49
49
|
end
|
|
50
50
|
rescue => e
|
|
51
51
|
# In case of unexpected errors, reset the negotiation object
|
|
@@ -55,7 +55,7 @@ module Datadog
|
|
|
55
55
|
|
|
56
56
|
# Transient errors due to network or agent. Logged the error but not via telemetry
|
|
57
57
|
logger.error do
|
|
58
|
-
"remote worker error: #{e.class
|
|
58
|
+
"remote worker error: #{e.class}: #{e} location: #{Array(e.backtrace).first}. " \
|
|
59
59
|
'resetting client state'
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -105,6 +105,7 @@ module Datadog
|
|
|
105
105
|
class Barrier
|
|
106
106
|
def initialize(timeout = nil)
|
|
107
107
|
@once = false
|
|
108
|
+
@waited = false
|
|
108
109
|
@timeout = timeout
|
|
109
110
|
|
|
110
111
|
@mutex = Mutex.new
|
|
@@ -112,37 +113,53 @@ module Datadog
|
|
|
112
113
|
end
|
|
113
114
|
|
|
114
115
|
# Wait for first lift to happen, otherwise don't wait
|
|
116
|
+
#
|
|
117
|
+
# Returns:
|
|
118
|
+
# - :lift if the barrier was lifted (worker completed a cycle)
|
|
119
|
+
# - :timeout if the wait timed out before the barrier was lifted
|
|
120
|
+
# - :pass if wait_once was already called previously
|
|
121
|
+
#
|
|
122
|
+
# Uses a separate @waited flag to distinguish "already waited" (:pass)
|
|
123
|
+
# from "worker lifted before we could wait" (:lift). Without this,
|
|
124
|
+
# a race between Worker#start and wait_once can cause the first call
|
|
125
|
+
# to return :pass if the worker completes before wait_once runs.
|
|
115
126
|
def wait_once(timeout = nil)
|
|
116
|
-
# TTAS (Test and Test-And-Set) optimisation
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@mutex.lock
|
|
127
|
+
# TTAS (Test and Test-And-Set) optimisation for subsequent calls.
|
|
128
|
+
# @waited is only set inside the mutex and only transitions false -> true,
|
|
129
|
+
# so an unsynchronized read is safe: a stale `false` just falls through
|
|
130
|
+
# to the synchronized path which re-checks.
|
|
131
|
+
return :pass if @waited
|
|
122
132
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
timeout ||= @timeout
|
|
133
|
+
@mutex.synchronize do
|
|
134
|
+
return :pass if @waited
|
|
126
135
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if RUBY_VERSION >= '3.2'
|
|
132
|
-
lifted = @condition.wait(@mutex, timeout)
|
|
136
|
+
if @once
|
|
137
|
+
# Worker lifted the barrier before we could wait.
|
|
138
|
+
# This is still the first call, so return :lift not :pass.
|
|
139
|
+
lifted = true
|
|
133
140
|
else
|
|
134
|
-
@
|
|
135
|
-
|
|
141
|
+
timeout ||= @timeout
|
|
142
|
+
|
|
143
|
+
# - starting with Ruby 3.2, ConditionVariable#wait returns nil on
|
|
144
|
+
# timeout and an integer otherwise
|
|
145
|
+
# - before Ruby 3.2, ConditionVariable returns itself
|
|
146
|
+
# so we have to rely on @once having been set
|
|
147
|
+
if RUBY_VERSION >= '3.2'
|
|
148
|
+
lifted = @condition.wait(@mutex, timeout)
|
|
149
|
+
else
|
|
150
|
+
@condition.wait(@mutex, timeout)
|
|
151
|
+
lifted = @once
|
|
152
|
+
end
|
|
136
153
|
end
|
|
137
154
|
|
|
155
|
+
@waited = true
|
|
156
|
+
|
|
138
157
|
if lifted
|
|
139
158
|
:lift
|
|
140
159
|
else
|
|
141
160
|
@once = true
|
|
142
161
|
:timeout
|
|
143
162
|
end
|
|
144
|
-
ensure
|
|
145
|
-
@mutex.unlock
|
|
146
163
|
end
|
|
147
164
|
end
|
|
148
165
|
|
|
@@ -100,7 +100,7 @@ module Datadog
|
|
|
100
100
|
def try_flush
|
|
101
101
|
yield
|
|
102
102
|
rescue => e
|
|
103
|
-
Datadog.logger.warn("Error while sending runtime metric. Cause: #{e.class
|
|
103
|
+
Datadog.logger.warn("Error while sending runtime metric. Cause: #{e.class}: #{e}")
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
def default_metric_options
|
|
@@ -99,6 +99,7 @@ module Datadog
|
|
|
99
99
|
@worker = Telemetry::Worker.new(
|
|
100
100
|
enabled: @enabled,
|
|
101
101
|
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
|
|
102
|
+
extended_heartbeat_interval_seconds: settings.telemetry.extended_heartbeat_interval_seconds,
|
|
102
103
|
metrics_aggregation_interval_seconds: settings.telemetry.metrics_aggregation_interval_seconds,
|
|
103
104
|
emitter: Emitter.new(
|
|
104
105
|
@transport,
|
|
@@ -108,6 +109,8 @@ module Datadog
|
|
|
108
109
|
metrics_manager: @metrics_manager,
|
|
109
110
|
dependency_collection: settings.telemetry.dependency_collection,
|
|
110
111
|
logger: logger,
|
|
112
|
+
settings: settings,
|
|
113
|
+
agent_settings: agent_settings,
|
|
111
114
|
shutdown_timeout: settings.telemetry.shutdown_timeout_seconds,
|
|
112
115
|
)
|
|
113
116
|
|
|
@@ -26,14 +26,13 @@ module Datadog
|
|
|
26
26
|
|
|
27
27
|
def configuration
|
|
28
28
|
config = Datadog.configuration
|
|
29
|
-
seq_id = Event.configuration_sequence.next
|
|
30
29
|
|
|
31
30
|
res = @changes.map do |name, value|
|
|
32
31
|
{
|
|
33
32
|
name: name,
|
|
34
33
|
value: value,
|
|
35
34
|
origin: @origin,
|
|
36
|
-
seq_id:
|
|
35
|
+
seq_id: Configuration::Option::Precedence::REMOTE_CONFIGURATION.numeric.next,
|
|
37
36
|
}
|
|
38
37
|
end
|
|
39
38
|
|
|
@@ -43,7 +42,7 @@ module Datadog
|
|
|
43
42
|
name: 'appsec.sca_enabled',
|
|
44
43
|
value: config.appsec.sca_enabled,
|
|
45
44
|
origin: 'code',
|
|
46
|
-
seq_id:
|
|
45
|
+
seq_id: Configuration::Option::Precedence::PROGRAMMATIC.numeric.next,
|
|
47
46
|
}
|
|
48
47
|
end
|
|
49
48
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'app_started'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Core
|
|
7
|
+
module Telemetry
|
|
8
|
+
module Event
|
|
9
|
+
# Telemetry class for the 'app-extended-heartbeat' event
|
|
10
|
+
class AppExtendedHeartbeat < AppStarted
|
|
11
|
+
def initialize(settings:, agent_settings:)
|
|
12
|
+
@configuration = configuration(settings, agent_settings)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def type
|
|
16
|
+
'app-extended-heartbeat'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def payload
|
|
20
|
+
{
|
|
21
|
+
configuration: @configuration,
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def app_started?
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|