Skip to content

Commit

Permalink
Merge branch 'master' into 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ekump committed Jan 4, 2024
2 parents 2b837a1 + 5899696 commit d152021
Show file tree
Hide file tree
Showing 140 changed files with 1,938 additions and 350 deletions.
2 changes: 1 addition & 1 deletion .circleci/images/primary/Dockerfile-3.3.0
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Note: See the "Publishing updates to images" note in ./README.md for how to publish new builds of this container image

FROM ruby:3.3-rc-bullseye
FROM ruby:3.3.0-bullseye

# Make apt non-interactive
RUN echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/90circleci \
Expand Down
4 changes: 2 additions & 2 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,8 @@ client.query("SELECT * FROM users WHERE group='x'")
|-----------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|
| `service_name` | `DD_TRACE_MYSQL2_SERVICE_NAME` | Name of application running the `mysql2` instrumentation. May be overridden by `global_default_service_name`. [See *Additional Configuration* for more details](#additional-configuration) | `mysql2` |
| `peer_service` | `DD_TRACE_MYSQL2_PEER_SERVICE` | Name of external service the application connects to | `nil` |
| `comment_propagation` | `DD_DBM_PROPAGATION_MODE` | SQL comment propagation mode for database monitoring. <br />(example: `disabled` \| `service`\| `full`). <br /><br />**Important**: *Note that enabling sql comment propagation results in potentially confidential data (service names) being stored in the databases which can then be accessed by other 3rd parties that have been granted access to the database.* | `'disabled'` |

| `comment_propagation` | `DD_DBM_PROPAGATION_MODE` | SQL comment propagation mode for database monitoring. <br />(example: `disabled` \| `service`\| `full`). <br /><br />**Important**: *Note that enabling SQL comment propagation results in potentially confidential data (service names) being stored in the databases which can then be accessed by other third parties that have been granted access to the database.* | `'disabled'` |
| `on_error` | | Custom error handler invoked when MySQL raises an error. Provided `span` and `error` as arguments. Sets error on the span by default. Useful for ignoring errors that are handled at the application level. | `proc { \|span, error\| span.set_error(error) unless span.nil? }` |
### Net/HTTP

The Net/HTTP integration will trace any HTTP call using the standard lib Net::HTTP module.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@
//
// ---

#ifndef NO_POSTPONED_TRIGGER
// Used to call the rb_postponed_job_trigger from Ruby 3.3+. These get initialized in
// `collectors_cpu_and_wall_time_worker_init` below and always get reused after that.
static rb_postponed_job_handle_t sample_from_postponed_job_handle;
static rb_postponed_job_handle_t after_gc_from_postponed_job_handle;
#endif

// Contains state for a single CpuAndWallTimeWorker instance
struct cpu_and_wall_time_worker_state {
// These are immutable after initialization
Expand Down Expand Up @@ -212,6 +219,16 @@ __thread uint64_t allocation_count = 0;
void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module) {
rb_global_variable(&active_sampler_instance);

#ifndef NO_POSTPONED_TRIGGER
int unused_flags = 0;
sample_from_postponed_job_handle = rb_postponed_job_preregister(unused_flags, sample_from_postponed_job, NULL);
after_gc_from_postponed_job_handle = rb_postponed_job_preregister(unused_flags, after_gc_from_postponed_job, NULL);

if (sample_from_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID || after_gc_from_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID) {
rb_raise(rb_eRuntimeError, "Failed to register profiler postponed jobs (got POSTPONED_JOB_HANDLE_INVALID)");
}
#endif

VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
VALUE collectors_cpu_and_wall_time_worker_class = rb_define_class_under(collectors_module, "CpuAndWallTimeWorker", rb_cObject);
// Hosts methods used for testing the native code using RSpec
Expand Down Expand Up @@ -476,20 +493,25 @@ static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED si

// Note: If we ever want to get rid of rb_postponed_job_register_one, remember not to clobber Ruby exceptions, as
// this function does this helpful job for us now -- https://github.com/ruby/ruby/commit/a98e343d39c4d7bf1e2190b076720f32d9f298b3.
int result = rb_postponed_job_register_one(0, sample_from_postponed_job, NULL);

// Officially, the result of rb_postponed_job_register_one is documented as being opaque, but in practice it does not
// seem to have changed between Ruby 2.3 and 3.2, and so we track it as a debugging mechanism
switch (result) {
case 0:
state->stats.postponed_job_full++; break;
case 1:
state->stats.postponed_job_success++; break;
case 2:
state->stats.postponed_job_skipped_already_existed++; break;
default:
state->stats.postponed_job_unknown_result++;
}
#ifndef NO_POSTPONED_TRIGGER // Ruby 3.3+
rb_postponed_job_trigger(sample_from_postponed_job_handle);
state->stats.postponed_job_success++; // Always succeeds
#else
int result = rb_postponed_job_register_one(0, sample_from_postponed_job, NULL);

// Officially, the result of rb_postponed_job_register_one is documented as being opaque, but in practice it does not
// seem to have changed between Ruby 2.3 and 3.2, and so we track it as a debugging mechanism
switch (result) {
case 0:
state->stats.postponed_job_full++; break;
case 1:
state->stats.postponed_job_success++; break;
case 2:
state->stats.postponed_job_skipped_already_existed++; break;
default:
state->stats.postponed_job_unknown_result++;
}
#endif
}

// The actual sampling trigger loop always runs **without** the global vm lock.
Expand Down Expand Up @@ -722,7 +744,13 @@ static void on_gc_event(VALUE tracepoint_data, DDTRACE_UNUSED void *unused) {

// We use rb_postponed_job_register_one to ask Ruby to run thread_context_collector_sample_after_gc when the
// thread collector flags it's time to flush.
if (should_flush) rb_postponed_job_register_one(0, after_gc_from_postponed_job, NULL);
if (should_flush) {
#ifndef NO_POSTPONED_TRIGGER // Ruby 3.3+
rb_postponed_job_trigger(after_gc_from_postponed_job_handle);
#else
rb_postponed_job_register_one(0, after_gc_from_postponed_job, NULL);
#endif
}
}
}

Expand Down
10 changes: 0 additions & 10 deletions ext/ddtrace_profiling_native_extension/collectors_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
// Gathers stack traces from running threads, storing them in a StackRecorder instance
// This file implements the native bits of the Datadog::Profiling::Collectors::Stack class

#define MAX_FRAMES_LIMIT 10000
#define MAX_FRAMES_LIMIT_AS_STRING "10000"

static VALUE missing_string = Qnil;

// Used as scratch space during sampling
Expand All @@ -37,13 +34,6 @@ static VALUE _native_sample(
);
static void maybe_add_placeholder_frames_omitted(VALUE thread, sampling_buffer* buffer, char *frames_omitted_message, int frames_omitted_message_size);
static void record_placeholder_stack_in_native_code(sampling_buffer* buffer, VALUE recorder_instance, sample_values values, sample_labels labels);
static void sample_thread_internal(
VALUE thread,
sampling_buffer* buffer,
VALUE recorder_instance,
sample_values values,
sample_labels labels
);

void collectors_stack_init(VALUE profiling_module) {
VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
Expand Down
3 changes: 3 additions & 0 deletions ext/ddtrace_profiling_native_extension/collectors_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include "stack_recorder.h"

#define MAX_FRAMES_LIMIT 10000
#define MAX_FRAMES_LIMIT_AS_STRING "10000"

typedef struct sampling_buffer sampling_buffer;

void sample_thread(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ void thread_context_collector_sample_allocation(VALUE self_instance, unsigned in
}
}

track_object(state->recorder_instance, new_object, sample_weight);
track_object(state->recorder_instance, new_object, sample_weight, optional_class_name);

trigger_sample_for_thread(
state,
Expand Down
3 changes: 3 additions & 0 deletions ext/ddtrace_profiling_native_extension/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ def add_compiler_flag(flag)
$defs << '-DHAVE_PTHREAD_GETCPUCLOCKID'
end

# On older Rubies, rb_postponed_job_preregister/rb_postponed_job_trigger did not exist
$defs << '-DNO_POSTPONED_TRIGGER' if RUBY_VERSION < '3.3'

# On older Rubies, M:N threads were not available
$defs << '-DNO_MN_THREADS_AVAILABLE' if RUBY_VERSION < '3.3'

Expand Down
Loading

0 comments on commit d152021

Please sign in to comment.