datadog 2.2.0 → 2.4.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 +87 -2
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +9 -1
- data/ext/datadog_profiling_loader/extconf.rb +14 -26
- data/ext/datadog_profiling_native_extension/clock_id.h +1 -0
- data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +1 -2
- data/ext/datadog_profiling_native_extension/clock_id_noop.c +1 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +257 -69
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +53 -28
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +34 -4
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +4 -0
- data/ext/datadog_profiling_native_extension/collectors_stack.c +136 -81
- data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +661 -48
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +10 -1
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +83 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +53 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +91 -69
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +50 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +75 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +54 -12
- data/ext/datadog_profiling_native_extension/heap_recorder.h +3 -1
- data/ext/datadog_profiling_native_extension/helpers.h +6 -17
- data/ext/datadog_profiling_native_extension/http_transport.c +41 -9
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +0 -86
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +2 -23
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +61 -172
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +116 -139
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +20 -11
- data/ext/datadog_profiling_native_extension/profiling.c +1 -3
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +0 -33
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +1 -26
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +14 -2
- data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -0
- data/ext/datadog_profiling_native_extension/time_helpers.c +0 -15
- data/ext/datadog_profiling_native_extension/time_helpers.h +36 -6
- data/ext/{datadog_profiling_native_extension → libdatadog_api}/crashtracker.c +37 -22
- data/ext/libdatadog_api/datadog_ruby_common.c +83 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +53 -0
- data/ext/libdatadog_api/extconf.rb +108 -0
- data/ext/libdatadog_api/macos_development.md +26 -0
- data/ext/libdatadog_extconf_helpers.rb +130 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +2184 -108
- data/lib/datadog/appsec/assets/waf_rules/strict.json +1430 -2
- data/lib/datadog/appsec/component.rb +29 -8
- data/lib/datadog/appsec/configuration/settings.rb +2 -2
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +1 -0
- data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +21 -0
- data/lib/datadog/appsec/contrib/devise/patcher.rb +12 -2
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +35 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +109 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +71 -0
- data/lib/datadog/appsec/contrib/graphql/integration.rb +54 -0
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +37 -0
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +59 -0
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +3 -6
- data/lib/datadog/appsec/event.rb +1 -1
- data/lib/datadog/appsec/processor/actions.rb +1 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +3 -1
- data/lib/datadog/appsec/processor/rule_merger.rb +33 -15
- data/lib/datadog/appsec/processor.rb +36 -37
- data/lib/datadog/appsec/rate_limiter.rb +25 -40
- data/lib/datadog/appsec/remote.rb +7 -3
- data/lib/datadog/appsec/response.rb +15 -1
- data/lib/datadog/appsec.rb +3 -2
- data/lib/datadog/core/configuration/components.rb +18 -15
- data/lib/datadog/core/configuration/settings.rb +135 -9
- data/lib/datadog/core/crashtracking/agent_base_url.rb +21 -0
- data/lib/datadog/core/crashtracking/component.rb +111 -0
- data/lib/datadog/core/crashtracking/tag_builder.rb +39 -0
- data/lib/datadog/core/diagnostics/environment_logger.rb +8 -11
- data/lib/datadog/core/environment/execution.rb +5 -5
- data/lib/datadog/core/metrics/client.rb +7 -0
- data/lib/datadog/core/rate_limiter.rb +183 -0
- data/lib/datadog/core/remote/client/capabilities.rb +4 -3
- data/lib/datadog/core/remote/component.rb +4 -2
- data/lib/datadog/core/remote/negotiation.rb +4 -4
- data/lib/datadog/core/remote/tie.rb +2 -0
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/component.rb +51 -2
- data/lib/datadog/core/telemetry/emitter.rb +9 -11
- data/lib/datadog/core/telemetry/event.rb +37 -1
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +10 -12
- data/lib/datadog/core/telemetry/http/ext.rb +3 -0
- data/lib/datadog/core/telemetry/http/transport.rb +38 -9
- data/lib/datadog/core/telemetry/logger.rb +51 -0
- data/lib/datadog/core/telemetry/logging.rb +71 -0
- data/lib/datadog/core/telemetry/request.rb +13 -1
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +102 -0
- data/lib/datadog/core/utils/time.rb +12 -0
- data/lib/datadog/di/code_tracker.rb +168 -0
- data/lib/datadog/di/configuration/settings.rb +163 -0
- data/lib/datadog/di/configuration.rb +11 -0
- data/lib/datadog/di/error.rb +31 -0
- data/lib/datadog/di/extensions.rb +16 -0
- data/lib/datadog/di/probe.rb +133 -0
- data/lib/datadog/di/probe_builder.rb +41 -0
- data/lib/datadog/di/redactor.rb +188 -0
- data/lib/datadog/di/serializer.rb +193 -0
- data/lib/datadog/di.rb +14 -0
- data/lib/datadog/kit/appsec/events.rb +2 -4
- data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +10 -0
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +23 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +7 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +28 -26
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +11 -13
- data/lib/datadog/profiling/collectors/info.rb +15 -6
- data/lib/datadog/profiling/collectors/thread_context.rb +30 -2
- data/lib/datadog/profiling/component.rb +89 -95
- data/lib/datadog/profiling/exporter.rb +3 -3
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +3 -3
- data/lib/datadog/profiling/ext.rb +21 -21
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +14 -7
- data/lib/datadog/profiling/load_native_extension.rb +5 -5
- data/lib/datadog/profiling/preload.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +5 -8
- data/lib/datadog/profiling/scheduler.rb +33 -25
- data/lib/datadog/profiling/stack_recorder.rb +3 -0
- data/lib/datadog/profiling/tag_builder.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +5 -5
- data/lib/datadog/profiling/tasks/setup.rb +16 -35
- data/lib/datadog/profiling.rb +4 -5
- data/lib/datadog/single_step_instrument.rb +12 -0
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -12
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +78 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +33 -0
- data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -0
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +4 -0
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +3 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +5 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/ext.rb +14 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +9 -0
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +19 -0
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +9 -12
- data/lib/datadog/tracing/contrib/graphql/trace_patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/tracing_patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +14 -10
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +10 -4
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +18 -15
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -5
- data/lib/datadog/tracing/contrib/httpclient/patcher.rb +1 -14
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/httprb/patcher.rb +1 -14
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +15 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +17 -13
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
- data/lib/datadog/tracing/contrib/patcher.rb +2 -1
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +4 -1
- data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +28 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +5 -1
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +22 -10
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +27 -0
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -0
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +4 -0
- data/lib/datadog/tracing/contrib/stripe/request.rb +3 -2
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -1
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +14 -16
- data/lib/datadog/tracing/distributed/propagation.rb +7 -0
- data/lib/datadog/tracing/metadata/errors.rb +9 -1
- data/lib/datadog/tracing/metadata/ext.rb +6 -0
- data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
- data/lib/datadog/tracing/remote.rb +5 -2
- data/lib/datadog/tracing/sampling/matcher.rb +6 -1
- data/lib/datadog/tracing/sampling/rate_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/rule.rb +2 -0
- data/lib/datadog/tracing/sampling/rule_sampler.rb +9 -5
- data/lib/datadog/tracing/sampling/span/ext.rb +1 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +2 -2
- data/lib/datadog/tracing/span.rb +9 -2
- data/lib/datadog/tracing/span_event.rb +41 -0
- data/lib/datadog/tracing/span_operation.rb +6 -2
- data/lib/datadog/tracing/trace_operation.rb +26 -2
- data/lib/datadog/tracing/tracer.rb +14 -12
- data/lib/datadog/tracing/transport/http/client.rb +1 -0
- data/lib/datadog/tracing/transport/io/client.rb +1 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -0
- data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
- data/lib/datadog/tracing/workers.rb +1 -1
- data/lib/datadog/version.rb +1 -1
- metadata +46 -11
- data/lib/datadog/profiling/crashtracker.rb +0 -91
- data/lib/datadog/profiling/ext/forking.rb +0 -98
- data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
@@ -166,6 +166,12 @@ struct heap_recorder {
|
|
166
166
|
size_t objects_frozen;
|
167
167
|
} stats_last_update;
|
168
168
|
};
|
169
|
+
|
170
|
+
struct end_heap_allocation_args {
|
171
|
+
struct heap_recorder *heap_recorder;
|
172
|
+
ddog_prof_Slice_Location locations;
|
173
|
+
};
|
174
|
+
|
169
175
|
static heap_record* get_or_create_heap_record(heap_recorder*, ddog_prof_Slice_Location);
|
170
176
|
static void cleanup_heap_record_if_unused(heap_recorder*, heap_record*);
|
171
177
|
static void on_committed_object_record_cleanup(heap_recorder *heap_recorder, object_record *record);
|
@@ -176,6 +182,7 @@ static int st_object_records_iterate(st_data_t, st_data_t, st_data_t);
|
|
176
182
|
static int st_object_records_debug(st_data_t key, st_data_t value, st_data_t extra);
|
177
183
|
static int update_object_record_entry(st_data_t*, st_data_t*, st_data_t, int);
|
178
184
|
static void commit_recording(heap_recorder*, heap_record*, recording);
|
185
|
+
static VALUE end_heap_allocation_recording(VALUE end_heap_allocation_args);
|
179
186
|
|
180
187
|
// ==========================
|
181
188
|
// Heap Recorder External API
|
@@ -219,7 +226,7 @@ void heap_recorder_free(heap_recorder *heap_recorder) {
|
|
219
226
|
st_foreach(heap_recorder->heap_records, st_heap_record_entry_free, 0);
|
220
227
|
st_free_table(heap_recorder->heap_records);
|
221
228
|
|
222
|
-
if (heap_recorder->active_recording.object_record != NULL) {
|
229
|
+
if (heap_recorder->active_recording.object_record != NULL && heap_recorder->active_recording.object_record != &SKIPPED_RECORD) {
|
223
230
|
// If there's a partial object record, clean it up as well
|
224
231
|
object_record_free(heap_recorder->active_recording.object_record);
|
225
232
|
}
|
@@ -340,9 +347,28 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
|
|
340
347
|
};
|
341
348
|
}
|
342
349
|
|
343
|
-
|
350
|
+
// end_heap_allocation_recording_with_rb_protect gets called while the stack_recorder is holding one of the profile
|
351
|
+
// locks. To enable us to correctly unlock the profile on exception, we wrap the call to end_heap_allocation_recording
|
352
|
+
// with an rb_protect.
|
353
|
+
__attribute__((warn_unused_result))
|
354
|
+
int end_heap_allocation_recording_with_rb_protect(struct heap_recorder *heap_recorder, ddog_prof_Slice_Location locations) {
|
355
|
+
int exception_state;
|
356
|
+
struct end_heap_allocation_args end_heap_allocation_args = {
|
357
|
+
.heap_recorder = heap_recorder,
|
358
|
+
.locations = locations,
|
359
|
+
};
|
360
|
+
rb_protect(end_heap_allocation_recording, (VALUE) &end_heap_allocation_args, &exception_state);
|
361
|
+
return exception_state;
|
362
|
+
}
|
363
|
+
|
364
|
+
static VALUE end_heap_allocation_recording(VALUE end_heap_allocation_args) {
|
365
|
+
struct end_heap_allocation_args *args = (struct end_heap_allocation_args *) end_heap_allocation_args;
|
366
|
+
|
367
|
+
struct heap_recorder *heap_recorder = args->heap_recorder;
|
368
|
+
ddog_prof_Slice_Location locations = args->locations;
|
369
|
+
|
344
370
|
if (heap_recorder == NULL) {
|
345
|
-
return;
|
371
|
+
return Qnil;
|
346
372
|
}
|
347
373
|
|
348
374
|
recording active_recording = heap_recorder->active_recording;
|
@@ -356,15 +382,16 @@ void end_heap_allocation_recording(struct heap_recorder *heap_recorder, ddog_pro
|
|
356
382
|
// data required for committing though.
|
357
383
|
heap_recorder->active_recording = (recording) {0};
|
358
384
|
|
359
|
-
if (active_recording.object_record == &SKIPPED_RECORD) {
|
360
|
-
|
361
|
-
return;
|
385
|
+
if (active_recording.object_record == &SKIPPED_RECORD) { // special marker when we decided to skip due to sampling
|
386
|
+
return Qnil;
|
362
387
|
}
|
363
388
|
|
364
389
|
heap_record *heap_record = get_or_create_heap_record(heap_recorder, locations);
|
365
390
|
|
366
391
|
// And then commit the new allocation.
|
367
392
|
commit_recording(heap_recorder, heap_record, active_recording);
|
393
|
+
|
394
|
+
return Qnil;
|
368
395
|
}
|
369
396
|
|
370
397
|
void heap_recorder_prepare_iteration(heap_recorder *heap_recorder) {
|
@@ -605,12 +632,14 @@ static int st_object_records_iterate(DDTRACE_UNUSED st_data_t key, st_data_t val
|
|
605
632
|
ddog_prof_Location *locations = recorder->reusable_locations;
|
606
633
|
for (uint16_t i = 0; i < stack->frames_len; i++) {
|
607
634
|
const heap_frame *frame = &stack->frames[i];
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
635
|
+
locations[i] = (ddog_prof_Location) {
|
636
|
+
.mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C("")},
|
637
|
+
.function = {
|
638
|
+
.name = {.ptr = frame->name, .len = strlen(frame->name)},
|
639
|
+
.filename = {.ptr = frame->filename, .len = strlen(frame->filename)},
|
640
|
+
},
|
641
|
+
.line = frame->line,
|
642
|
+
};
|
614
643
|
}
|
615
644
|
|
616
645
|
heap_recorder_iteration_data iteration_data;
|
@@ -755,8 +784,20 @@ static void cleanup_heap_record_if_unused(heap_recorder *heap_recorder, heap_rec
|
|
755
784
|
}
|
756
785
|
|
757
786
|
static void on_committed_object_record_cleanup(heap_recorder *heap_recorder, object_record *record) {
|
787
|
+
// @ivoanjo: We've seen a segfault crash in the field in this function (October 2024) which we're still trying to investigate.
|
788
|
+
// (See PROF-10656 Datadog-internal for details). Just in case, I've sprinkled a bunch of NULL tests in this function for now.
|
789
|
+
// Once we figure out the issue we can get rid of them again.
|
790
|
+
|
791
|
+
if (heap_recorder == NULL) rb_raise(rb_eRuntimeError, "heap_recorder was NULL in on_committed_object_record_cleanup");
|
792
|
+
if (heap_recorder->heap_records == NULL) rb_raise(rb_eRuntimeError, "heap_recorder->heap_records was NULL in on_committed_object_record_cleanup");
|
793
|
+
if (record == NULL) rb_raise(rb_eRuntimeError, "record was NULL in on_committed_object_record_cleanup");
|
794
|
+
|
758
795
|
// Starting with the associated heap record. There will now be one less tracked object pointing to it
|
759
796
|
heap_record *heap_record = record->heap_record;
|
797
|
+
|
798
|
+
if (heap_record == NULL) rb_raise(rb_eRuntimeError, "heap_record was NULL in on_committed_object_record_cleanup");
|
799
|
+
if (heap_record->stack == NULL) rb_raise(rb_eRuntimeError, "heap_record->stack was NULL in on_committed_object_record_cleanup");
|
800
|
+
|
760
801
|
heap_record->num_tracked_objects--;
|
761
802
|
|
762
803
|
// One less object using this heap record, it may have become unused...
|
@@ -815,6 +856,7 @@ VALUE object_record_inspect(object_record *record) {
|
|
815
856
|
if (!ruby_ref_from_id(LONG2NUM(record->obj_id), &ref)) {
|
816
857
|
rb_str_catf(inspect, "object=<invalid>");
|
817
858
|
} else {
|
859
|
+
rb_str_catf(inspect, "value=%p ", (void *) ref);
|
818
860
|
VALUE ruby_inspect = ruby_safe_inspect(ref);
|
819
861
|
if (ruby_inspect != Qnil) {
|
820
862
|
rb_str_catf(inspect, "object=%"PRIsVALUE, ruby_inspect);
|
@@ -114,7 +114,9 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
|
|
114
114
|
// @param locations The stacktrace representing the location of the allocation.
|
115
115
|
//
|
116
116
|
// WARN: It is illegal to call this without previously having called ::start_heap_allocation_recording.
|
117
|
-
|
117
|
+
// WARN: This method rescues exceptions with `rb_protect`, returning the exception state integer for the caller to handle.
|
118
|
+
__attribute__((warn_unused_result))
|
119
|
+
int end_heap_allocation_recording_with_rb_protect(heap_recorder *heap_recorder, ddog_prof_Slice_Location locations);
|
118
120
|
|
119
121
|
// Update the heap recorder to reflect the latest state of the VM and prepare internal structures
|
120
122
|
// for efficient iteration.
|
@@ -2,22 +2,11 @@
|
|
2
2
|
|
3
3
|
#include <stdint.h>
|
4
4
|
|
5
|
-
// Used to mark symbols to be exported to the outside of the extension.
|
6
|
-
// Consider very carefully before tagging a function with this.
|
7
|
-
#define DDTRACE_EXPORT __attribute__ ((visibility ("default")))
|
8
|
-
|
9
|
-
// Used to mark function arguments that are deliberately left unused
|
10
|
-
#ifdef __GNUC__
|
11
|
-
#define DDTRACE_UNUSED __attribute__((unused))
|
12
|
-
#else
|
13
|
-
#define DDTRACE_UNUSED
|
14
|
-
#endif
|
15
|
-
|
16
5
|
// @ivoanjo: After trying to read through https://stackoverflow.com/questions/3437404/min-and-max-in-c I decided I
|
17
6
|
// don't like C and I just implemented this as a function.
|
18
|
-
inline
|
19
|
-
inline
|
20
|
-
inline
|
21
|
-
inline
|
22
|
-
inline
|
23
|
-
inline
|
7
|
+
static inline uint64_t uint64_max_of(uint64_t a, uint64_t b) { return a > b ? a : b; }
|
8
|
+
static inline uint64_t uint64_min_of(uint64_t a, uint64_t b) { return a > b ? b : a; }
|
9
|
+
static inline long long_max_of(long a, long b) { return a > b ? a : b; }
|
10
|
+
static inline long long_min_of(long a, long b) { return a > b ? b : a; }
|
11
|
+
static inline double double_max_of(double a, double b) { return a > b ? a : b; }
|
12
|
+
static inline double double_min_of(double a, double b) { return a > b ? b : a; }
|
@@ -21,7 +21,7 @@ struct call_exporter_without_gvl_arguments {
|
|
21
21
|
bool send_ran;
|
22
22
|
};
|
23
23
|
|
24
|
-
inline
|
24
|
+
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
|
25
25
|
static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
|
26
26
|
static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
|
27
27
|
static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_result);
|
@@ -53,11 +53,11 @@ void http_transport_init(VALUE profiling_module) {
|
|
53
53
|
ok_symbol = ID2SYM(rb_intern_const("ok"));
|
54
54
|
error_symbol = ID2SYM(rb_intern_const("error"));
|
55
55
|
|
56
|
-
library_version_string =
|
56
|
+
library_version_string = datadog_gem_version();
|
57
57
|
rb_global_variable(&library_version_string);
|
58
58
|
}
|
59
59
|
|
60
|
-
inline
|
60
|
+
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
|
61
61
|
ENFORCE_TYPE(string, T_STRING);
|
62
62
|
ddog_ByteSlice byte_slice = {.ptr = (uint8_t *) StringValuePtr(string), .len = RSTRING_LEN(string)};
|
63
63
|
return byte_slice;
|
@@ -77,6 +77,32 @@ static VALUE _native_validate_exporter(DDTRACE_UNUSED VALUE _self, VALUE exporte
|
|
77
77
|
return rb_ary_new_from_args(2, ok_symbol, Qnil);
|
78
78
|
}
|
79
79
|
|
80
|
+
static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
|
81
|
+
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
82
|
+
|
83
|
+
VALUE exporter_working_mode = rb_ary_entry(exporter_configuration, 0);
|
84
|
+
ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
|
85
|
+
ID working_mode = SYM2ID(exporter_working_mode);
|
86
|
+
|
87
|
+
ID agentless_id = rb_intern("agentless");
|
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) {
|
95
|
+
VALUE site = rb_ary_entry(exporter_configuration, 1);
|
96
|
+
VALUE api_key = rb_ary_entry(exporter_configuration, 2);
|
97
|
+
|
98
|
+
return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
|
99
|
+
} else { // agent_id
|
100
|
+
VALUE base_url = rb_ary_entry(exporter_configuration, 1);
|
101
|
+
|
102
|
+
return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
80
106
|
static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration, VALUE tags_as_array) {
|
81
107
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
82
108
|
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
@@ -115,8 +141,7 @@ static VALUE perform_export(
|
|
115
141
|
ddog_prof_Exporter_Slice_File files_to_export_unmodified,
|
116
142
|
ddog_Vec_Tag *additional_tags,
|
117
143
|
ddog_CharSlice internal_metadata,
|
118
|
-
ddog_CharSlice info
|
119
|
-
uint64_t timeout_milliseconds
|
144
|
+
ddog_CharSlice info
|
120
145
|
) {
|
121
146
|
ddog_prof_ProfiledEndpointsStats *endpoints_stats = NULL; // Not in use yet
|
122
147
|
ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
|
@@ -128,8 +153,7 @@ static VALUE perform_export(
|
|
128
153
|
additional_tags,
|
129
154
|
endpoints_stats,
|
130
155
|
&internal_metadata,
|
131
|
-
&info
|
132
|
-
timeout_milliseconds
|
156
|
+
&info
|
133
157
|
);
|
134
158
|
|
135
159
|
if (build_result.tag == DDOG_PROF_EXPORTER_REQUEST_BUILD_RESULT_ERR) {
|
@@ -254,6 +278,15 @@ static VALUE _native_do_export(
|
|
254
278
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
255
279
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
256
280
|
|
281
|
+
ddog_prof_MaybeError timeout_result = ddog_prof_Exporter_set_timeout(exporter_result.ok, timeout_milliseconds);
|
282
|
+
if (timeout_result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
|
283
|
+
// NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
|
284
|
+
// if the exporter is not well built. Because such a situation should already be caught above I think it's
|
285
|
+
// 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.some));
|
288
|
+
}
|
289
|
+
|
257
290
|
return perform_export(
|
258
291
|
exporter_result.ok,
|
259
292
|
start,
|
@@ -262,8 +295,7 @@ static VALUE _native_do_export(
|
|
262
295
|
files_to_export_unmodified,
|
263
296
|
null_additional_tags,
|
264
297
|
internal_metadata,
|
265
|
-
info
|
266
|
-
timeout_milliseconds
|
298
|
+
info
|
267
299
|
);
|
268
300
|
}
|
269
301
|
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
#include <ruby.h>
|
4
4
|
|
5
|
-
static VALUE log_failure_to_process_tag(VALUE err_details);
|
6
|
-
|
7
5
|
const char *ruby_value_type_to_string(enum ruby_value_type type) {
|
8
6
|
return ruby_value_type_to_char_slice(type).ptr;
|
9
7
|
}
|
@@ -62,87 +60,3 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
|
|
62
60
|
ddog_Error_drop(error);
|
63
61
|
return error_msg_size;
|
64
62
|
}
|
65
|
-
|
66
|
-
__attribute__((warn_unused_result))
|
67
|
-
ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
|
68
|
-
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
69
|
-
|
70
|
-
VALUE exporter_working_mode = rb_ary_entry(exporter_configuration, 0);
|
71
|
-
ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
|
72
|
-
ID working_mode = SYM2ID(exporter_working_mode);
|
73
|
-
|
74
|
-
ID agentless_id = rb_intern("agentless");
|
75
|
-
ID agent_id = rb_intern("agent");
|
76
|
-
|
77
|
-
if (working_mode != agentless_id && working_mode != agent_id) {
|
78
|
-
rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
|
79
|
-
}
|
80
|
-
|
81
|
-
if (working_mode == agentless_id) {
|
82
|
-
VALUE site = rb_ary_entry(exporter_configuration, 1);
|
83
|
-
VALUE api_key = rb_ary_entry(exporter_configuration, 2);
|
84
|
-
ENFORCE_TYPE(site, T_STRING);
|
85
|
-
ENFORCE_TYPE(api_key, T_STRING);
|
86
|
-
|
87
|
-
return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
|
88
|
-
} else { // agent_id
|
89
|
-
VALUE base_url = rb_ary_entry(exporter_configuration, 1);
|
90
|
-
ENFORCE_TYPE(base_url, T_STRING);
|
91
|
-
|
92
|
-
return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
|
93
|
-
}
|
94
|
-
}
|
95
|
-
|
96
|
-
__attribute__((warn_unused_result))
|
97
|
-
ddog_Vec_Tag convert_tags(VALUE tags_as_array) {
|
98
|
-
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
99
|
-
|
100
|
-
long tags_count = RARRAY_LEN(tags_as_array);
|
101
|
-
ddog_Vec_Tag tags = ddog_Vec_Tag_new();
|
102
|
-
|
103
|
-
for (long i = 0; i < tags_count; i++) {
|
104
|
-
VALUE name_value_pair = rb_ary_entry(tags_as_array, i);
|
105
|
-
|
106
|
-
if (!RB_TYPE_P(name_value_pair, T_ARRAY)) {
|
107
|
-
ddog_Vec_Tag_drop(tags);
|
108
|
-
ENFORCE_TYPE(name_value_pair, T_ARRAY);
|
109
|
-
}
|
110
|
-
|
111
|
-
// Note: We can index the array without checking its size first because rb_ary_entry returns Qnil if out of bounds
|
112
|
-
VALUE tag_name = rb_ary_entry(name_value_pair, 0);
|
113
|
-
VALUE tag_value = rb_ary_entry(name_value_pair, 1);
|
114
|
-
|
115
|
-
if (!(RB_TYPE_P(tag_name, T_STRING) && RB_TYPE_P(tag_value, T_STRING))) {
|
116
|
-
ddog_Vec_Tag_drop(tags);
|
117
|
-
ENFORCE_TYPE(tag_name, T_STRING);
|
118
|
-
ENFORCE_TYPE(tag_value, T_STRING);
|
119
|
-
}
|
120
|
-
|
121
|
-
ddog_Vec_Tag_PushResult push_result =
|
122
|
-
ddog_Vec_Tag_push(&tags, char_slice_from_ruby_string(tag_name), char_slice_from_ruby_string(tag_value));
|
123
|
-
|
124
|
-
if (push_result.tag == DDOG_VEC_TAG_PUSH_RESULT_ERR) {
|
125
|
-
// libdatadog validates tags and may catch invalid tags that ddtrace didn't actually catch.
|
126
|
-
// We warn users about such tags, and then just ignore them.
|
127
|
-
|
128
|
-
int exception_state;
|
129
|
-
rb_protect(log_failure_to_process_tag, get_error_details_and_drop(&push_result.err), &exception_state);
|
130
|
-
|
131
|
-
// Since we are calling into Ruby code, it may raise an exception. Ensure that dynamically-allocated tags
|
132
|
-
// get cleaned before propagating the exception.
|
133
|
-
if (exception_state) {
|
134
|
-
ddog_Vec_Tag_drop(tags);
|
135
|
-
rb_jump_tag(exception_state); // "Re-raise" exception
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
return tags;
|
141
|
-
}
|
142
|
-
|
143
|
-
static VALUE log_failure_to_process_tag(VALUE err_details) {
|
144
|
-
VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
|
145
|
-
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
146
|
-
|
147
|
-
return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to add tag to profiling request: %"PRIsVALUE, err_details));
|
148
|
-
}
|
@@ -3,27 +3,10 @@
|
|
3
3
|
#include <datadog/profiling.h>
|
4
4
|
#include "ruby_helpers.h"
|
5
5
|
|
6
|
-
|
7
|
-
ENFORCE_TYPE(string, T_STRING);
|
8
|
-
ddog_CharSlice char_slice = {.ptr = StringValuePtr(string), .len = RSTRING_LEN(string)};
|
9
|
-
return char_slice;
|
10
|
-
}
|
11
|
-
|
12
|
-
inline static VALUE ruby_string_from_vec_u8(ddog_Vec_U8 string) {
|
6
|
+
static inline VALUE ruby_string_from_vec_u8(ddog_Vec_U8 string) {
|
13
7
|
return rb_str_new((char *) string.ptr, string.len);
|
14
8
|
}
|
15
9
|
|
16
|
-
inline static VALUE ruby_string_from_error(const ddog_Error *error) {
|
17
|
-
ddog_CharSlice char_slice = ddog_Error_message(error);
|
18
|
-
return rb_str_new(char_slice.ptr, char_slice.len);
|
19
|
-
}
|
20
|
-
|
21
|
-
inline static VALUE get_error_details_and_drop(ddog_Error *error) {
|
22
|
-
VALUE result = ruby_string_from_error(error);
|
23
|
-
ddog_Error_drop(error);
|
24
|
-
return result;
|
25
|
-
}
|
26
|
-
|
27
10
|
// Utility function to be able to extract an error cstring from a ddog_Error.
|
28
11
|
// Returns the amount of characters written to string (which are necessarily
|
29
12
|
// bounded by capacity - 1 since the string will be null-terminated).
|
@@ -37,10 +20,6 @@ ddog_CharSlice ruby_value_type_to_char_slice(enum ruby_value_type type);
|
|
37
20
|
|
38
21
|
// Returns a dynamically allocated string from the provided char slice.
|
39
22
|
// WARN: The returned string must be explicitly freed with ruby_xfree.
|
40
|
-
inline
|
23
|
+
static inline char* string_from_char_slice(ddog_CharSlice slice) {
|
41
24
|
return ruby_strndup(slice.ptr, slice.len);
|
42
25
|
}
|
43
|
-
|
44
|
-
ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration);
|
45
|
-
|
46
|
-
ddog_Vec_Tag convert_tags(VALUE tags_as_array);
|