datadog 2.16.0 → 2.18.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 +72 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +12 -46
- data/ext/datadog_profiling_native_extension/collectors_stack.c +227 -49
- data/ext/datadog_profiling_native_extension/collectors_stack.h +19 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +63 -12
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +22 -12
- data/ext/datadog_profiling_native_extension/encoded_profile.h +1 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +7 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +239 -363
- data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
- data/ext/datadog_profiling_native_extension/http_transport.c +45 -72
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +1 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -3
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +2 -10
- data/ext/datadog_profiling_native_extension/stack_recorder.c +156 -60
- data/ext/libdatadog_api/crashtracker.c +10 -3
- data/ext/libdatadog_api/extconf.rb +2 -2
- data/ext/libdatadog_api/library_config.c +54 -12
- data/ext/libdatadog_api/library_config.h +6 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +2 -7
- data/ext/libdatadog_extconf_helpers.rb +2 -2
- data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +65 -0
- data/lib/datadog/appsec/api_security/sampler.rb +59 -0
- data/lib/datadog/appsec/api_security.rb +23 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +257 -85
- data/lib/datadog/appsec/assets/waf_rules/strict.json +10 -78
- data/lib/datadog/appsec/component.rb +30 -54
- data/lib/datadog/appsec/configuration/settings.rb +60 -2
- data/lib/datadog/appsec/context.rb +6 -6
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +27 -16
- data/lib/datadog/appsec/processor/rule_loader.rb +5 -6
- data/lib/datadog/appsec/remote.rb +15 -55
- data/lib/datadog/appsec/security_engine/engine.rb +194 -0
- data/lib/datadog/appsec/security_engine/runner.rb +10 -11
- data/lib/datadog/appsec.rb +4 -7
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings.rb +52 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -46
- data/lib/datadog/core/configuration/components.rb +31 -24
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/option.rb +27 -27
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +32 -20
- data/lib/datadog/core/configuration/stable_config.rb +1 -2
- data/lib/datadog/core/configuration.rb +16 -16
- data/lib/datadog/core/crashtracking/component.rb +2 -1
- data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
- data/lib/datadog/core/encoding.rb +1 -1
- 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/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +12 -14
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
- data/lib/datadog/core/process_discovery.rb +5 -1
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client.rb +32 -31
- data/lib/datadog/core/remote/component.rb +3 -3
- 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 +12 -0
- data/lib/datadog/core/remote/transport/http/client.rb +1 -1
- data/lib/datadog/core/remote/transport/http/config.rb +21 -5
- data/lib/datadog/core/remote/transport/http/negotiation.rb +1 -1
- data/lib/datadog/core/runtime/metrics.rb +3 -3
- data/lib/datadog/core/tag_builder.rb +56 -0
- data/lib/datadog/core/telemetry/component.rb +39 -24
- data/lib/datadog/core/telemetry/emitter.rb +7 -1
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -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 +269 -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 -475
- data/lib/datadog/core/telemetry/logger.rb +5 -4
- data/lib/datadog/core/telemetry/logging.rb +11 -5
- data/lib/datadog/core/telemetry/metric.rb +3 -3
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +2 -2
- data/lib/datadog/core/telemetry/transport/telemetry.rb +0 -1
- data/lib/datadog/core/telemetry/worker.rb +48 -27
- data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/builder.rb +14 -14
- data/lib/datadog/core/transport/http/env.rb +8 -0
- 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 +10 -2
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/utils.rb +7 -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 +9 -10
- data/lib/datadog/di/instrumenter.rb +52 -2
- data/lib/datadog/di/probe_notification_builder.rb +31 -41
- data/lib/datadog/di/probe_notifier_worker.rb +9 -1
- data/lib/datadog/di/serializer.rb +6 -2
- data/lib/datadog/di/transport/http/input.rb +10 -0
- data/lib/datadog/di/transport/input.rb +10 -2
- data/lib/datadog/error_tracking/component.rb +2 -2
- data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +16 -1
- data/lib/datadog/profiling/component.rb +7 -9
- data/lib/datadog/profiling/ext.rb +0 -13
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +3 -8
- data/lib/datadog/profiling/profiler.rb +2 -0
- data/lib/datadog/profiling/scheduler.rb +10 -2
- data/lib/datadog/profiling/stack_recorder.rb +5 -5
- data/lib/datadog/profiling/tag_builder.rb +5 -41
- data/lib/datadog/profiling/tasks/setup.rb +2 -0
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
- 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/http/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/sync_writer.rb +1 -1
- data/lib/datadog/tracing/trace_operation.rb +12 -4
- data/lib/datadog/tracing/tracer.rb +6 -2
- data/lib/datadog/version.rb +1 -1
- metadata +31 -12
- data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -321
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -1023
- data/lib/datadog/appsec/processor/rule_merger.rb +0 -171
- data/lib/datadog/appsec/processor.rb +0 -107
@@ -34,7 +34,7 @@ typedef struct {
|
|
34
34
|
|
35
35
|
// The class of the object that we're tracking.
|
36
36
|
// NOTE: This is optional and will be set to NULL if not set.
|
37
|
-
|
37
|
+
ddog_prof_ManagedStringId class;
|
38
38
|
|
39
39
|
// The GC allocation gen in which we saw this object being allocated.
|
40
40
|
//
|
@@ -59,7 +59,7 @@ typedef struct {
|
|
59
59
|
} heap_recorder_iteration_data;
|
60
60
|
|
61
61
|
// Initialize a new heap recorder.
|
62
|
-
heap_recorder* heap_recorder_new(
|
62
|
+
heap_recorder* heap_recorder_new(ddog_prof_ManagedStringStorage string_storage);
|
63
63
|
|
64
64
|
// Free a previously initialized heap recorder.
|
65
65
|
void heap_recorder_free(heap_recorder *heap_recorder);
|
@@ -164,10 +164,6 @@ VALUE heap_recorder_state_snapshot(heap_recorder *heap_recorder);
|
|
164
164
|
|
165
165
|
// v--- TEST-ONLY APIs ---v
|
166
166
|
|
167
|
-
// Assert internal hashing logic is valid for the provided locations and its
|
168
|
-
// corresponding internal representations in heap recorder.
|
169
|
-
void heap_recorder_testonly_assert_hash_matches(ddog_prof_Slice_Location locations);
|
170
|
-
|
171
167
|
// Returns a Ruby string with a representation of internal data helpful to
|
172
168
|
// troubleshoot issues such as unexpected test failures.
|
173
169
|
VALUE heap_recorder_testonly_debug(heap_recorder *heap_recorder);
|
@@ -177,3 +173,5 @@ VALUE heap_recorder_testonly_is_object_recorded(heap_recorder *heap_recorder, VA
|
|
177
173
|
|
178
174
|
// Used to ensure that a GC actually triggers an update of the objects
|
179
175
|
void heap_recorder_testonly_reset_last_update(heap_recorder *heap_recorder);
|
176
|
+
|
177
|
+
void heap_recorder_testonly_benchmark_intern(heap_recorder *heap_recorder, ddog_CharSlice string, int times, bool use_all);
|
@@ -15,26 +15,22 @@ static VALUE error_symbol = Qnil; // :error in Ruby
|
|
15
15
|
static VALUE library_version_string = Qnil;
|
16
16
|
|
17
17
|
typedef struct {
|
18
|
-
|
19
|
-
|
18
|
+
ddog_prof_ProfileExporter *exporter;
|
19
|
+
ddog_prof_Request_Result *build_result;
|
20
20
|
ddog_CancellationToken *cancel_token;
|
21
|
-
|
21
|
+
ddog_prof_Result_HttpStatus result;
|
22
22
|
bool send_ran;
|
23
23
|
} call_exporter_without_gvl_arguments;
|
24
24
|
|
25
25
|
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
|
26
26
|
static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
|
27
|
-
static
|
28
|
-
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);
|
29
29
|
static VALUE _native_do_export(
|
30
30
|
VALUE self,
|
31
31
|
VALUE exporter_configuration,
|
32
32
|
VALUE upload_timeout_milliseconds,
|
33
|
-
VALUE flush
|
34
|
-
VALUE start_timespec_seconds,
|
35
|
-
VALUE start_timespec_nanoseconds,
|
36
|
-
VALUE finish_timespec_seconds,
|
37
|
-
VALUE finish_timespec_nanoseconds
|
33
|
+
VALUE flush
|
38
34
|
);
|
39
35
|
static void *call_exporter_without_gvl(void *call_args);
|
40
36
|
static void interrupt_exporter_call(void *cancel_token);
|
@@ -43,7 +39,7 @@ void http_transport_init(VALUE profiling_module) {
|
|
43
39
|
VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
|
44
40
|
|
45
41
|
rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
|
46
|
-
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);
|
47
43
|
|
48
44
|
ok_symbol = ID2SYM(rb_intern_const("ok"));
|
49
45
|
error_symbol = ID2SYM(rb_intern_const("error"));
|
@@ -60,14 +56,14 @@ static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
|
|
60
56
|
|
61
57
|
static VALUE _native_validate_exporter(DDTRACE_UNUSED VALUE _self, VALUE exporter_configuration) {
|
62
58
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
63
|
-
|
59
|
+
ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, rb_ary_new());
|
64
60
|
|
65
61
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
66
62
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
67
63
|
|
68
64
|
// We don't actually need the exporter for now -- we just wanted to validate that we could create it with the
|
69
65
|
// settings we were given
|
70
|
-
ddog_prof_Exporter_drop(exporter_result.ok);
|
66
|
+
ddog_prof_Exporter_drop(&exporter_result.ok);
|
71
67
|
|
72
68
|
return rb_ary_new_from_args(2, ok_symbol, Qnil);
|
73
69
|
}
|
@@ -93,7 +89,7 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
|
|
93
89
|
}
|
94
90
|
}
|
95
91
|
|
96
|
-
static
|
92
|
+
static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array) {
|
97
93
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
98
94
|
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
99
95
|
|
@@ -107,7 +103,7 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
|
|
107
103
|
ddog_CharSlice library_version = char_slice_from_ruby_string(library_version_string);
|
108
104
|
ddog_CharSlice profiling_family = DDOG_CHARSLICE_C("ruby");
|
109
105
|
|
110
|
-
|
106
|
+
ddog_prof_ProfileExporter_Result exporter_result =
|
111
107
|
ddog_prof_Exporter_new(library_name, library_version, profiling_family, &tags, endpoint);
|
112
108
|
|
113
109
|
ddog_Vec_Tag_drop(tags);
|
@@ -115,8 +111,12 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
|
|
115
111
|
return exporter_result;
|
116
112
|
}
|
117
113
|
|
118
|
-
static
|
119
|
-
|
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 ?
|
120
120
|
Qnil :
|
121
121
|
rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&exporter_result.err));
|
122
122
|
}
|
@@ -124,38 +124,37 @@ static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_resul
|
|
124
124
|
// Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
|
125
125
|
// which can raise exceptions, otherwise the objects will be leaked.
|
126
126
|
static VALUE perform_export(
|
127
|
-
|
128
|
-
|
129
|
-
ddog_Timespec finish,
|
127
|
+
ddog_prof_ProfileExporter *exporter,
|
128
|
+
ddog_prof_EncodedProfile *profile,
|
130
129
|
ddog_prof_Exporter_Slice_File files_to_compress_and_export,
|
131
|
-
ddog_prof_Exporter_Slice_File files_to_export_unmodified,
|
132
130
|
ddog_CharSlice internal_metadata,
|
133
131
|
ddog_CharSlice info
|
134
132
|
) {
|
135
|
-
|
136
|
-
ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
|
133
|
+
ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
|
137
134
|
exporter,
|
138
|
-
|
139
|
-
finish,
|
135
|
+
profile,
|
140
136
|
files_to_compress_and_export,
|
141
|
-
files_to_export_unmodified,
|
137
|
+
/* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
|
142
138
|
/* optional_additional_tags: */ NULL,
|
143
|
-
endpoints_stats,
|
144
139
|
&internal_metadata,
|
145
140
|
&info
|
146
141
|
);
|
147
142
|
|
148
|
-
if (build_result.tag ==
|
143
|
+
if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
|
149
144
|
ddog_prof_Exporter_drop(exporter);
|
150
145
|
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
|
151
146
|
}
|
152
147
|
|
153
|
-
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__);
|
154
153
|
|
155
154
|
// We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
|
156
155
|
// is pending
|
157
156
|
call_exporter_without_gvl_arguments args =
|
158
|
-
{.exporter = exporter, .build_result = &build_result, .cancel_token =
|
157
|
+
{.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
|
159
158
|
|
160
159
|
// We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
|
161
160
|
// exceptions.
|
@@ -172,14 +171,15 @@ static VALUE perform_export(
|
|
172
171
|
int pending_exception = 0;
|
173
172
|
|
174
173
|
while (!args.send_ran && !pending_exception) {
|
175
|
-
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);
|
176
175
|
|
177
176
|
// To make sure we don't leak memory, we never check for pending exceptions if send ran
|
178
177
|
if (!args.send_ran) pending_exception = check_if_pending_exception();
|
179
178
|
}
|
180
179
|
|
181
180
|
// Cleanup exporter and token, no longer needed
|
182
|
-
ddog_CancellationToken_drop(
|
181
|
+
ddog_CancellationToken_drop(&cancel_token_request);
|
182
|
+
ddog_CancellationToken_drop(&cancel_token_interrupt);
|
183
183
|
ddog_prof_Exporter_drop(exporter);
|
184
184
|
|
185
185
|
if (pending_exception) {
|
@@ -192,10 +192,10 @@ static VALUE perform_export(
|
|
192
192
|
|
193
193
|
// The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
|
194
194
|
|
195
|
-
|
195
|
+
ddog_prof_Result_HttpStatus result = args.result;
|
196
196
|
|
197
|
-
return result.tag ==
|
198
|
-
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)) :
|
199
199
|
rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&result.err));
|
200
200
|
}
|
201
201
|
|
@@ -203,11 +203,7 @@ static VALUE _native_do_export(
|
|
203
203
|
DDTRACE_UNUSED VALUE _self,
|
204
204
|
VALUE exporter_configuration,
|
205
205
|
VALUE upload_timeout_milliseconds,
|
206
|
-
VALUE flush
|
207
|
-
VALUE start_timespec_seconds,
|
208
|
-
VALUE start_timespec_nanoseconds,
|
209
|
-
VALUE finish_timespec_seconds,
|
210
|
-
VALUE finish_timespec_nanoseconds
|
206
|
+
VALUE flush
|
211
207
|
) {
|
212
208
|
VALUE encoded_profile = rb_funcall(flush, rb_intern("encoded_profile"), 0);
|
213
209
|
VALUE code_provenance_file_name = rb_funcall(flush, rb_intern("code_provenance_file_name"), 0);
|
@@ -217,10 +213,6 @@ static VALUE _native_do_export(
|
|
217
213
|
VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
|
218
214
|
|
219
215
|
ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
|
220
|
-
ENFORCE_TYPE(start_timespec_seconds, T_FIXNUM);
|
221
|
-
ENFORCE_TYPE(start_timespec_nanoseconds, T_FIXNUM);
|
222
|
-
ENFORCE_TYPE(finish_timespec_seconds, T_FIXNUM);
|
223
|
-
ENFORCE_TYPE(finish_timespec_nanoseconds, T_FIXNUM);
|
224
216
|
enforce_encoded_profile_instance(encoded_profile);
|
225
217
|
ENFORCE_TYPE(code_provenance_file_name, T_STRING);
|
226
218
|
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
@@ -233,28 +225,9 @@ static VALUE _native_do_export(
|
|
233
225
|
|
234
226
|
uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
|
235
227
|
|
236
|
-
ddog_Timespec start =
|
237
|
-
{.seconds = NUM2LONG(start_timespec_seconds), .nanoseconds = NUM2UINT(start_timespec_nanoseconds)};
|
238
|
-
ddog_Timespec finish =
|
239
|
-
{.seconds = NUM2LONG(finish_timespec_seconds), .nanoseconds = NUM2UINT(finish_timespec_nanoseconds)};
|
240
|
-
|
241
228
|
int to_compress_length = have_code_provenance ? 1 : 0;
|
242
229
|
ddog_prof_Exporter_File to_compress[to_compress_length];
|
243
|
-
int already_compressed_length = 1; // pprof
|
244
|
-
ddog_prof_Exporter_File already_compressed[already_compressed_length];
|
245
|
-
|
246
230
|
ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
|
247
|
-
ddog_prof_Exporter_Slice_File files_to_export_unmodified = {.ptr = already_compressed, .len = already_compressed_length};
|
248
|
-
|
249
|
-
// TODO: Hardcoding the file name will go away with libdatadog 17
|
250
|
-
VALUE pprof_file_name = rb_str_new_cstr("rubyprofile.pprof");
|
251
|
-
VALUE pprof_data = rb_funcall(encoded_profile, rb_intern("_native_bytes"), 0);
|
252
|
-
ENFORCE_TYPE(pprof_data, T_STRING);
|
253
|
-
|
254
|
-
already_compressed[0] = (ddog_prof_Exporter_File) {
|
255
|
-
.name = char_slice_from_ruby_string(pprof_file_name),
|
256
|
-
.file = byte_slice_from_ruby_string(pprof_data),
|
257
|
-
};
|
258
231
|
|
259
232
|
if (have_code_provenance) {
|
260
233
|
to_compress[0] = (ddog_prof_Exporter_File) {
|
@@ -266,27 +239,25 @@ static VALUE _native_do_export(
|
|
266
239
|
ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
|
267
240
|
ddog_CharSlice info = char_slice_from_ruby_string(info_json);
|
268
241
|
|
269
|
-
|
242
|
+
ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, tags_as_array);
|
270
243
|
// Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
|
271
244
|
|
272
245
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
273
246
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
274
247
|
|
275
|
-
|
276
|
-
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) {
|
277
250
|
// NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
|
278
251
|
// if the exporter is not well built. Because such a situation should already be caught above I think it's
|
279
252
|
// preferable to leave this here as a virtually unreachable exception rather than ignoring it.
|
280
|
-
ddog_prof_Exporter_drop(exporter_result.ok);
|
281
|
-
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));
|
282
255
|
}
|
283
256
|
|
284
257
|
return perform_export(
|
285
|
-
exporter_result.ok,
|
286
|
-
|
287
|
-
finish,
|
258
|
+
&exporter_result.ok,
|
259
|
+
to_ddog_prof_EncodedProfile(encoded_profile),
|
288
260
|
files_to_compress_and_export,
|
289
|
-
files_to_export_unmodified,
|
290
261
|
internal_metadata,
|
291
262
|
info
|
292
263
|
);
|
@@ -303,5 +274,7 @@ static void *call_exporter_without_gvl(void *call_args) {
|
|
303
274
|
|
304
275
|
// Called by Ruby when it wants to interrupt call_exporter_without_gvl above, e.g. when the app wants to exit cleanly
|
305
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...
|
306
279
|
ddog_CancellationToken_cancel((ddog_CancellationToken *) cancel_token);
|
307
280
|
}
|
@@ -60,3 +60,25 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
|
|
60
60
|
ddog_Error_drop(error);
|
61
61
|
return error_msg_size;
|
62
62
|
}
|
63
|
+
|
64
|
+
ddog_prof_ManagedStringId intern_or_raise(ddog_prof_ManagedStringStorage string_storage, ddog_CharSlice string) {
|
65
|
+
if (string.len == 0) return (ddog_prof_ManagedStringId) { 0 }; // Id 0 is always an empty string, no need to ask
|
66
|
+
|
67
|
+
ddog_prof_ManagedStringStorageInternResult intern_result = ddog_prof_ManagedStringStorage_intern(string_storage, string);
|
68
|
+
if (intern_result.tag == DDOG_PROF_MANAGED_STRING_STORAGE_INTERN_RESULT_ERR) {
|
69
|
+
rb_raise(rb_eRuntimeError, "Failed to intern string: %"PRIsVALUE, get_error_details_and_drop(&intern_result.err));
|
70
|
+
}
|
71
|
+
return intern_result.ok;
|
72
|
+
}
|
73
|
+
|
74
|
+
void intern_all_or_raise(
|
75
|
+
ddog_prof_ManagedStringStorage string_storage,
|
76
|
+
ddog_prof_Slice_CharSlice strings,
|
77
|
+
ddog_prof_ManagedStringId *output_ids,
|
78
|
+
uintptr_t output_ids_size
|
79
|
+
) {
|
80
|
+
ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_intern_all(string_storage, strings, output_ids, output_ids_size);
|
81
|
+
if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
|
82
|
+
rb_raise(rb_eRuntimeError, "Failed to intern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
|
83
|
+
}
|
84
|
+
}
|
@@ -18,8 +18,11 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
|
|
18
18
|
const char *ruby_value_type_to_string(enum ruby_value_type type);
|
19
19
|
ddog_CharSlice ruby_value_type_to_char_slice(enum ruby_value_type type);
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
ddog_prof_ManagedStringId intern_or_raise(ddog_prof_ManagedStringStorage string_storage, ddog_CharSlice string);
|
22
|
+
|
23
|
+
void intern_all_or_raise(
|
24
|
+
ddog_prof_ManagedStringStorage string_storage,
|
25
|
+
ddog_prof_Slice_CharSlice strings,
|
26
|
+
ddog_prof_ManagedStringId *output_ids,
|
27
|
+
uintptr_t output_ids_size
|
28
|
+
);
|
@@ -569,6 +569,7 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *st
|
|
569
569
|
|
570
570
|
stack_buffer[i].as.native_frame.caching_cme = (VALUE)cme;
|
571
571
|
stack_buffer[i].as.native_frame.method_id = cme->def->original_id;
|
572
|
+
stack_buffer[i].as.native_frame.function = cme->def->body.cfunc.func;
|
572
573
|
stack_buffer[i].is_ruby_frame = false;
|
573
574
|
i++;
|
574
575
|
}
|
@@ -18,16 +18,19 @@ typedef struct {
|
|
18
18
|
rb_nativethread_id_t owner;
|
19
19
|
} current_gvl_owner;
|
20
20
|
|
21
|
+
// If a sample is kept around for later use, some of its fields need marking. Remember to
|
22
|
+
// update the marking code in `sampling_buffer_mark` if new fields are added.
|
21
23
|
typedef struct {
|
22
24
|
union {
|
23
25
|
struct {
|
24
|
-
VALUE iseq;
|
25
|
-
void *caching_pc; // For caching only
|
26
|
+
VALUE iseq; // Needs marking if kept around
|
27
|
+
void *caching_pc; // For caching validation/invalidation only (does not need marking)
|
26
28
|
int line;
|
27
29
|
} ruby_frame;
|
28
30
|
struct {
|
29
|
-
VALUE caching_cme; // For caching only
|
31
|
+
VALUE caching_cme; // For caching validation/invalidation only (does not need marking)
|
30
32
|
ID method_id;
|
33
|
+
void *function;
|
31
34
|
} native_frame;
|
32
35
|
} as;
|
33
36
|
bool is_ruby_frame : 1;
|
@@ -103,16 +103,6 @@ void raise_syserr(
|
|
103
103
|
}
|
104
104
|
}
|
105
105
|
|
106
|
-
char* ruby_strndup(const char *str, size_t size) {
|
107
|
-
char *dup;
|
108
|
-
|
109
|
-
dup = xmalloc(size + 1);
|
110
|
-
memcpy(dup, str, size);
|
111
|
-
dup[size] = '\0';
|
112
|
-
|
113
|
-
return dup;
|
114
|
-
}
|
115
|
-
|
116
106
|
static VALUE _id2ref(VALUE obj_id) {
|
117
107
|
// Call ::ObjectSpace._id2ref natively. It will raise if the id is no longer valid
|
118
108
|
return rb_funcall(module_object_space, _id2ref_id, 1, obj_id);
|
@@ -122,9 +112,7 @@ static VALUE _id2ref_failure(DDTRACE_UNUSED VALUE _unused1, DDTRACE_UNUSED VALUE
|
|
122
112
|
return Qfalse;
|
123
113
|
}
|
124
114
|
|
125
|
-
//
|
126
|
-
// writes the ref to the value pointer parameter if !NULL. False if id doesn't
|
127
|
-
// reference a valid object (in which case value is not changed).
|
115
|
+
// See notes on header for important details
|
128
116
|
bool ruby_ref_from_id(VALUE obj_id, VALUE *value) {
|
129
117
|
// Call ::ObjectSpace._id2ref natively. It will raise if the id is no longer valid
|
130
118
|
// so we need to call it via rb_rescue2
|
@@ -67,19 +67,11 @@ NORETURN(void raise_syserr(
|
|
67
67
|
const char *function_name
|
68
68
|
));
|
69
69
|
|
70
|
-
// Alternative to ruby_strdup that takes a size argument.
|
71
|
-
// Similar to C's strndup but slightly less smart as size is expected to
|
72
|
-
// be smaller or equal to the real size of str (minus null termination if it
|
73
|
-
// exists).
|
74
|
-
// A new string will be returned with size+1 bytes and last byte set to '\0'.
|
75
|
-
// The returned string must be freed explicitly.
|
76
|
-
//
|
77
|
-
// WARN: Cannot be used during GC or outside the GVL.
|
78
|
-
char* ruby_strndup(const char *str, size_t size);
|
79
|
-
|
80
70
|
// Native wrapper to get an object ref from an id. Returns true on success and
|
81
71
|
// writes the ref to the value pointer parameter if !NULL. False if id doesn't
|
82
72
|
// reference a valid object (in which case value is not changed).
|
73
|
+
//
|
74
|
+
// Note: GVL can be released and other threads may get to run before this method returns
|
83
75
|
bool ruby_ref_from_id(size_t id, VALUE *value);
|
84
76
|
|
85
77
|
// Native wrapper to get the approximate/estimated current size of the passed
|