Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8a64c7d
Update Stable Config native extension to support libdatadog 21 and ad…
vpellan Sep 19, 2025
2f08abf
Upgrade libdatadog dependency to 21.0
vpellan Sep 22, 2025
0d6d79d
Fix crashtracking specs
vpellan Oct 2, 2025
392c648
[skip ci] update process-discovery native FFI
dmehala Oct 2, 2025
e4cc822
Fix process_discovery update
vpellan Oct 3, 2025
bcab255
Apply suggestions for stable config
vpellan Oct 3, 2025
70ff040
Upgrade libdatadog dependency to 22.0
vpellan Oct 3, 2025
ceba539
[🤖] Update Latest Dependency: https://github.com/DataDog/dd-trace-rb/…
dd-apm-ecosystems-autobot[bot] Oct 3, 2025
fff7d04
[🤖] Lock Dependency: https://github.com/DataDog/dd-trace-rb/actions/r…
dd-apm-ecosystems-autobot[bot] Oct 3, 2025
13d3f96
lint + standard
vpellan Oct 3, 2025
9be227b
revert logger_without_configuration changes
vpellan Oct 3, 2025
ff54715
Add empty process_tags and container_id fields
vpellan Oct 6, 2025
66c6015
Update libdatadog to 22.0.1
vpellan Oct 8, 2025
049ba40
Merge 66c6015c50dec7a26ecb53ec5c101280f081a408 into 9304c118c6d89d9de…
vpellan Oct 8, 2025
709e821
[🤖] Lock Dependency: https://github.com/DataDog/dd-trace-rb/actions/r…
dd-apm-ecosystems-autobot[bot] Oct 8, 2025
5f57075
Merge branch 'master' into vpellan/update-stable-config-libdatadog-21
vpellan Oct 9, 2025
f1f8037
Merge branch 'master' into vpellan/update-stable-config-libdatadog-21
vpellan Oct 10, 2025
b70c467
Merge f1f8037cc5237eb2a1ca2b6e4a36a59c923bb459 into fc601fb8e60c18ec5…
vpellan Oct 10, 2025
56b72c5
[🤖] Lock Dependency: https://github.com/DataDog/dd-trace-rb/actions/r…
dd-apm-ecosystems-autobot[bot] Oct 10, 2025
e06a0b7
Merge branch 'master' into vpellan/update-stable-config-libdatadog-21
vpellan Oct 10, 2025
5023f8b
Simplified stable config tests
vpellan Oct 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion datadog.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Gem::Specification.new do |spec|

# When updating the version here, please also update the version in `libdatadog_extconf_helpers.rb`
# (and yes we have a test for it)
spec.add_dependency 'libdatadog', '~> 18.1.0.1.0'
spec.add_dependency 'libdatadog', '~> 22.0.1.1.0'

# Will no longer be a default gem on Ruby 3.5, see
# https://github.com/ruby/ruby/commit/d7e558e3c48c213d0e8bedca4fb547db55613f7c and
Expand Down
62 changes: 35 additions & 27 deletions ext/libdatadog_api/library_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static VALUE _native_configurator_get(VALUE self);
static VALUE _native_configurator_with_local_path(DDTRACE_UNUSED VALUE _self, VALUE rb_configurator, VALUE path);
static VALUE _native_configurator_with_fleet_path(DDTRACE_UNUSED VALUE _self, VALUE rb_configurator, VALUE path);

static VALUE config_vec_class = Qnil;
static VALUE config_logged_result_class = Qnil;

// ddog_Configurator memory management
static void configurator_free(void *configurator_ptr) {
Expand All @@ -29,29 +29,29 @@ static const rb_data_type_t configurator_typed_data = {
.flags = RUBY_TYPED_FREE_IMMEDIATELY
};

// ddog_Vec_LibraryConfig memory management
static void config_vec_free(void *config_vec_ptr) {
ddog_Vec_LibraryConfig *config_vec = (ddog_Vec_LibraryConfig *)config_vec_ptr;
// ddog_LibraryConfigLoggedResult memory management
static void config_logged_result_free(void *config_logged_result_ptr) {
ddog_LibraryConfigLoggedResult *config_logged_result = (ddog_LibraryConfigLoggedResult *)config_logged_result_ptr;

ddog_library_config_drop(*config_vec);
ruby_xfree(config_vec_ptr);
ddog_library_config_drop(*config_logged_result);
ruby_xfree(config_logged_result_ptr);
}

static const rb_data_type_t config_vec_typed_data = {
.wrap_struct_name = "Datadog::Core::Configuration::StableConfigVec",
static const rb_data_type_t config_logged_result_typed_data = {
.wrap_struct_name = "Datadog::Core::Configuration::StableConfigLoggedResult",
.function = {
.dfree = config_vec_free,
.dfree = config_logged_result_free,
.dsize = NULL,
},
.flags = RUBY_TYPED_FREE_IMMEDIATELY
};

void library_config_init(VALUE core_module) {
rb_global_variable(&config_vec_class);
rb_global_variable(&config_logged_result_class);
VALUE configuration_module = rb_define_module_under(core_module, "Configuration");
VALUE stable_config_module = rb_define_module_under(configuration_module, "StableConfig");
VALUE configurator_class = rb_define_class_under(stable_config_module, "Configurator", rb_cObject);
config_vec_class = rb_define_class_under(configuration_module, "StableConfigVec", rb_cObject);
config_logged_result_class = rb_define_class_under(configuration_module, "StableConfigLoggedResult", rb_cObject);

rb_define_alloc_func(configurator_class, _native_configurator_new);
rb_define_method(configurator_class, "get", _native_configurator_get, 0);
Expand All @@ -61,11 +61,12 @@ void library_config_init(VALUE core_module) {
rb_define_singleton_method(testing_module, "with_local_path", _native_configurator_with_local_path, 2);
rb_define_singleton_method(testing_module, "with_fleet_path", _native_configurator_with_fleet_path, 2);

rb_undef_alloc_func(config_vec_class); // It cannot be created from Ruby code and only serves as an intermediate object for the Ruby GC
rb_undef_alloc_func(config_logged_result_class); // It cannot be created from Ruby code and only serves as an intermediate object for the Ruby GC
}

static VALUE _native_configurator_new(VALUE klass) {
ddog_Configurator *configurator = ddog_library_configurator_new(false, DDOG_CHARSLICE_C("ruby"));
// We always collect debug logs, so if DD_TRACE_DEBUG is set by stable config, we'll be able to log them.
ddog_Configurator *configurator = ddog_library_configurator_new(true, DDOG_CHARSLICE_C("ruby"));

ddog_library_configurator_with_detect_process_info(configurator);

Expand Down Expand Up @@ -98,27 +99,33 @@ static VALUE _native_configurator_get(VALUE self) {
ddog_Configurator *configurator;
TypedData_Get_Struct(self, ddog_Configurator, &configurator_typed_data, configurator);

ddog_Result_VecLibraryConfig configurator_result = ddog_library_configurator_get(configurator);
// Wrapping config_logged_result into a Ruby object enables the Ruby GC to manage its memory
// We need to allocate memory for config_logged_result because once it is out of scope, it will be freed (at the end of this function)
// So we cannot reference it with &config_logged_result
// We are doing this in case one of the ruby API raises an exception before the end of this function,
// so the allocated memory will still be freed
ddog_LibraryConfigLoggedResult *configurator_logged_result = ruby_xcalloc(1, sizeof(ddog_LibraryConfigLoggedResult));
*configurator_logged_result = ddog_library_configurator_get(configurator);
VALUE config_logged_result_rb = TypedData_Wrap_Struct(config_logged_result_class, &config_logged_result_typed_data, configurator_logged_result);

if (configurator_result.tag == DDOG_RESULT_VEC_LIBRARY_CONFIG_ERR_VEC_LIBRARY_CONFIG) {
ddog_Error err = configurator_result.err;
if (configurator_logged_result->tag == DDOG_LIBRARY_CONFIG_LOGGED_RESULT_ERR) {
ddog_Error err = configurator_logged_result->err;
VALUE message = get_error_details_and_drop(&err);
if (is_config_loaded()) {
log_warning(message);
} else {
log_warning_without_config(message);
}
RB_GC_GUARD(config_logged_result_rb);
return rb_hash_new();
}

// Wrapping config_vec into a Ruby object enables the Ruby GC to manage its memory
// We need to allocate memory for config_vec because once it is out of scope, it will be freed (at the end of this function)
// So we cannot reference it with &config_vec
// We are doing this in case one of the ruby API raises an exception before the end of this function,
// so the allocated memory will still be freed
ddog_Vec_LibraryConfig *config_vec = ruby_xmalloc(sizeof(ddog_Vec_LibraryConfig));
*config_vec = configurator_result.ok;
VALUE config_vec_rb = TypedData_Wrap_Struct(config_vec_class, &config_vec_typed_data, config_vec);
VALUE logs = Qnil;
if (configurator_logged_result->ok.logs.length > 0) {
logs = rb_utf8_str_new_cstr(configurator_logged_result->ok.logs.ptr);
}

ddog_Vec_LibraryConfig config_vec = configurator_logged_result->ok.value;

VALUE local_config_hash = rb_hash_new();
VALUE fleet_config_hash = rb_hash_new();
Expand All @@ -127,8 +134,8 @@ static VALUE _native_configurator_get(VALUE self) {
bool fleet_config_id_set = false;
VALUE local_hash = rb_hash_new();
VALUE fleet_hash = rb_hash_new();
for (uintptr_t i = 0; i < config_vec->len; i++) {
ddog_LibraryConfig config = config_vec->ptr[i];
for (uintptr_t i = 0; i < config_vec.len; i++) {
ddog_LibraryConfig config = config_vec.ptr[i];
VALUE selected_hash;
if (config.source == DDOG_LIBRARY_CONFIG_SOURCE_LOCAL_STABLE_CONFIG) {
selected_hash = local_config_hash;
Expand Down Expand Up @@ -156,9 +163,10 @@ static VALUE _native_configurator_get(VALUE self) {
rb_hash_aset(fleet_hash, ID2SYM(rb_intern("config")), fleet_config_hash);

VALUE result = rb_hash_new();
rb_hash_aset(result, ID2SYM(rb_intern("logs")), logs);
rb_hash_aset(result, ID2SYM(rb_intern("local")), local_hash);
rb_hash_aset(result, ID2SYM(rb_intern("fleet")), fleet_hash);

RB_GC_GUARD(config_vec_rb);
RB_GC_GUARD(config_logged_result_rb);
return result;
}
32 changes: 19 additions & 13 deletions ext/libdatadog_api/process_discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,40 @@ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, VALUE self) {
rb_scan_args(argc, argv, "1:", &logger, &options);
if (options == Qnil) options = rb_hash_new();

VALUE schema_version = rb_hash_fetch(options, ID2SYM(rb_intern("schema_version")));
VALUE runtime_id = rb_hash_fetch(options, ID2SYM(rb_intern("runtime_id")));
VALUE tracer_language = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_language")));
VALUE tracer_version = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_version")));
VALUE hostname = rb_hash_fetch(options, ID2SYM(rb_intern("hostname")));
VALUE service_name = rb_hash_fetch(options, ID2SYM(rb_intern("service_name")));
VALUE service_env = rb_hash_fetch(options, ID2SYM(rb_intern("service_env")));
VALUE service_version = rb_hash_fetch(options, ID2SYM(rb_intern("service_version")));
VALUE process_tags = rb_hash_fetch(options, ID2SYM(rb_intern("process_tags")));
VALUE container_id = rb_hash_fetch(options, ID2SYM(rb_intern("container_id")));

ENFORCE_TYPE(schema_version, T_FIXNUM);
ENFORCE_TYPE(runtime_id, T_STRING);
ENFORCE_TYPE(tracer_language, T_STRING);
ENFORCE_TYPE(tracer_version, T_STRING);
ENFORCE_TYPE(hostname, T_STRING);
ENFORCE_TYPE(service_name, T_STRING);
ENFORCE_TYPE(service_env, T_STRING);
ENFORCE_TYPE(service_version, T_STRING);

ddog_Result_TracerMemfdHandle result = ddog_store_tracer_metadata(
(uint8_t) NUM2UINT(schema_version),
char_slice_from_ruby_string(runtime_id),
char_slice_from_ruby_string(tracer_language),
char_slice_from_ruby_string(tracer_version),
char_slice_from_ruby_string(hostname),
char_slice_from_ruby_string(service_name),
char_slice_from_ruby_string(service_env),
char_slice_from_ruby_string(service_version)
);
ENFORCE_TYPE(process_tags, T_STRING);
ENFORCE_TYPE(container_id, T_STRING);

void* builder = ddog_tracer_metadata_new();

ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_RUNTIME_ID, StringValueCStr(runtime_id));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_TRACER_LANGUAGE, StringValueCStr(tracer_language));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_TRACER_VERSION, StringValueCStr(tracer_version));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_HOSTNAME, StringValueCStr(hostname));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_SERVICE_NAME, StringValueCStr(service_name));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_SERVICE_ENV, StringValueCStr(service_env));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_SERVICE_VERSION, StringValueCStr(service_version));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_PROCESS_TAGS, StringValueCStr(process_tags));
ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_CONTAINER_ID, StringValueCStr(container_id));

ddog_Result_TracerMemfdHandle result = ddog_tracer_metadata_store(builder);
ddog_tracer_metadata_free(builder);

if (result.tag == DDOG_RESULT_TRACER_MEMFD_HANDLE_ERR_TRACER_MEMFD_HANDLE) {
rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("Failed to store the tracer configuration in a memory file descriptor: %"PRIsVALUE, get_error_details_and_drop(&result.err)));
Expand Down
2 changes: 1 addition & 1 deletion ext/libdatadog_extconf_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Datadog
module LibdatadogExtconfHelpers
# Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
# may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
LIBDATADOG_VERSION = '~> 18.1.0.1.0'
LIBDATADOG_VERSION = '~> 22.0.1.1.0'

# Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
# libdatadog are moved after the extension gets compiled.
Expand Down
4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_activesupport.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_aws.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_contrib.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_contrib_old.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_core_old.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_dalli_2.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_dalli_latest.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_elasticsearch_7.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions gemfiles/jruby_9.2_elasticsearch_latest.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gemfiles/jruby_9.2_excon_latest.gemfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading