ddtrace 1.4.1 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +144 -1
  3. data/LICENSE-3rdparty.csv +1 -0
  4. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +9 -2
  5. data/ext/ddtrace_profiling_loader/extconf.rb +17 -0
  6. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +38 -2
  7. data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -0
  8. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -0
  9. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +517 -42
  10. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +3 -0
  11. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +208 -30
  12. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +156 -46
  13. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +11 -2
  14. data/ext/ddtrace_profiling_native_extension/extconf.rb +11 -1
  15. data/ext/ddtrace_profiling_native_extension/http_transport.c +83 -64
  16. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +4 -4
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +3 -4
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +59 -0
  19. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
  20. data/ext/ddtrace_profiling_native_extension/profiling.c +10 -0
  21. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -1
  22. data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +4 -2
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +45 -29
  24. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +7 -7
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +1169 -275
  26. data/lib/datadog/appsec/assets/waf_rules/risky.json +78 -78
  27. data/lib/datadog/appsec/assets/waf_rules/strict.json +278 -88
  28. data/lib/datadog/appsec/configuration/settings.rb +0 -2
  29. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -20
  30. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +11 -11
  31. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +11 -11
  32. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +11 -11
  33. data/lib/datadog/appsec/contrib/rack/request.rb +3 -0
  34. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +46 -19
  35. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -6
  36. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  37. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +11 -11
  38. data/lib/datadog/appsec/contrib/rails/request.rb +3 -0
  39. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -12
  40. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +11 -11
  41. data/lib/datadog/appsec/event.rb +6 -10
  42. data/lib/datadog/appsec/instrumentation/gateway.rb +16 -2
  43. data/lib/datadog/appsec/processor.rb +18 -2
  44. data/lib/datadog/ci/ext/environment.rb +16 -4
  45. data/lib/datadog/core/configuration/agent_settings_resolver.rb +0 -3
  46. data/lib/datadog/core/configuration/components.rb +28 -16
  47. data/lib/datadog/core/configuration/settings.rb +127 -8
  48. data/lib/datadog/core/configuration.rb +1 -1
  49. data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
  50. data/lib/datadog/core/header_collection.rb +41 -0
  51. data/lib/datadog/core/telemetry/collector.rb +0 -2
  52. data/lib/datadog/core/utils/compression.rb +5 -1
  53. data/lib/datadog/core/workers/async.rb +0 -2
  54. data/lib/datadog/core.rb +0 -54
  55. data/lib/datadog/opentracer/tracer.rb +4 -6
  56. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +12 -2
  57. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -3
  58. data/lib/datadog/profiling/collectors/old_stack.rb +1 -1
  59. data/lib/datadog/profiling/exporter.rb +2 -4
  60. data/lib/datadog/profiling/http_transport.rb +1 -1
  61. data/lib/datadog/profiling.rb +1 -1
  62. data/lib/datadog/tracing/client_ip.rb +164 -0
  63. data/lib/datadog/tracing/configuration/ext.rb +14 -0
  64. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
  65. data/lib/datadog/tracing/contrib/aws/services.rb +0 -2
  66. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  67. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -0
  68. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +2 -0
  69. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -0
  70. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -2
  71. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +2 -0
  72. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -0
  73. data/lib/datadog/tracing/contrib/ext.rb +25 -0
  74. data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -2
  75. data/lib/datadog/tracing/contrib/grape/endpoint.rb +0 -2
  76. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -1
  77. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -0
  78. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -1
  79. data/lib/datadog/tracing/contrib/grpc/ext.rb +2 -0
  80. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +47 -0
  81. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +22 -0
  82. data/lib/datadog/tracing/contrib/hanami/ext.rb +24 -0
  83. data/lib/datadog/tracing/contrib/hanami/integration.rb +44 -0
  84. data/lib/datadog/tracing/contrib/hanami/patcher.rb +33 -0
  85. data/lib/datadog/tracing/contrib/hanami/plugin.rb +23 -0
  86. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +41 -0
  87. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +44 -0
  88. data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -0
  89. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +2 -0
  90. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -0
  91. data/lib/datadog/tracing/contrib/mongodb/ext.rb +7 -0
  92. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -0
  93. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +12 -0
  94. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  95. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -0
  96. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +12 -0
  97. data/lib/datadog/tracing/contrib/pg/ext.rb +2 -1
  98. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +38 -21
  99. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +43 -0
  100. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +32 -0
  101. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +28 -0
  102. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +49 -0
  103. data/lib/datadog/tracing/contrib/rack/header_collection.rb +35 -0
  104. data/lib/datadog/tracing/contrib/rack/middlewares.rb +105 -43
  105. data/lib/datadog/tracing/contrib/redis/ext.rb +2 -0
  106. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +4 -2
  107. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
  108. data/lib/datadog/tracing/contrib/redis/patcher.rb +40 -0
  109. data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
  110. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +2 -0
  111. data/lib/datadog/tracing/contrib/sinatra/env.rb +12 -23
  112. data/lib/datadog/tracing/contrib/sinatra/ext.rb +7 -3
  113. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +2 -2
  114. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +8 -80
  115. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +14 -9
  116. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +92 -10
  117. data/lib/datadog/tracing/contrib.rb +1 -0
  118. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +84 -0
  119. data/lib/datadog/tracing/distributed/headers/datadog.rb +122 -30
  120. data/lib/datadog/tracing/distributed/headers/ext.rb +2 -0
  121. data/lib/datadog/tracing/flush.rb +57 -35
  122. data/lib/datadog/tracing/metadata/ext.rb +11 -9
  123. data/lib/datadog/tracing/metadata/tagging.rb +9 -0
  124. data/lib/datadog/tracing/propagation/http.rb +9 -1
  125. data/lib/datadog/tracing/sampling/ext.rb +31 -0
  126. data/lib/datadog/tracing/sampling/priority_sampler.rb +46 -4
  127. data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +8 -9
  128. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +29 -5
  129. data/lib/datadog/tracing/sampling/rate_limiter.rb +3 -0
  130. data/lib/datadog/tracing/sampling/rate_sampler.rb +20 -3
  131. data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
  132. data/lib/datadog/tracing/sampling/span/ext.rb +25 -0
  133. data/lib/datadog/tracing/sampling/span/matcher.rb +9 -0
  134. data/lib/datadog/tracing/sampling/span/rule.rb +82 -0
  135. data/lib/datadog/tracing/sampling/span/rule_parser.rb +104 -0
  136. data/lib/datadog/tracing/sampling/span/sampler.rb +75 -0
  137. data/lib/datadog/tracing/span_operation.rb +0 -2
  138. data/lib/datadog/tracing/trace_digest.rb +3 -0
  139. data/lib/datadog/tracing/trace_operation.rb +32 -3
  140. data/lib/datadog/tracing/trace_segment.rb +7 -2
  141. data/lib/datadog/tracing/tracer.rb +34 -6
  142. data/lib/datadog/tracing/writer.rb +7 -0
  143. data/lib/ddtrace/transport/trace_formatter.rb +7 -0
  144. data/lib/ddtrace/transport/traces.rb +3 -1
  145. data/lib/ddtrace/version.rb +1 -1
  146. metadata +36 -18
  147. data/lib/datadog/profiling/old_ext.rb +0 -42
  148. data/lib/datadog/profiling/transport/http/api/endpoint.rb +0 -85
  149. data/lib/datadog/profiling/transport/http/api/instance.rb +0 -38
  150. data/lib/datadog/profiling/transport/http/api/spec.rb +0 -42
  151. data/lib/datadog/profiling/transport/http/api.rb +0 -45
  152. data/lib/datadog/profiling/transport/http/builder.rb +0 -30
  153. data/lib/datadog/profiling/transport/http/client.rb +0 -37
  154. data/lib/datadog/profiling/transport/http/response.rb +0 -21
  155. 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 ddprof_ffi_Profile in a Ruby object and expose Ruby-level serialization APIs
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 `ddprof_ffi_Profile` in parallel, we will
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 `ddprof_ffi_Profile` profile instances inside itself.
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
- ddprof_ffi_Profile *slot_one_profile;
138
+ ddog_Profile *slot_one_profile;
139
139
 
140
140
  pthread_mutex_t slot_two_mutex;
141
- ddprof_ffi_Profile *slot_two_profile;
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
- ddprof_ffi_Profile *profile;
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
- ddprof_ffi_Profile *profile;
158
- ddprof_ffi_SerializeResult result;
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(ddprof_ffi_Timespec ddprof_time);
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 ddprof_ffi_Profile *serializer_flip_active_and_inactive_slots(struct stack_recorder_state *state);
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 ddprof_ffi_Profile instance
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
- ddprof_ffi_Slice_value_type sample_types = {.ptr = enabled_value_types, .len = ENABLED_VALUE_TYPES_COUNT};
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 = ddprof_ffi_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
231
- state->slot_two_profile = ddprof_ffi_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
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
- ddprof_ffi_Profile_free(state->slot_one_profile);
241
+ ddog_Profile_free(state->slot_one_profile);
241
242
 
242
243
  pthread_mutex_destroy(&state->slot_two_mutex);
243
- ddprof_ffi_Profile_free(state->slot_two_profile);
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
- ddprof_ffi_SerializeResult serialized_profile = args.result;
271
+ ddog_SerializeResult serialized_profile = args.result;
271
272
 
272
- if (serialized_profile.tag == DDPROF_FFI_SERIALIZE_RESULT_ERR) {
273
+ if (serialized_profile.tag == DDOG_SERIALIZE_RESULT_ERR) {
273
274
  VALUE err_details = ruby_string_from_vec_u8(serialized_profile.err);
274
- ddprof_ffi_SerializeResult_drop(serialized_profile);
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
- ddprof_ffi_Timespec ddprof_start = serialized_profile.ok.start;
281
- ddprof_ffi_Timespec ddprof_finish = serialized_profile.ok.end;
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
- ddprof_ffi_SerializeResult_drop(serialized_profile);
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 (!ddprof_ffi_Profile_reset(args.profile, NULL /* start_time is optional */ )) {
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(ddprof_ffi_Timespec ddprof_time) {
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, ddprof_ffi_Sample sample) {
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
- ddprof_ffi_Profile_add(active_slot.profile, sample);
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
- args->profile = serializer_flip_active_and_inactive_slots(args->state);
321
- args->result = ddprof_ffi_Profile_serialize(args->profile, NULL /* end_time is optional */, NULL /* duration_nanos is optional */);
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 ddprof_ffi_Profile *serializer_flip_active_and_inactive_slots(struct stack_recorder_state *state) {
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, &current_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 <ddprof/ffi.h>
3
+ #include <datadog/profiling.h>
4
4
 
5
- // Note: Please DO NOT use `VALUE_STRING` anywhere else, instead use `DDPROF_FFI_CHARSLICE_C`.
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
- // `DDPROF_FFI_CHARSLICE_C` with the following error:
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 ddprof_ffi_ValueType enabled_value_types[] = {CPU_TIME_VALUE, CPU_SAMPLES_VALUE, WALL_TIME_VALUE};
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 ddprof_ffi_ValueType enabled_value_types[] = {
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(ddprof_ffi_ValueType))
35
+ #define ENABLED_VALUE_TYPES_COUNT (sizeof(enabled_value_types) / sizeof(ddog_ValueType))
36
36
 
37
- void record_sample(VALUE recorder_instance, ddprof_ffi_Sample sample);
37
+ void record_sample(VALUE recorder_instance, ddog_Sample sample);
38
38
  VALUE enforce_recorder_instance(VALUE object);