datadog 2.12.1 → 2.17.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 +154 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +16 -14
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +23 -23
- data/ext/libdatadog_api/crashtracker.c +11 -12
- data/ext/libdatadog_api/crashtracker.h +5 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +122 -0
- data/ext/libdatadog_api/library_config.h +19 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +117 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
- data/lib/datadog/appsec/actions_handler.rb +24 -2
- data/lib/datadog/appsec/anonymizer.rb +16 -0
- data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
- data/lib/datadog/appsec/api_security.rb +9 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +29 -20
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +93 -28
- data/lib/datadog/appsec/context.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
- data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
- data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
- data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
- data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
- data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +19 -18
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/event.rb +96 -135
- data/lib/datadog/appsec/ext.rb +4 -2
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
- data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
- data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
- data/lib/datadog/appsec/processor.rb +1 -1
- data/lib/datadog/appsec/remote.rb +23 -11
- data/lib/datadog/appsec/response.rb +6 -6
- data/lib/datadog/appsec/security_engine/runner.rb +3 -3
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/appsec.rb +1 -1
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +50 -31
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/ext.rb +4 -0
- data/lib/datadog/core/configuration/option.rb +79 -43
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +68 -35
- data/lib/datadog/core/configuration/stable_config.rb +23 -0
- data/lib/datadog/core/configuration.rb +40 -16
- data/lib/datadog/core/crashtracking/component.rb +3 -10
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/encoding.rb +1 -1
- data/lib/datadog/core/environment/agent_info.rb +4 -3
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +20 -21
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery.rb +32 -0
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client.rb +40 -32
- data/lib/datadog/core/remote/component.rb +6 -9
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/configuration/repository.rb +2 -1
- data/lib/datadog/core/remote/negotiation.rb +9 -9
- data/lib/datadog/core/remote/transport/config.rb +4 -3
- data/lib/datadog/core/remote/transport/http/client.rb +5 -4
- data/lib/datadog/core/remote/transport/http/config.rb +27 -37
- data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
- data/lib/datadog/core/remote/transport/http.rb +22 -57
- data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
- data/lib/datadog/core/runtime/metrics.rb +12 -5
- data/lib/datadog/core/telemetry/component.rb +78 -53
- data/lib/datadog/core/telemetry/emitter.rb +23 -11
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
- data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -472
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +8 -8
- data/lib/datadog/core/telemetry/request.rb +4 -4
- data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
- data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
- data/lib/datadog/core/telemetry/transport/http.rb +63 -0
- data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
- data/lib/datadog/core/telemetry/worker.rb +90 -24
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/api/instance.rb +17 -0
- data/lib/datadog/core/transport/http/api/spec.rb +17 -0
- data/lib/datadog/core/transport/http/builder.rb +18 -16
- data/lib/datadog/core/transport/http.rb +39 -2
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +20 -0
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +29 -12
- data/lib/datadog/core/workers/interval_loop.rb +12 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/core.rb +8 -0
- data/lib/datadog/di/boot.rb +34 -0
- data/lib/datadog/di/component.rb +0 -2
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/probe_notifier_worker.rb +16 -16
- data/lib/datadog/di/remote.rb +2 -0
- data/lib/datadog/di/transport/diagnostics.rb +4 -3
- data/lib/datadog/di/transport/http/api.rb +2 -12
- data/lib/datadog/di/transport/http/client.rb +4 -3
- data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
- data/lib/datadog/di/transport/http/input.rb +7 -34
- data/lib/datadog/di/transport/http.rb +14 -62
- data/lib/datadog/di/transport/input.rb +4 -3
- data/lib/datadog/di/utils.rb +5 -0
- data/lib/datadog/di.rb +5 -32
- data/lib/datadog/error_tracking/collector.rb +87 -0
- data/lib/datadog/error_tracking/component.rb +167 -0
- data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
- data/lib/datadog/error_tracking/configuration.rb +11 -0
- data/lib/datadog/error_tracking/ext.rb +18 -0
- data/lib/datadog/error_tracking/extensions.rb +16 -0
- data/lib/datadog/error_tracking/filters.rb +77 -0
- data/lib/datadog/error_tracking.rb +18 -0
- data/lib/datadog/kit/appsec/events.rb +12 -0
- data/lib/datadog/kit/identity.rb +5 -1
- data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
- data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
- data/lib/datadog/opentelemetry/api/context.rb +16 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/opentelemetry.rb +2 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +5 -59
- data/lib/datadog/profiling/scheduler.rb +8 -1
- data/lib/datadog/profiling/stack_recorder.rb +4 -4
- data/lib/datadog/profiling/tag_builder.rb +1 -5
- data/lib/datadog/profiling.rb +6 -2
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/component.rb +15 -12
- data/lib/datadog/tracing/configuration/ext.rb +7 -1
- data/lib/datadog/tracing/configuration/settings.rb +18 -2
- data/lib/datadog/tracing/context_provider.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
- data/lib/datadog/tracing/contrib/karafka.rb +37 -0
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/correlation.rb +9 -2
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/baggage.rb +131 -0
- data/lib/datadog/tracing/distributed/datadog.rb +4 -2
- data/lib/datadog/tracing/distributed/propagation.rb +25 -4
- data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/metadata/ext.rb +5 -0
- data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
- data/lib/datadog/tracing/metadata.rb +2 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
- data/lib/datadog/tracing/span.rb +10 -1
- data/lib/datadog/tracing/span_event.rb +1 -1
- data/lib/datadog/tracing/span_operation.rb +46 -16
- data/lib/datadog/tracing/sync_writer.rb +1 -2
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +44 -24
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +45 -5
- data/lib/datadog/tracing/transport/http/api.rb +2 -10
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -41
- data/lib/datadog/tracing/transport/http.rb +11 -44
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +26 -9
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
- data/lib/datadog/tracing/writer.rb +2 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -3
- metadata +80 -19
- data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
- data/lib/datadog/core/telemetry/http/env.rb +0 -20
- data/lib/datadog/core/telemetry/http/ext.rb +0 -28
- data/lib/datadog/core/telemetry/http/response.rb +0 -70
- data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -4,6 +4,7 @@
|
|
4
4
|
#include "helpers.h"
|
5
5
|
#include "libdatadog_helpers.h"
|
6
6
|
#include "ruby_helpers.h"
|
7
|
+
#include "encoded_profile.h"
|
7
8
|
|
8
9
|
// Used to report profiling data to Datadog.
|
9
10
|
// This file implements the native bits of the Datadog::Profiling::HttpTransport class
|
@@ -14,32 +15,22 @@ static VALUE error_symbol = Qnil; // :error in Ruby
|
|
14
15
|
static VALUE library_version_string = Qnil;
|
15
16
|
|
16
17
|
typedef struct {
|
17
|
-
|
18
|
-
|
18
|
+
ddog_prof_ProfileExporter *exporter;
|
19
|
+
ddog_prof_Request_Result *build_result;
|
19
20
|
ddog_CancellationToken *cancel_token;
|
20
|
-
|
21
|
+
ddog_prof_Result_HttpStatus result;
|
21
22
|
bool send_ran;
|
22
23
|
} call_exporter_without_gvl_arguments;
|
23
24
|
|
24
25
|
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
|
25
26
|
static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
|
26
|
-
static
|
27
|
-
static VALUE handle_exporter_failure(
|
27
|
+
static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
|
28
|
+
static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result);
|
28
29
|
static VALUE _native_do_export(
|
29
30
|
VALUE self,
|
30
31
|
VALUE exporter_configuration,
|
31
32
|
VALUE upload_timeout_milliseconds,
|
32
|
-
VALUE
|
33
|
-
VALUE start_timespec_nanoseconds,
|
34
|
-
VALUE finish_timespec_seconds,
|
35
|
-
VALUE finish_timespec_nanoseconds,
|
36
|
-
VALUE pprof_file_name,
|
37
|
-
VALUE pprof_data,
|
38
|
-
VALUE code_provenance_file_name,
|
39
|
-
VALUE code_provenance_data,
|
40
|
-
VALUE tags_as_array,
|
41
|
-
VALUE internal_metadata_json,
|
42
|
-
VALUE info_json
|
33
|
+
VALUE flush
|
43
34
|
);
|
44
35
|
static void *call_exporter_without_gvl(void *call_args);
|
45
36
|
static void interrupt_exporter_call(void *cancel_token);
|
@@ -48,7 +39,7 @@ void http_transport_init(VALUE profiling_module) {
|
|
48
39
|
VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
|
49
40
|
|
50
41
|
rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
|
51
|
-
rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export,
|
42
|
+
rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 3);
|
52
43
|
|
53
44
|
ok_symbol = ID2SYM(rb_intern_const("ok"));
|
54
45
|
error_symbol = ID2SYM(rb_intern_const("error"));
|
@@ -65,14 +56,14 @@ static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
|
|
65
56
|
|
66
57
|
static VALUE _native_validate_exporter(DDTRACE_UNUSED VALUE _self, VALUE exporter_configuration) {
|
67
58
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
68
|
-
|
59
|
+
ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, rb_ary_new());
|
69
60
|
|
70
61
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
71
62
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
72
63
|
|
73
64
|
// We don't actually need the exporter for now -- we just wanted to validate that we could create it with the
|
74
65
|
// settings we were given
|
75
|
-
ddog_prof_Exporter_drop(exporter_result.ok);
|
66
|
+
ddog_prof_Exporter_drop(&exporter_result.ok);
|
76
67
|
|
77
68
|
return rb_ary_new_from_args(2, ok_symbol, Qnil);
|
78
69
|
}
|
@@ -84,26 +75,21 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
|
|
84
75
|
ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
|
85
76
|
ID working_mode = SYM2ID(exporter_working_mode);
|
86
77
|
|
87
|
-
|
88
|
-
ID agent_id = rb_intern("agent");
|
89
|
-
|
90
|
-
if (working_mode != agentless_id && working_mode != agent_id) {
|
91
|
-
rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
|
92
|
-
}
|
93
|
-
|
94
|
-
if (working_mode == agentless_id) {
|
78
|
+
if (working_mode == rb_intern("agentless")) {
|
95
79
|
VALUE site = rb_ary_entry(exporter_configuration, 1);
|
96
80
|
VALUE api_key = rb_ary_entry(exporter_configuration, 2);
|
97
81
|
|
98
82
|
return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
|
99
|
-
} else
|
83
|
+
} else if (working_mode == rb_intern("agent")) {
|
100
84
|
VALUE base_url = rb_ary_entry(exporter_configuration, 1);
|
101
85
|
|
102
86
|
return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
|
87
|
+
} else {
|
88
|
+
rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
|
103
89
|
}
|
104
90
|
}
|
105
91
|
|
106
|
-
static
|
92
|
+
static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array) {
|
107
93
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
108
94
|
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
109
95
|
|
@@ -117,7 +103,7 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
|
|
117
103
|
ddog_CharSlice library_version = char_slice_from_ruby_string(library_version_string);
|
118
104
|
ddog_CharSlice profiling_family = DDOG_CHARSLICE_C("ruby");
|
119
105
|
|
120
|
-
|
106
|
+
ddog_prof_ProfileExporter_Result exporter_result =
|
121
107
|
ddog_prof_Exporter_new(library_name, library_version, profiling_family, &tags, endpoint);
|
122
108
|
|
123
109
|
ddog_Vec_Tag_drop(tags);
|
@@ -125,8 +111,12 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
|
|
125
111
|
return exporter_result;
|
126
112
|
}
|
127
113
|
|
128
|
-
static
|
129
|
-
|
114
|
+
static void validate_token(ddog_CancellationToken token, const char *file, int line) {
|
115
|
+
if (token.inner == NULL) rb_raise(rb_eRuntimeError, "Unexpected: Validation token was empty at %s:%d", file, line);
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result) {
|
119
|
+
return exporter_result.tag == DDOG_PROF_PROFILE_EXPORTER_RESULT_OK_HANDLE_PROFILE_EXPORTER ?
|
130
120
|
Qnil :
|
131
121
|
rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&exporter_result.err));
|
132
122
|
}
|
@@ -134,39 +124,37 @@ static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_resul
|
|
134
124
|
// Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
|
135
125
|
// which can raise exceptions, otherwise the objects will be leaked.
|
136
126
|
static VALUE perform_export(
|
137
|
-
|
138
|
-
|
139
|
-
ddog_Timespec finish,
|
127
|
+
ddog_prof_ProfileExporter *exporter,
|
128
|
+
ddog_prof_EncodedProfile *profile,
|
140
129
|
ddog_prof_Exporter_Slice_File files_to_compress_and_export,
|
141
|
-
ddog_prof_Exporter_Slice_File files_to_export_unmodified,
|
142
|
-
ddog_Vec_Tag *additional_tags,
|
143
130
|
ddog_CharSlice internal_metadata,
|
144
131
|
ddog_CharSlice info
|
145
132
|
) {
|
146
|
-
|
147
|
-
ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
|
133
|
+
ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
|
148
134
|
exporter,
|
149
|
-
|
150
|
-
finish,
|
135
|
+
profile,
|
151
136
|
files_to_compress_and_export,
|
152
|
-
files_to_export_unmodified,
|
153
|
-
|
154
|
-
endpoints_stats,
|
137
|
+
/* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
|
138
|
+
/* optional_additional_tags: */ NULL,
|
155
139
|
&internal_metadata,
|
156
140
|
&info
|
157
141
|
);
|
158
142
|
|
159
|
-
if (build_result.tag ==
|
143
|
+
if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
|
160
144
|
ddog_prof_Exporter_drop(exporter);
|
161
145
|
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
|
162
146
|
}
|
163
147
|
|
164
|
-
ddog_CancellationToken
|
148
|
+
ddog_CancellationToken cancel_token_request = ddog_CancellationToken_new();
|
149
|
+
ddog_CancellationToken cancel_token_interrupt = ddog_CancellationToken_clone(&cancel_token_request);
|
150
|
+
|
151
|
+
validate_token(cancel_token_request, __FILE__, __LINE__);
|
152
|
+
validate_token(cancel_token_interrupt, __FILE__, __LINE__);
|
165
153
|
|
166
154
|
// We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
|
167
155
|
// is pending
|
168
156
|
call_exporter_without_gvl_arguments args =
|
169
|
-
{.exporter = exporter, .build_result = &build_result, .cancel_token =
|
157
|
+
{.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
|
170
158
|
|
171
159
|
// We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
|
172
160
|
// exceptions.
|
@@ -183,14 +171,15 @@ static VALUE perform_export(
|
|
183
171
|
int pending_exception = 0;
|
184
172
|
|
185
173
|
while (!args.send_ran && !pending_exception) {
|
186
|
-
rb_thread_call_without_gvl2(call_exporter_without_gvl, &args, interrupt_exporter_call,
|
174
|
+
rb_thread_call_without_gvl2(call_exporter_without_gvl, &args, interrupt_exporter_call, &cancel_token_interrupt);
|
187
175
|
|
188
176
|
// To make sure we don't leak memory, we never check for pending exceptions if send ran
|
189
177
|
if (!args.send_ran) pending_exception = check_if_pending_exception();
|
190
178
|
}
|
191
179
|
|
192
180
|
// Cleanup exporter and token, no longer needed
|
193
|
-
ddog_CancellationToken_drop(
|
181
|
+
ddog_CancellationToken_drop(&cancel_token_request);
|
182
|
+
ddog_CancellationToken_drop(&cancel_token_interrupt);
|
194
183
|
ddog_prof_Exporter_drop(exporter);
|
195
184
|
|
196
185
|
if (pending_exception) {
|
@@ -203,10 +192,10 @@ static VALUE perform_export(
|
|
203
192
|
|
204
193
|
// The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
|
205
194
|
|
206
|
-
|
195
|
+
ddog_prof_Result_HttpStatus result = args.result;
|
207
196
|
|
208
|
-
return result.tag ==
|
209
|
-
rb_ary_new_from_args(2, ok_symbol, UINT2NUM(result.
|
197
|
+
return result.tag == DDOG_PROF_RESULT_HTTP_STATUS_OK_HTTP_STATUS ?
|
198
|
+
rb_ary_new_from_args(2, ok_symbol, UINT2NUM(result.ok.code)) :
|
210
199
|
rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&result.err));
|
211
200
|
}
|
212
201
|
|
@@ -214,26 +203,19 @@ static VALUE _native_do_export(
|
|
214
203
|
DDTRACE_UNUSED VALUE _self,
|
215
204
|
VALUE exporter_configuration,
|
216
205
|
VALUE upload_timeout_milliseconds,
|
217
|
-
VALUE
|
218
|
-
VALUE start_timespec_nanoseconds,
|
219
|
-
VALUE finish_timespec_seconds,
|
220
|
-
VALUE finish_timespec_nanoseconds,
|
221
|
-
VALUE pprof_file_name,
|
222
|
-
VALUE pprof_data,
|
223
|
-
VALUE code_provenance_file_name,
|
224
|
-
VALUE code_provenance_data,
|
225
|
-
VALUE tags_as_array,
|
226
|
-
VALUE internal_metadata_json,
|
227
|
-
VALUE info_json
|
206
|
+
VALUE flush
|
228
207
|
) {
|
208
|
+
VALUE encoded_profile = rb_funcall(flush, rb_intern("encoded_profile"), 0);
|
209
|
+
VALUE code_provenance_file_name = rb_funcall(flush, rb_intern("code_provenance_file_name"), 0);
|
210
|
+
VALUE code_provenance_data = rb_funcall(flush, rb_intern("code_provenance_data"), 0);
|
211
|
+
VALUE tags_as_array = rb_funcall(flush, rb_intern("tags_as_array"), 0);
|
212
|
+
VALUE internal_metadata_json = rb_funcall(flush, rb_intern("internal_metadata_json"), 0);
|
213
|
+
VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
|
214
|
+
|
229
215
|
ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
|
230
|
-
|
231
|
-
ENFORCE_TYPE(start_timespec_nanoseconds, T_FIXNUM);
|
232
|
-
ENFORCE_TYPE(finish_timespec_seconds, T_FIXNUM);
|
233
|
-
ENFORCE_TYPE(finish_timespec_nanoseconds, T_FIXNUM);
|
234
|
-
ENFORCE_TYPE(pprof_file_name, T_STRING);
|
235
|
-
ENFORCE_TYPE(pprof_data, T_STRING);
|
216
|
+
enforce_encoded_profile_instance(encoded_profile);
|
236
217
|
ENFORCE_TYPE(code_provenance_file_name, T_STRING);
|
218
|
+
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
237
219
|
ENFORCE_TYPE(internal_metadata_json, T_STRING);
|
238
220
|
ENFORCE_TYPE(info_json, T_STRING);
|
239
221
|
|
@@ -243,23 +225,9 @@ static VALUE _native_do_export(
|
|
243
225
|
|
244
226
|
uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
|
245
227
|
|
246
|
-
ddog_Timespec start =
|
247
|
-
{.seconds = NUM2LONG(start_timespec_seconds), .nanoseconds = NUM2UINT(start_timespec_nanoseconds)};
|
248
|
-
ddog_Timespec finish =
|
249
|
-
{.seconds = NUM2LONG(finish_timespec_seconds), .nanoseconds = NUM2UINT(finish_timespec_nanoseconds)};
|
250
|
-
|
251
228
|
int to_compress_length = have_code_provenance ? 1 : 0;
|
252
229
|
ddog_prof_Exporter_File to_compress[to_compress_length];
|
253
|
-
int already_compressed_length = 1; // pprof
|
254
|
-
ddog_prof_Exporter_File already_compressed[already_compressed_length];
|
255
|
-
|
256
230
|
ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
|
257
|
-
ddog_prof_Exporter_Slice_File files_to_export_unmodified = {.ptr = already_compressed, .len = already_compressed_length};
|
258
|
-
|
259
|
-
already_compressed[0] = (ddog_prof_Exporter_File) {
|
260
|
-
.name = char_slice_from_ruby_string(pprof_file_name),
|
261
|
-
.file = byte_slice_from_ruby_string(pprof_data),
|
262
|
-
};
|
263
231
|
|
264
232
|
if (have_code_provenance) {
|
265
233
|
to_compress[0] = (ddog_prof_Exporter_File) {
|
@@ -268,32 +236,28 @@ static VALUE _native_do_export(
|
|
268
236
|
};
|
269
237
|
}
|
270
238
|
|
271
|
-
ddog_Vec_Tag *null_additional_tags = NULL;
|
272
239
|
ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
|
273
240
|
ddog_CharSlice info = char_slice_from_ruby_string(info_json);
|
274
241
|
|
275
|
-
|
242
|
+
ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, tags_as_array);
|
276
243
|
// Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
|
277
244
|
|
278
245
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
279
246
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
280
247
|
|
281
|
-
|
282
|
-
if (timeout_result.tag ==
|
248
|
+
ddog_VoidResult timeout_result = ddog_prof_Exporter_set_timeout(&exporter_result.ok, timeout_milliseconds);
|
249
|
+
if (timeout_result.tag == DDOG_VOID_RESULT_ERR) {
|
283
250
|
// NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
|
284
251
|
// if the exporter is not well built. Because such a situation should already be caught above I think it's
|
285
252
|
// preferable to leave this here as a virtually unreachable exception rather than ignoring it.
|
286
|
-
ddog_prof_Exporter_drop(exporter_result.ok);
|
287
|
-
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.
|
253
|
+
ddog_prof_Exporter_drop(&exporter_result.ok);
|
254
|
+
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.err));
|
288
255
|
}
|
289
256
|
|
290
257
|
return perform_export(
|
291
|
-
exporter_result.ok,
|
292
|
-
|
293
|
-
finish,
|
258
|
+
&exporter_result.ok,
|
259
|
+
to_ddog_prof_EncodedProfile(encoded_profile),
|
294
260
|
files_to_compress_and_export,
|
295
|
-
files_to_export_unmodified,
|
296
|
-
null_additional_tags,
|
297
261
|
internal_metadata,
|
298
262
|
info
|
299
263
|
);
|
@@ -310,5 +274,7 @@ static void *call_exporter_without_gvl(void *call_args) {
|
|
310
274
|
|
311
275
|
// Called by Ruby when it wants to interrupt call_exporter_without_gvl above, e.g. when the app wants to exit cleanly
|
312
276
|
static void interrupt_exporter_call(void *cancel_token) {
|
277
|
+
// TODO: False here can mean two things: it was already cancelled OR it failed to cancel.
|
278
|
+
// Would be nice to change libdatadog to be able to distinguish between them...
|
313
279
|
ddog_CancellationToken_cancel((ddog_CancellationToken *) cancel_token);
|
314
280
|
}
|
@@ -312,6 +312,7 @@ VALUE thread_name_for(VALUE thread) {
|
|
312
312
|
// to support our custom rb_profile_frames (see below)
|
313
313
|
// Modifications:
|
314
314
|
// * Support int first_lineno for Ruby 3.2.0+ (https://github.com/ruby/ruby/pull/6430)
|
315
|
+
// * Validate iseq and pos before calling `rb_iseq_line_no` as a safety measure (see comment below for details)
|
315
316
|
//
|
316
317
|
// `node_id` gets used depending on Ruby VM compilation settings (USE_ISEQ_NODE_ID being defined).
|
317
318
|
// To avoid getting false "unused argument" warnings in setups where it's not used, we need to do this weird dance
|
@@ -358,6 +359,13 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
|
|
358
359
|
__builtin_trap();
|
359
360
|
}
|
360
361
|
#endif
|
362
|
+
|
363
|
+
// In PROF-11475 we spotted a crash when calling `rb_iseq_line_no` from this method. We couldn't reproduce or
|
364
|
+
// figure out the root cause, but "just in case", we're validating that the iseq looks valid and that the
|
365
|
+
// `n` used for the position is also sane, and if they don't look good, we don't calculate the line, rather
|
366
|
+
// than potentially trigger any issues.
|
367
|
+
if (RB_UNLIKELY(!RB_TYPE_P((VALUE) iseq, T_IMEMO) || n < 0 || n > ISEQ_BODY(iseq)->iseq_size)) return 0;
|
368
|
+
|
361
369
|
if (lineno) *lineno = rb_iseq_line_no(iseq, pos);
|
362
370
|
#ifdef USE_ISEQ_NODE_ID
|
363
371
|
if (node_id) *node_id = rb_iseq_node_id(iseq, pos);
|
@@ -20,6 +20,7 @@ void collectors_dynamic_sampling_rate_init(VALUE profiling_module);
|
|
20
20
|
void collectors_idle_sampling_helper_init(VALUE profiling_module);
|
21
21
|
void collectors_stack_init(VALUE profiling_module);
|
22
22
|
void collectors_thread_context_init(VALUE profiling_module);
|
23
|
+
void encoded_profile_init(VALUE profiling_module);
|
23
24
|
void http_transport_init(VALUE profiling_module);
|
24
25
|
void stack_recorder_init(VALUE profiling_module);
|
25
26
|
|
@@ -61,6 +62,7 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
|
|
61
62
|
collectors_idle_sampling_helper_init(profiling_module);
|
62
63
|
collectors_stack_init(profiling_module);
|
63
64
|
collectors_thread_context_init(profiling_module);
|
65
|
+
encoded_profile_init(profiling_module);
|
64
66
|
http_transport_init(profiling_module);
|
65
67
|
stack_recorder_init(profiling_module);
|
66
68
|
unsafe_api_calls_check_init();
|
@@ -8,6 +8,7 @@
|
|
8
8
|
#include "ruby_helpers.h"
|
9
9
|
#include "time_helpers.h"
|
10
10
|
#include "heap_recorder.h"
|
11
|
+
#include "encoded_profile.h"
|
11
12
|
|
12
13
|
// Used to wrap a ddog_prof_Profile in a Ruby object and expose Ruby-level serialization APIs
|
13
14
|
// This file implements the native bits of the Datadog::Profiling::StackRecorder class
|
@@ -181,6 +182,7 @@ typedef struct {
|
|
181
182
|
typedef struct {
|
182
183
|
ddog_prof_Profile profile;
|
183
184
|
stats_slot stats;
|
185
|
+
ddog_Timespec start_timestamp;
|
184
186
|
} profile_slot;
|
185
187
|
|
186
188
|
// Contains native state for each instance
|
@@ -252,7 +254,7 @@ static ddog_Timespec system_epoch_now_timespec(void);
|
|
252
254
|
static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance);
|
253
255
|
static void serializer_set_start_timestamp_for_next_profile(stack_recorder_state *state, ddog_Timespec start_time);
|
254
256
|
static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint);
|
255
|
-
static void reset_profile_slot(profile_slot *slot, ddog_Timespec
|
257
|
+
static void reset_profile_slot(profile_slot *slot, ddog_Timespec start_timestamp);
|
256
258
|
static VALUE _native_track_object(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE new_obj, VALUE weight, VALUE alloc_class);
|
257
259
|
static VALUE _native_check_heap_hashes(DDTRACE_UNUSED VALUE _self, VALUE locations);
|
258
260
|
static VALUE _native_start_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
@@ -358,24 +360,26 @@ static void initialize_slot_concurrency_control(stack_recorder_state *state) {
|
|
358
360
|
}
|
359
361
|
|
360
362
|
static void initialize_profiles(stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types) {
|
363
|
+
ddog_Timespec start_timestamp = system_epoch_now_timespec();
|
364
|
+
|
361
365
|
ddog_prof_Profile_NewResult slot_one_profile_result =
|
362
|
-
ddog_prof_Profile_new(sample_types, NULL /* period is optional
|
366
|
+
ddog_prof_Profile_new(sample_types, NULL /* period is optional */);
|
363
367
|
|
364
368
|
if (slot_one_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
|
365
369
|
rb_raise(rb_eRuntimeError, "Failed to initialize slot one profile: %"PRIsVALUE, get_error_details_and_drop(&slot_one_profile_result.err));
|
366
370
|
}
|
367
371
|
|
368
|
-
state->profile_slot_one = (profile_slot) { .profile = slot_one_profile_result.ok };
|
372
|
+
state->profile_slot_one = (profile_slot) { .profile = slot_one_profile_result.ok, .start_timestamp = start_timestamp };
|
369
373
|
|
370
374
|
ddog_prof_Profile_NewResult slot_two_profile_result =
|
371
|
-
ddog_prof_Profile_new(sample_types, NULL /* period is optional
|
375
|
+
ddog_prof_Profile_new(sample_types, NULL /* period is optional */);
|
372
376
|
|
373
377
|
if (slot_two_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
|
374
378
|
// Note: No need to take any special care of slot one, it'll get cleaned up by stack_recorder_typed_data_free
|
375
379
|
rb_raise(rb_eRuntimeError, "Failed to initialize slot two profile: %"PRIsVALUE, get_error_details_and_drop(&slot_two_profile_result.err));
|
376
380
|
}
|
377
381
|
|
378
|
-
state->profile_slot_two = (profile_slot) { .profile = slot_two_profile_result.ok };
|
382
|
+
state->profile_slot_two = (profile_slot) { .profile = slot_two_profile_result.ok, .start_timestamp = start_timestamp };
|
379
383
|
}
|
380
384
|
|
381
385
|
static void stack_recorder_typed_data_free(void *state_ptr) {
|
@@ -564,18 +568,14 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
|
|
564
568
|
|
565
569
|
state->stats_lifetime.serialization_successes++;
|
566
570
|
|
567
|
-
|
568
|
-
|
569
|
-
ddog_Timespec ddprof_start = serialized_profile.ok.start;
|
570
|
-
ddog_Timespec ddprof_finish = serialized_profile.ok.end;
|
571
|
-
|
572
|
-
ddog_prof_EncodedProfile_drop(&serialized_profile.ok);
|
571
|
+
// Once we wrap this into a Ruby object, our `EncodedProfile` class will automatically manage memory for it
|
572
|
+
VALUE encoded_profile = from_ddog_prof_EncodedProfile(serialized_profile.ok);
|
573
573
|
|
574
|
-
VALUE start = ruby_time_from(
|
575
|
-
VALUE finish = ruby_time_from(
|
574
|
+
VALUE start = ruby_time_from(args.slot->start_timestamp);
|
575
|
+
VALUE finish = ruby_time_from(finish_timestamp);
|
576
576
|
VALUE profile_stats = build_profile_stats(args.slot, serialization_time_ns, heap_iteration_prep_time_ns, args.heap_profile_build_time_ns);
|
577
577
|
|
578
|
-
return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(4, start, finish,
|
578
|
+
return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(4, start, finish, encoded_profile, profile_stats));
|
579
579
|
}
|
580
580
|
|
581
581
|
static VALUE ruby_time_from(ddog_Timespec ddprof_time) {
|
@@ -763,7 +763,6 @@ static void *call_serialize_without_gvl(void *call_args) {
|
|
763
763
|
long serialize_no_gvl_start_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
|
764
764
|
|
765
765
|
profile_slot *slot_now_inactive = serializer_flip_active_and_inactive_slots(args->state);
|
766
|
-
|
767
766
|
args->slot = slot_now_inactive;
|
768
767
|
|
769
768
|
// Now that we have the inactive profile with all but heap samples, lets fill it with heap data
|
@@ -772,7 +771,7 @@ static void *call_serialize_without_gvl(void *call_args) {
|
|
772
771
|
args->heap_profile_build_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns;
|
773
772
|
|
774
773
|
// Note: The profile gets reset by the serialize call
|
775
|
-
args->result = ddog_prof_Profile_serialize(&args->slot->profile, &args->
|
774
|
+
args->result = ddog_prof_Profile_serialize(&args->slot->profile, &args->slot->start_timestamp, &args->finish_timestamp);
|
776
775
|
args->serialize_ran = true;
|
777
776
|
args->serialize_no_gvl_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns;
|
778
777
|
|
@@ -780,7 +779,7 @@ static void *call_serialize_without_gvl(void *call_args) {
|
|
780
779
|
}
|
781
780
|
|
782
781
|
VALUE enforce_recorder_instance(VALUE object) {
|
783
|
-
|
782
|
+
ENFORCE_TYPED_DATA(object, &stack_recorder_typed_data);
|
784
783
|
return object;
|
785
784
|
}
|
786
785
|
|
@@ -889,9 +888,9 @@ static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_
|
|
889
888
|
// In case the fork happened halfway through `serializer_flip_active_and_inactive_slots` execution and the
|
890
889
|
// resulting state is inconsistent, we make sure to reset it back to the initial state.
|
891
890
|
initialize_slot_concurrency_control(state);
|
892
|
-
|
893
|
-
reset_profile_slot(&state->profile_slot_one,
|
894
|
-
reset_profile_slot(&state->profile_slot_two,
|
891
|
+
ddog_Timespec start_timestamp = system_epoch_now_timespec();
|
892
|
+
reset_profile_slot(&state->profile_slot_one, start_timestamp);
|
893
|
+
reset_profile_slot(&state->profile_slot_two, start_timestamp);
|
895
894
|
|
896
895
|
heap_recorder_after_fork(state->heap_recorder);
|
897
896
|
|
@@ -903,7 +902,7 @@ static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_
|
|
903
902
|
static void serializer_set_start_timestamp_for_next_profile(stack_recorder_state *state, ddog_Timespec start_time) {
|
904
903
|
// Before making this profile active, we reset it so that it uses the correct start_time for its start
|
905
904
|
profile_slot *next_profile_slot = (state->active_slot == 1) ? &state->profile_slot_two : &state->profile_slot_one;
|
906
|
-
reset_profile_slot(next_profile_slot,
|
905
|
+
reset_profile_slot(next_profile_slot, start_time);
|
907
906
|
}
|
908
907
|
|
909
908
|
static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint) {
|
@@ -948,11 +947,12 @@ static VALUE _native_check_heap_hashes(DDTRACE_UNUSED VALUE _self, VALUE locatio
|
|
948
947
|
return Qnil;
|
949
948
|
}
|
950
949
|
|
951
|
-
static void reset_profile_slot(profile_slot *slot, ddog_Timespec
|
952
|
-
ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(&slot->profile
|
950
|
+
static void reset_profile_slot(profile_slot *slot, ddog_Timespec start_timestamp) {
|
951
|
+
ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(&slot->profile);
|
953
952
|
if (reset_result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
|
954
953
|
rb_raise(rb_eRuntimeError, "Failed to reset profile: %"PRIsVALUE, get_error_details_and_drop(&reset_result.err));
|
955
954
|
}
|
955
|
+
slot->start_timestamp = start_timestamp;
|
956
956
|
slot->stats = (stats_slot) {};
|
957
957
|
}
|
958
958
|
|
@@ -5,20 +5,14 @@
|
|
5
5
|
|
6
6
|
static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
|
7
7
|
static VALUE _native_stop(DDTRACE_UNUSED VALUE _self);
|
8
|
-
|
8
|
+
|
9
|
+
static bool first_init = true;
|
9
10
|
|
10
11
|
// Used to report Ruby VM crashes.
|
11
12
|
// Once initialized, segfaults will be reported automatically using libdatadog.
|
12
13
|
|
13
|
-
void
|
14
|
-
VALUE datadog_module = rb_define_module("Datadog");
|
15
|
-
VALUE core_module = rb_define_module_under(datadog_module, "Core");
|
14
|
+
void crashtracker_init(VALUE core_module) {
|
16
15
|
VALUE crashtracking_module = rb_define_module_under(core_module, "Crashtracking");
|
17
|
-
|
18
|
-
crashtracker_init(crashtracking_module);
|
19
|
-
}
|
20
|
-
|
21
|
-
void crashtracker_init(VALUE crashtracking_module) {
|
22
16
|
VALUE crashtracker_class = rb_define_class_under(crashtracking_module, "Component", rb_cObject);
|
23
17
|
|
24
18
|
rb_define_singleton_method(crashtracker_class, "_native_start_or_update_on_fork", _native_start_or_update_on_fork, -1);
|
@@ -70,7 +64,7 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
70
64
|
// "Process.kill('SEGV', Process.pid)" gets run.
|
71
65
|
//
|
72
66
|
// This actually changed in libdatadog 14, so I could see no issues with `create_alt_stack = true`, but not
|
73
|
-
//
|
67
|
+
// overriding what Ruby set up seems a saner default to keep anyway.
|
74
68
|
.create_alt_stack = false,
|
75
69
|
.use_alt_stack = true,
|
76
70
|
.endpoint = endpoint,
|
@@ -100,9 +94,14 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
100
94
|
|
101
95
|
ddog_VoidResult result =
|
102
96
|
action == start_action ?
|
103
|
-
|
97
|
+
(first_init ?
|
98
|
+
ddog_crasht_init(config, receiver_config, metadata) :
|
99
|
+
ddog_crasht_reconfigure(config, receiver_config, metadata)
|
100
|
+
) :
|
104
101
|
ddog_crasht_update_on_fork(config, receiver_config, metadata);
|
105
102
|
|
103
|
+
first_init = false;
|
104
|
+
|
106
105
|
// Clean up before potentially raising any exceptions
|
107
106
|
ddog_Vec_Tag_drop(tags);
|
108
107
|
ddog_endpoint_drop(endpoint);
|
@@ -116,7 +115,7 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
116
115
|
}
|
117
116
|
|
118
117
|
static VALUE _native_stop(DDTRACE_UNUSED VALUE _self) {
|
119
|
-
ddog_VoidResult result =
|
118
|
+
ddog_VoidResult result = ddog_crasht_disable();
|
120
119
|
|
121
120
|
if (result.tag == DDOG_VOID_RESULT_ERR) {
|
122
121
|
rb_raise(rb_eRuntimeError, "Failed to stop the crash tracker: %"PRIsVALUE, get_error_details_and_drop(&result.err));
|
@@ -29,10 +29,7 @@ VALUE datadog_gem_version(void) {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
static VALUE log_failure_to_process_tag(VALUE err_details) {
|
32
|
-
|
33
|
-
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
34
|
-
|
35
|
-
return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
|
32
|
+
return log_warning(rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
|
36
33
|
}
|
37
34
|
|
38
35
|
__attribute__((warn_unused_result))
|
@@ -27,6 +27,9 @@
|
|
27
27
|
#define ENFORCE_BOOLEAN(value) \
|
28
28
|
{ if (RB_UNLIKELY(value != Qtrue && value != Qfalse)) raise_unexpected_type(value, ADD_QUOTES(value), "true or false", __FILE__, __LINE__, __func__); }
|
29
29
|
|
30
|
+
#define ENFORCE_TYPED_DATA(value, type) \
|
31
|
+
{ if (RB_UNLIKELY(!rb_typeddata_is_kind_of(value, type))) raise_unexpected_type(value, ADD_QUOTES(value), "TypedData of type " ADD_QUOTES(type), __FILE__, __LINE__, __func__); }
|
32
|
+
|
30
33
|
NORETURN(void raise_unexpected_type(VALUE value, const char *value_name, const char *type_name, const char *file, int line, const char* function_name));
|
31
34
|
|
32
35
|
// Helper to retrieve Datadog::VERSION::STRING
|
@@ -38,6 +41,13 @@ static inline ddog_CharSlice char_slice_from_ruby_string(VALUE string) {
|
|
38
41
|
return char_slice;
|
39
42
|
}
|
40
43
|
|
44
|
+
static inline VALUE log_warning(VALUE warning) {
|
45
|
+
VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
|
46
|
+
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
47
|
+
|
48
|
+
return rb_funcall(logger, rb_intern("warn"), 1, warning);
|
49
|
+
}
|
50
|
+
|
41
51
|
__attribute__((warn_unused_result))
|
42
52
|
ddog_Vec_Tag convert_tags(VALUE tags_as_array);
|
43
53
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#include "datadog_ruby_common.h"
|
4
|
+
#include "crashtracker.h"
|
5
|
+
#include "process_discovery.h"
|
6
|
+
#include "library_config.h"
|
7
|
+
|
8
|
+
void DDTRACE_EXPORT Init_libdatadog_api(void) {
|
9
|
+
VALUE datadog_module = rb_define_module("Datadog");
|
10
|
+
VALUE core_module = rb_define_module_under(datadog_module, "Core");
|
11
|
+
|
12
|
+
crashtracker_init(core_module);
|
13
|
+
process_discovery_init(core_module);
|
14
|
+
library_config_init(core_module);
|
15
|
+
}
|