ddtrace 1.4.1 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +144 -1
- data/LICENSE-3rdparty.csv +1 -0
- data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +9 -2
- data/ext/ddtrace_profiling_loader/extconf.rb +17 -0
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +38 -2
- data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -0
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +517 -42
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +3 -0
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +208 -30
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +156 -46
- data/ext/ddtrace_profiling_native_extension/collectors_stack.h +11 -2
- data/ext/ddtrace_profiling_native_extension/extconf.rb +11 -1
- data/ext/ddtrace_profiling_native_extension/http_transport.c +83 -64
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +4 -4
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +3 -4
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +59 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +10 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -1
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +4 -2
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +45 -29
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +7 -7
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +1169 -275
- data/lib/datadog/appsec/assets/waf_rules/risky.json +78 -78
- data/lib/datadog/appsec/assets/waf_rules/strict.json +278 -88
- data/lib/datadog/appsec/configuration/settings.rb +0 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -20
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/request.rb +3 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +46 -19
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -6
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +11 -11
- data/lib/datadog/appsec/contrib/rails/request.rb +3 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -12
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +11 -11
- data/lib/datadog/appsec/event.rb +6 -10
- data/lib/datadog/appsec/instrumentation/gateway.rb +16 -2
- data/lib/datadog/appsec/processor.rb +18 -2
- data/lib/datadog/ci/ext/environment.rb +16 -4
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +0 -3
- data/lib/datadog/core/configuration/components.rb +28 -16
- data/lib/datadog/core/configuration/settings.rb +127 -8
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
- data/lib/datadog/core/header_collection.rb +41 -0
- data/lib/datadog/core/telemetry/collector.rb +0 -2
- data/lib/datadog/core/utils/compression.rb +5 -1
- data/lib/datadog/core/workers/async.rb +0 -2
- data/lib/datadog/core.rb +0 -54
- data/lib/datadog/opentracer/tracer.rb +4 -6
- data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +12 -2
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -3
- data/lib/datadog/profiling/collectors/old_stack.rb +1 -1
- data/lib/datadog/profiling/exporter.rb +2 -4
- data/lib/datadog/profiling/http_transport.rb +1 -1
- data/lib/datadog/profiling.rb +1 -1
- data/lib/datadog/tracing/client_ip.rb +164 -0
- data/lib/datadog/tracing/configuration/ext.rb +14 -0
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/aws/services.rb +0 -2
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -0
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +2 -0
- data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -0
- data/lib/datadog/tracing/contrib/ext.rb +25 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +0 -2
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -0
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +47 -0
- data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +22 -0
- data/lib/datadog/tracing/contrib/hanami/ext.rb +24 -0
- data/lib/datadog/tracing/contrib/hanami/integration.rb +44 -0
- data/lib/datadog/tracing/contrib/hanami/patcher.rb +33 -0
- data/lib/datadog/tracing/contrib/hanami/plugin.rb +23 -0
- data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +41 -0
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +44 -0
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +7 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +12 -0
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -0
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +12 -0
- data/lib/datadog/tracing/contrib/pg/ext.rb +2 -1
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +38 -21
- data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +43 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +32 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +28 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +49 -0
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +35 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +105 -43
- data/lib/datadog/tracing/contrib/redis/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
- data/lib/datadog/tracing/contrib/redis/patcher.rb +40 -0
- data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +2 -0
- data/lib/datadog/tracing/contrib/sinatra/env.rb +12 -23
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +7 -3
- data/lib/datadog/tracing/contrib/sinatra/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +8 -80
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +14 -9
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +92 -10
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +84 -0
- data/lib/datadog/tracing/distributed/headers/datadog.rb +122 -30
- data/lib/datadog/tracing/distributed/headers/ext.rb +2 -0
- data/lib/datadog/tracing/flush.rb +57 -35
- data/lib/datadog/tracing/metadata/ext.rb +11 -9
- data/lib/datadog/tracing/metadata/tagging.rb +9 -0
- data/lib/datadog/tracing/propagation/http.rb +9 -1
- data/lib/datadog/tracing/sampling/ext.rb +31 -0
- data/lib/datadog/tracing/sampling/priority_sampler.rb +46 -4
- data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +8 -9
- data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +29 -5
- data/lib/datadog/tracing/sampling/rate_limiter.rb +3 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +20 -3
- data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
- data/lib/datadog/tracing/sampling/span/ext.rb +25 -0
- data/lib/datadog/tracing/sampling/span/matcher.rb +9 -0
- data/lib/datadog/tracing/sampling/span/rule.rb +82 -0
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +104 -0
- data/lib/datadog/tracing/sampling/span/sampler.rb +75 -0
- data/lib/datadog/tracing/span_operation.rb +0 -2
- data/lib/datadog/tracing/trace_digest.rb +3 -0
- data/lib/datadog/tracing/trace_operation.rb +32 -3
- data/lib/datadog/tracing/trace_segment.rb +7 -2
- data/lib/datadog/tracing/tracer.rb +34 -6
- data/lib/datadog/tracing/writer.rb +7 -0
- data/lib/ddtrace/transport/trace_formatter.rb +7 -0
- data/lib/ddtrace/transport/traces.rb +3 -1
- data/lib/ddtrace/version.rb +1 -1
- metadata +36 -18
- data/lib/datadog/profiling/old_ext.rb +0 -42
- data/lib/datadog/profiling/transport/http/api/endpoint.rb +0 -85
- data/lib/datadog/profiling/transport/http/api/instance.rb +0 -38
- data/lib/datadog/profiling/transport/http/api/spec.rb +0 -42
- data/lib/datadog/profiling/transport/http/api.rb +0 -45
- data/lib/datadog/profiling/transport/http/builder.rb +0 -30
- data/lib/datadog/profiling/transport/http/client.rb +0 -37
- data/lib/datadog/profiling/transport/http/response.rb +0 -21
- data/lib/datadog/profiling/transport/http.rb +0 -118
@@ -7,7 +7,7 @@
|
|
7
7
|
#include "libdatadog_helpers.h"
|
8
8
|
#include "ruby_helpers.h"
|
9
9
|
|
10
|
-
// Used to wrap a
|
10
|
+
// Used to wrap a ddog_Profile in a Ruby object and expose Ruby-level serialization APIs
|
11
11
|
// This file implements the native bits of the Datadog::Profiling::StackRecorder class
|
12
12
|
|
13
13
|
// ---
|
@@ -24,7 +24,7 @@
|
|
24
24
|
// 2. The thread that serializes and reports profiles, let's call it the **serializer thread**. We enforce that there
|
25
25
|
// cannot be more than one thread attempting to serialize profiles at a time.
|
26
26
|
//
|
27
|
-
// If both the sampler and serializer threads are trying to access the same `
|
27
|
+
// If both the sampler and serializer threads are trying to access the same `ddog_Profile` in parallel, we will
|
28
28
|
// have a concurrency issue. Thus, the StackRecorder has an added mechanism to avoid this.
|
29
29
|
//
|
30
30
|
// As an additional constraint, the **sampler thread** has absolute priority and must never block while
|
@@ -32,7 +32,7 @@
|
|
32
32
|
//
|
33
33
|
// ### The solution: Keep two profiles at the same time
|
34
34
|
//
|
35
|
-
// To solve for the constraints above, the StackRecorder keeps two `
|
35
|
+
// To solve for the constraints above, the StackRecorder keeps two `ddog_Profile` profile instances inside itself.
|
36
36
|
// They are called the `slot_one_profile` and `slot_two_profile`.
|
37
37
|
//
|
38
38
|
// Each profile is paired with its own mutex. `slot_one_profile` is protected by `slot_one_mutex` and `slot_two_profile`
|
@@ -135,10 +135,10 @@ static VALUE stack_recorder_class = Qnil;
|
|
135
135
|
// Contains native state for each instance
|
136
136
|
struct stack_recorder_state {
|
137
137
|
pthread_mutex_t slot_one_mutex;
|
138
|
-
|
138
|
+
ddog_Profile *slot_one_profile;
|
139
139
|
|
140
140
|
pthread_mutex_t slot_two_mutex;
|
141
|
-
|
141
|
+
ddog_Profile *slot_two_profile;
|
142
142
|
|
143
143
|
short active_slot; // MUST NEVER BE ACCESSED FROM record_sample; this is NOT for the sampler thread to use.
|
144
144
|
};
|
@@ -146,7 +146,7 @@ struct stack_recorder_state {
|
|
146
146
|
// Used to return a pair of values from sampler_lock_active_profile()
|
147
147
|
struct active_slot_pair {
|
148
148
|
pthread_mutex_t *mutex;
|
149
|
-
|
149
|
+
ddog_Profile *profile;
|
150
150
|
};
|
151
151
|
|
152
152
|
struct call_serialize_without_gvl_arguments {
|
@@ -154,8 +154,8 @@ struct call_serialize_without_gvl_arguments {
|
|
154
154
|
struct stack_recorder_state *state;
|
155
155
|
|
156
156
|
// Set by callee
|
157
|
-
|
158
|
-
|
157
|
+
ddog_Profile *profile;
|
158
|
+
ddog_SerializeResult result;
|
159
159
|
|
160
160
|
// Set by both
|
161
161
|
bool serialize_ran;
|
@@ -164,15 +164,16 @@ struct call_serialize_without_gvl_arguments {
|
|
164
164
|
static VALUE _native_new(VALUE klass);
|
165
165
|
static void stack_recorder_typed_data_free(void *data);
|
166
166
|
static VALUE _native_serialize(VALUE self, VALUE recorder_instance);
|
167
|
-
static VALUE ruby_time_from(
|
167
|
+
static VALUE ruby_time_from(ddog_Timespec ddprof_time);
|
168
168
|
static void *call_serialize_without_gvl(void *call_args);
|
169
169
|
static struct active_slot_pair sampler_lock_active_profile();
|
170
170
|
static void sampler_unlock_active_profile(struct active_slot_pair active_slot);
|
171
|
-
static
|
171
|
+
static ddog_Profile *serializer_flip_active_and_inactive_slots(struct stack_recorder_state *state, ddog_Timespec start_timestamp_for_next_profile);
|
172
172
|
static VALUE _native_active_slot(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
173
173
|
static VALUE _native_is_slot_one_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
174
174
|
static VALUE _native_is_slot_two_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
175
175
|
static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot);
|
176
|
+
static ddog_Timespec time_now();
|
176
177
|
|
177
178
|
void stack_recorder_init(VALUE profiling_module) {
|
178
179
|
stack_recorder_class = rb_define_class_under(profiling_module, "StackRecorder", rb_cObject);
|
@@ -199,7 +200,7 @@ void stack_recorder_init(VALUE profiling_module) {
|
|
199
200
|
ruby_time_from_id = rb_intern_const("ruby_time_from");
|
200
201
|
}
|
201
202
|
|
202
|
-
// This structure is used to define a Ruby object that stores a pointer to a
|
203
|
+
// This structure is used to define a Ruby object that stores a pointer to a ddog_Profile instance
|
203
204
|
// See also https://github.com/ruby/ruby/blob/master/doc/extension.rdoc for how this works
|
204
205
|
static const rb_data_type_t stack_recorder_typed_data = {
|
205
206
|
.wrap_struct_name = "Datadog::Profiling::StackRecorder",
|
@@ -214,7 +215,7 @@ static const rb_data_type_t stack_recorder_typed_data = {
|
|
214
215
|
static VALUE _native_new(VALUE klass) {
|
215
216
|
struct stack_recorder_state *state = ruby_xcalloc(1, sizeof(struct stack_recorder_state));
|
216
217
|
|
217
|
-
|
218
|
+
ddog_Slice_value_type sample_types = {.ptr = enabled_value_types, .len = ENABLED_VALUE_TYPES_COUNT};
|
218
219
|
|
219
220
|
state->slot_one_mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
|
220
221
|
state->slot_two_mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
|
@@ -227,8 +228,8 @@ static VALUE _native_new(VALUE klass) {
|
|
227
228
|
|
228
229
|
// Note: Don't raise exceptions after this point, since it'll lead to libdatadog memory leaking!
|
229
230
|
|
230
|
-
state->slot_one_profile =
|
231
|
-
state->slot_two_profile =
|
231
|
+
state->slot_one_profile = ddog_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
|
232
|
+
state->slot_two_profile = ddog_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
|
232
233
|
|
233
234
|
return TypedData_Wrap_Struct(klass, &stack_recorder_typed_data, state);
|
234
235
|
}
|
@@ -237,10 +238,10 @@ static void stack_recorder_typed_data_free(void *state_ptr) {
|
|
237
238
|
struct stack_recorder_state *state = (struct stack_recorder_state *) state_ptr;
|
238
239
|
|
239
240
|
pthread_mutex_destroy(&state->slot_one_mutex);
|
240
|
-
|
241
|
+
ddog_Profile_free(state->slot_one_profile);
|
241
242
|
|
242
243
|
pthread_mutex_destroy(&state->slot_two_mutex);
|
243
|
-
|
244
|
+
ddog_Profile_free(state->slot_two_profile);
|
244
245
|
|
245
246
|
ruby_xfree(state);
|
246
247
|
}
|
@@ -267,33 +268,33 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
|
|
267
268
|
rb_thread_call_without_gvl2(call_serialize_without_gvl, &args, NULL /* No interruption function needed in this case */, NULL /* Not needed */);
|
268
269
|
}
|
269
270
|
|
270
|
-
|
271
|
+
ddog_SerializeResult serialized_profile = args.result;
|
271
272
|
|
272
|
-
if (serialized_profile.tag ==
|
273
|
+
if (serialized_profile.tag == DDOG_SERIALIZE_RESULT_ERR) {
|
273
274
|
VALUE err_details = ruby_string_from_vec_u8(serialized_profile.err);
|
274
|
-
|
275
|
+
ddog_SerializeResult_drop(serialized_profile);
|
275
276
|
return rb_ary_new_from_args(2, error_symbol, err_details);
|
276
277
|
}
|
277
278
|
|
278
279
|
VALUE encoded_pprof = ruby_string_from_vec_u8(serialized_profile.ok.buffer);
|
279
280
|
|
280
|
-
|
281
|
-
|
281
|
+
ddog_Timespec ddprof_start = serialized_profile.ok.start;
|
282
|
+
ddog_Timespec ddprof_finish = serialized_profile.ok.end;
|
282
283
|
|
283
284
|
// Clean up libdatadog object to avoid leaking in case ruby_time_from raises an exception
|
284
|
-
|
285
|
+
ddog_SerializeResult_drop(serialized_profile);
|
285
286
|
|
286
287
|
VALUE start = ruby_time_from(ddprof_start);
|
287
288
|
VALUE finish = ruby_time_from(ddprof_finish);
|
288
289
|
|
289
|
-
if (!
|
290
|
+
if (!ddog_Profile_reset(args.profile, NULL /* start_time is optional */ )) {
|
290
291
|
return rb_ary_new_from_args(2, error_symbol, rb_str_new_cstr("Failed to reset profile"));
|
291
292
|
}
|
292
293
|
|
293
294
|
return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(3, start, finish, encoded_pprof));
|
294
295
|
}
|
295
296
|
|
296
|
-
static VALUE ruby_time_from(
|
297
|
+
static VALUE ruby_time_from(ddog_Timespec ddprof_time) {
|
297
298
|
#ifndef NO_RB_TIME_TIMESPEC_NEW // Modern Rubies
|
298
299
|
const int utc = INT_MAX - 1; // From Ruby sources
|
299
300
|
struct timespec time = {.tv_sec = ddprof_time.seconds, .tv_nsec = ddprof_time.nanoseconds};
|
@@ -303,13 +304,13 @@ static VALUE ruby_time_from(ddprof_ffi_Timespec ddprof_time) {
|
|
303
304
|
#endif
|
304
305
|
}
|
305
306
|
|
306
|
-
void record_sample(VALUE recorder_instance,
|
307
|
+
void record_sample(VALUE recorder_instance, ddog_Sample sample) {
|
307
308
|
struct stack_recorder_state *state;
|
308
309
|
TypedData_Get_Struct(recorder_instance, struct stack_recorder_state, &stack_recorder_typed_data, state);
|
309
310
|
|
310
311
|
struct active_slot_pair active_slot = sampler_lock_active_profile(state);
|
311
312
|
|
312
|
-
|
313
|
+
ddog_Profile_add(active_slot.profile, sample);
|
313
314
|
|
314
315
|
sampler_unlock_active_profile(active_slot);
|
315
316
|
}
|
@@ -317,8 +318,10 @@ void record_sample(VALUE recorder_instance, ddprof_ffi_Sample sample) {
|
|
317
318
|
static void *call_serialize_without_gvl(void *call_args) {
|
318
319
|
struct call_serialize_without_gvl_arguments *args = (struct call_serialize_without_gvl_arguments *) call_args;
|
319
320
|
|
320
|
-
|
321
|
-
|
321
|
+
ddog_Timespec finish_timestamp = time_now();
|
322
|
+
|
323
|
+
args->profile = serializer_flip_active_and_inactive_slots(args->state, finish_timestamp);
|
324
|
+
args->result = ddog_Profile_serialize(args->profile, &finish_timestamp, NULL /* duration_nanos is optional */);
|
322
325
|
args->serialize_ran = true;
|
323
326
|
|
324
327
|
return NULL; // Unused
|
@@ -357,7 +360,7 @@ static void sampler_unlock_active_profile(struct active_slot_pair active_slot) {
|
|
357
360
|
if (error != 0) rb_syserr_fail(error, "Unexpected failure in sampler_unlock_active_profile");
|
358
361
|
}
|
359
362
|
|
360
|
-
static
|
363
|
+
static ddog_Profile *serializer_flip_active_and_inactive_slots(struct stack_recorder_state *state, ddog_Timespec start_timestamp_for_next_profile) {
|
361
364
|
int error;
|
362
365
|
int previously_active_slot = state->active_slot;
|
363
366
|
|
@@ -368,6 +371,10 @@ static ddprof_ffi_Profile *serializer_flip_active_and_inactive_slots(struct stac
|
|
368
371
|
pthread_mutex_t *previously_active = (previously_active_slot == 1) ? &state->slot_one_mutex : &state->slot_two_mutex;
|
369
372
|
pthread_mutex_t *previously_inactive = (previously_active_slot == 1) ? &state->slot_two_mutex : &state->slot_one_mutex;
|
370
373
|
|
374
|
+
// Before making this profile active, we reset it so that it uses the correct timestamp for its start
|
375
|
+
ddog_Profile *previously_inactive_profile = (previously_active_slot == 1) ? state->slot_two_profile : state->slot_one_profile;
|
376
|
+
if (!ddog_Profile_reset(previously_inactive_profile, &start_timestamp_for_next_profile)) rb_raise(rb_eRuntimeError, "Failed to reset profile");
|
377
|
+
|
371
378
|
// Release the lock, thus making this slot active
|
372
379
|
error = pthread_mutex_unlock(previously_inactive);
|
373
380
|
if (error) rb_syserr_fail(error, "Unexpected failure during serializer_flip_active_and_inactive_slots for previously_inactive");
|
@@ -420,3 +427,12 @@ static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot) {
|
|
420
427
|
rb_syserr_fail(error, "Unexpected failure when checking mutex state");
|
421
428
|
}
|
422
429
|
}
|
430
|
+
|
431
|
+
// Note that this is using CLOCK_REALTIME (e.g. actual time since unix epoch) and not the CLOCK_MONOTONIC as we use in other parts of the codebase
|
432
|
+
static ddog_Timespec time_now() {
|
433
|
+
struct timespec current_time;
|
434
|
+
|
435
|
+
if (clock_gettime(CLOCK_REALTIME, ¤t_time) != 0) rb_sys_fail("Failed to read CLOCK_REALTIME");
|
436
|
+
|
437
|
+
return (ddog_Timespec) {.seconds = current_time.tv_sec, .nanoseconds = (uint32_t) current_time.tv_nsec};
|
438
|
+
}
|
@@ -1,16 +1,16 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
-
#include <
|
3
|
+
#include <datadog/profiling.h>
|
4
4
|
|
5
|
-
// Note: Please DO NOT use `VALUE_STRING` anywhere else, instead use `
|
5
|
+
// Note: Please DO NOT use `VALUE_STRING` anywhere else, instead use `DDOG_CHARSLICE_C`.
|
6
6
|
// `VALUE_STRING` is only needed because older versions of gcc (4.9.2, used in our Ruby 2.2 CI test images)
|
7
7
|
// tripped when compiling `enabled_value_types` using `-std=gnu99` due to the extra cast that is included in
|
8
|
-
// `
|
8
|
+
// `DDOG_CHARSLICE_C` with the following error:
|
9
9
|
//
|
10
10
|
// ```
|
11
11
|
// compiling ../../../../ext/ddtrace_profiling_native_extension/stack_recorder.c
|
12
12
|
// ../../../../ext/ddtrace_profiling_native_extension/stack_recorder.c:23:1: error: initializer element is not constant
|
13
|
-
// static const
|
13
|
+
// static const ddog_ValueType enabled_value_types[] = {CPU_TIME_VALUE, CPU_SAMPLES_VALUE, WALL_TIME_VALUE};
|
14
14
|
// ^
|
15
15
|
// ```
|
16
16
|
#define VALUE_STRING(string) {.ptr = "" string, .len = sizeof(string) - 1}
|
@@ -23,7 +23,7 @@
|
|
23
23
|
#define HEAP_LIVE_SIZE_VALUE {.type_ = VALUE_STRING("heap-live-size"), .unit = VALUE_STRING("bytes")}
|
24
24
|
#define HEAP_LIVE_SAMPLES_VALUE {.type_ = VALUE_STRING("heap-live-samples"), .unit = VALUE_STRING("count")}
|
25
25
|
|
26
|
-
static const
|
26
|
+
static const ddog_ValueType enabled_value_types[] = {
|
27
27
|
#define CPU_TIME_VALUE_POS 0
|
28
28
|
CPU_TIME_VALUE,
|
29
29
|
#define CPU_SAMPLES_VALUE_POS 1
|
@@ -32,7 +32,7 @@ static const ddprof_ffi_ValueType enabled_value_types[] = {
|
|
32
32
|
WALL_TIME_VALUE
|
33
33
|
};
|
34
34
|
|
35
|
-
#define ENABLED_VALUE_TYPES_COUNT (sizeof(enabled_value_types) / sizeof(
|
35
|
+
#define ENABLED_VALUE_TYPES_COUNT (sizeof(enabled_value_types) / sizeof(ddog_ValueType))
|
36
36
|
|
37
|
-
void record_sample(VALUE recorder_instance,
|
37
|
+
void record_sample(VALUE recorder_instance, ddog_Sample sample);
|
38
38
|
VALUE enforce_recorder_instance(VALUE object);
|