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
@@ -1,15 +1,25 @@
|
|
1
1
|
#include <ruby.h>
|
2
|
-
#include <datadog/
|
3
|
-
|
2
|
+
#include <datadog/crashtracker.h>
|
3
|
+
|
4
|
+
#include "datadog_ruby_common.h"
|
4
5
|
|
5
6
|
static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
|
6
7
|
static VALUE _native_stop(DDTRACE_UNUSED VALUE _self);
|
8
|
+
static void crashtracker_init(VALUE crashtracking_module);
|
7
9
|
|
8
10
|
// Used to report Ruby VM crashes.
|
9
11
|
// Once initialized, segfaults will be reported automatically using libdatadog.
|
10
12
|
|
11
|
-
void
|
12
|
-
VALUE
|
13
|
+
void DDTRACE_EXPORT Init_libdatadog_api(void) {
|
14
|
+
VALUE datadog_module = rb_define_module("Datadog");
|
15
|
+
VALUE core_module = rb_define_module_under(datadog_module, "Core");
|
16
|
+
VALUE crashtracking_module = rb_define_module_under(core_module, "Crashtracking");
|
17
|
+
|
18
|
+
crashtracker_init(crashtracking_module);
|
19
|
+
}
|
20
|
+
|
21
|
+
void crashtracker_init(VALUE crashtracking_module) {
|
22
|
+
VALUE crashtracker_class = rb_define_class_under(crashtracking_module, "Component", rb_cObject);
|
13
23
|
|
14
24
|
rb_define_singleton_method(crashtracker_class, "_native_start_or_update_on_fork", _native_start_or_update_on_fork, -1);
|
15
25
|
rb_define_singleton_method(crashtracker_class, "_native_stop", _native_stop, 0);
|
@@ -18,8 +28,9 @@ void crashtracker_init(VALUE profiling_module) {
|
|
18
28
|
static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
|
19
29
|
VALUE options;
|
20
30
|
rb_scan_args(argc, argv, "0:", &options);
|
31
|
+
if (options == Qnil) options = rb_hash_new();
|
21
32
|
|
22
|
-
VALUE
|
33
|
+
VALUE agent_base_url = rb_hash_fetch(options, ID2SYM(rb_intern("agent_base_url")));
|
23
34
|
VALUE path_to_crashtracking_receiver_binary = rb_hash_fetch(options, ID2SYM(rb_intern("path_to_crashtracking_receiver_binary")));
|
24
35
|
VALUE ld_library_path = rb_hash_fetch(options, ID2SYM(rb_intern("ld_library_path")));
|
25
36
|
VALUE tags_as_array = rb_hash_fetch(options, ID2SYM(rb_intern("tags_as_array")));
|
@@ -29,7 +40,7 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
29
40
|
VALUE start_action = ID2SYM(rb_intern("start"));
|
30
41
|
VALUE update_on_fork_action = ID2SYM(rb_intern("update_on_fork"));
|
31
42
|
|
32
|
-
ENFORCE_TYPE(
|
43
|
+
ENFORCE_TYPE(agent_base_url, T_STRING);
|
33
44
|
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
34
45
|
ENFORCE_TYPE(path_to_crashtracking_receiver_binary, T_STRING);
|
35
46
|
ENFORCE_TYPE(ld_library_path, T_STRING);
|
@@ -38,14 +49,14 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
38
49
|
|
39
50
|
if (action != start_action && action != update_on_fork_action) rb_raise(rb_eArgError, "Unexpected action: %+"PRIsVALUE, action);
|
40
51
|
|
41
|
-
VALUE version =
|
42
|
-
ddog_prof_Endpoint endpoint = endpoint_from(exporter_configuration);
|
52
|
+
VALUE version = datadog_gem_version();
|
43
53
|
|
44
|
-
// Tags are heap-allocated, so after here we can't raise exceptions otherwise we'll leak this memory
|
54
|
+
// Tags and endpoint are heap-allocated, so after here we can't raise exceptions otherwise we'll leak this memory
|
45
55
|
// Start of exception-free zone to prevent leaks {{
|
56
|
+
ddog_Endpoint *endpoint = ddog_endpoint_from_url(char_slice_from_ruby_string(agent_base_url));
|
46
57
|
ddog_Vec_Tag tags = convert_tags(tags_as_array);
|
47
58
|
|
48
|
-
|
59
|
+
ddog_crasht_Config config = {
|
49
60
|
.additional_files = {},
|
50
61
|
// The Ruby VM already uses an alt stack to detect stack overflows so the crash handler must not overwrite it.
|
51
62
|
//
|
@@ -57,23 +68,26 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
57
68
|
// "Process.kill('SEGV', Process.pid)" gets run.
|
58
69
|
.create_alt_stack = false,
|
59
70
|
.endpoint = endpoint,
|
60
|
-
.resolve_frames =
|
71
|
+
.resolve_frames = DDOG_CRASHT_STACKTRACE_COLLECTION_ENABLED_WITH_SYMBOLS_IN_RECEIVER,
|
61
72
|
.timeout_secs = FIX2INT(upload_timeout_seconds),
|
73
|
+
// Waits for crash tracker to finish reporting the issue before letting the Ruby process die; see
|
74
|
+
// https://github.com/DataDog/libdatadog/pull/477 for details
|
75
|
+
.wait_for_receiver = true,
|
62
76
|
};
|
63
77
|
|
64
|
-
|
65
|
-
.
|
66
|
-
.
|
78
|
+
ddog_crasht_Metadata metadata = {
|
79
|
+
.library_name = DDOG_CHARSLICE_C("dd-trace-rb"),
|
80
|
+
.library_version = char_slice_from_ruby_string(version),
|
67
81
|
.family = DDOG_CHARSLICE_C("ruby"),
|
68
82
|
.tags = &tags,
|
69
83
|
};
|
70
84
|
|
71
|
-
|
85
|
+
ddog_crasht_EnvVar ld_library_path_env = {
|
72
86
|
.key = DDOG_CHARSLICE_C("LD_LIBRARY_PATH"),
|
73
87
|
.val = char_slice_from_ruby_string(ld_library_path),
|
74
88
|
};
|
75
89
|
|
76
|
-
|
90
|
+
ddog_crasht_ReceiverConfig receiver_config = {
|
77
91
|
.args = {},
|
78
92
|
.env = {.ptr = &ld_library_path_env, .len = 1},
|
79
93
|
.path_to_receiver_binary = char_slice_from_ruby_string(path_to_crashtracking_receiver_binary),
|
@@ -81,16 +95,17 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
81
95
|
.optional_stdout_filename = {},
|
82
96
|
};
|
83
97
|
|
84
|
-
|
98
|
+
ddog_crasht_Result result =
|
85
99
|
action == start_action ?
|
86
|
-
|
87
|
-
|
100
|
+
ddog_crasht_init_with_receiver(config, receiver_config, metadata) :
|
101
|
+
ddog_crasht_update_on_fork(config, receiver_config, metadata);
|
88
102
|
|
89
103
|
// Clean up before potentially raising any exceptions
|
90
104
|
ddog_Vec_Tag_drop(tags);
|
105
|
+
ddog_endpoint_drop(endpoint);
|
91
106
|
// }} End of exception-free zone to prevent leaks
|
92
107
|
|
93
|
-
if (result.tag ==
|
108
|
+
if (result.tag == DDOG_CRASHT_RESULT_ERR) {
|
94
109
|
rb_raise(rb_eRuntimeError, "Failed to start/update the crash tracker: %"PRIsVALUE, get_error_details_and_drop(&result.err));
|
95
110
|
}
|
96
111
|
|
@@ -98,9 +113,9 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
|
|
98
113
|
}
|
99
114
|
|
100
115
|
static VALUE _native_stop(DDTRACE_UNUSED VALUE _self) {
|
101
|
-
|
116
|
+
ddog_crasht_Result result = ddog_crasht_shutdown();
|
102
117
|
|
103
|
-
if (result.tag ==
|
118
|
+
if (result.tag == DDOG_CRASHT_RESULT_ERR) {
|
104
119
|
rb_raise(rb_eRuntimeError, "Failed to stop the crash tracker: %"PRIsVALUE, get_error_details_and_drop(&result.err));
|
105
120
|
}
|
106
121
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#include "datadog_ruby_common.h"
|
2
|
+
|
3
|
+
// IMPORTANT: Currently this file is copy-pasted between extensions. Make sure to update all versions when doing any change!
|
4
|
+
|
5
|
+
void raise_unexpected_type(VALUE value, const char *value_name, const char *type_name, const char *file, int line, const char* function_name) {
|
6
|
+
rb_exc_raise(
|
7
|
+
rb_exc_new_str(
|
8
|
+
rb_eTypeError,
|
9
|
+
rb_sprintf("wrong argument %"PRIsVALUE" for '%s' (expected a %s) at %s:%d:in `%s'",
|
10
|
+
rb_inspect(value),
|
11
|
+
value_name,
|
12
|
+
type_name,
|
13
|
+
file,
|
14
|
+
line,
|
15
|
+
function_name
|
16
|
+
)
|
17
|
+
)
|
18
|
+
);
|
19
|
+
}
|
20
|
+
|
21
|
+
VALUE datadog_gem_version(void) {
|
22
|
+
VALUE ddtrace_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
|
23
|
+
ENFORCE_TYPE(ddtrace_module, T_MODULE);
|
24
|
+
VALUE version_module = rb_const_get(ddtrace_module, rb_intern("VERSION"));
|
25
|
+
ENFORCE_TYPE(version_module, T_MODULE);
|
26
|
+
VALUE version_string = rb_const_get(version_module, rb_intern("STRING"));
|
27
|
+
ENFORCE_TYPE(version_string, T_STRING);
|
28
|
+
return version_string;
|
29
|
+
}
|
30
|
+
|
31
|
+
static VALUE log_failure_to_process_tag(VALUE err_details) {
|
32
|
+
VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
|
33
|
+
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
34
|
+
|
35
|
+
return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
|
36
|
+
}
|
37
|
+
|
38
|
+
__attribute__((warn_unused_result))
|
39
|
+
ddog_Vec_Tag convert_tags(VALUE tags_as_array) {
|
40
|
+
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
41
|
+
|
42
|
+
long tags_count = RARRAY_LEN(tags_as_array);
|
43
|
+
ddog_Vec_Tag tags = ddog_Vec_Tag_new();
|
44
|
+
|
45
|
+
for (long i = 0; i < tags_count; i++) {
|
46
|
+
VALUE name_value_pair = rb_ary_entry(tags_as_array, i);
|
47
|
+
|
48
|
+
if (!RB_TYPE_P(name_value_pair, T_ARRAY)) {
|
49
|
+
ddog_Vec_Tag_drop(tags);
|
50
|
+
ENFORCE_TYPE(name_value_pair, T_ARRAY);
|
51
|
+
}
|
52
|
+
|
53
|
+
// Note: We can index the array without checking its size first because rb_ary_entry returns Qnil if out of bounds
|
54
|
+
VALUE tag_name = rb_ary_entry(name_value_pair, 0);
|
55
|
+
VALUE tag_value = rb_ary_entry(name_value_pair, 1);
|
56
|
+
|
57
|
+
if (!(RB_TYPE_P(tag_name, T_STRING) && RB_TYPE_P(tag_value, T_STRING))) {
|
58
|
+
ddog_Vec_Tag_drop(tags);
|
59
|
+
ENFORCE_TYPE(tag_name, T_STRING);
|
60
|
+
ENFORCE_TYPE(tag_value, T_STRING);
|
61
|
+
}
|
62
|
+
|
63
|
+
ddog_Vec_Tag_PushResult push_result =
|
64
|
+
ddog_Vec_Tag_push(&tags, char_slice_from_ruby_string(tag_name), char_slice_from_ruby_string(tag_value));
|
65
|
+
|
66
|
+
if (push_result.tag == DDOG_VEC_TAG_PUSH_RESULT_ERR) {
|
67
|
+
// libdatadog validates tags and may catch invalid tags that ddtrace didn't actually catch.
|
68
|
+
// We warn users about such tags, and then just ignore them.
|
69
|
+
|
70
|
+
int exception_state;
|
71
|
+
rb_protect(log_failure_to_process_tag, get_error_details_and_drop(&push_result.err), &exception_state);
|
72
|
+
|
73
|
+
// Since we are calling into Ruby code, it may raise an exception. Ensure that dynamically-allocated tags
|
74
|
+
// get cleaned before propagating the exception.
|
75
|
+
if (exception_state) {
|
76
|
+
ddog_Vec_Tag_drop(tags);
|
77
|
+
rb_jump_tag(exception_state); // "Re-raise" exception
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
return tags;
|
83
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
// IMPORTANT: Currently this file is copy-pasted between extensions. Make sure to update all versions when doing any change!
|
4
|
+
|
5
|
+
#include <ruby.h>
|
6
|
+
#include <datadog/profiling.h>
|
7
|
+
|
8
|
+
// Used to mark symbols to be exported to the outside of the extension.
|
9
|
+
// Consider very carefully before tagging a function with this.
|
10
|
+
#define DDTRACE_EXPORT __attribute__ ((visibility ("default")))
|
11
|
+
|
12
|
+
// Used to mark function arguments that are deliberately left unused
|
13
|
+
#ifdef __GNUC__
|
14
|
+
#define DDTRACE_UNUSED __attribute__((unused))
|
15
|
+
#else
|
16
|
+
#define DDTRACE_UNUSED
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#define ADD_QUOTES_HELPER(x) #x
|
20
|
+
#define ADD_QUOTES(x) ADD_QUOTES_HELPER(x)
|
21
|
+
|
22
|
+
// Ruby has a Check_Type(value, type) that is roughly equivalent to this BUT Ruby's version is rather cryptic when it fails
|
23
|
+
// e.g. "wrong argument type nil (expected String)". This is a replacement that prints more information to help debugging.
|
24
|
+
#define ENFORCE_TYPE(value, type) \
|
25
|
+
{ if (RB_UNLIKELY(!RB_TYPE_P(value, type))) raise_unexpected_type(value, ADD_QUOTES(value), ADD_QUOTES(type), __FILE__, __LINE__, __func__); }
|
26
|
+
|
27
|
+
#define ENFORCE_BOOLEAN(value) \
|
28
|
+
{ if (RB_UNLIKELY(value != Qtrue && value != Qfalse)) raise_unexpected_type(value, ADD_QUOTES(value), "true or false", __FILE__, __LINE__, __func__); }
|
29
|
+
|
30
|
+
NORETURN(void raise_unexpected_type(VALUE value, const char *value_name, const char *type_name, const char *file, int line, const char* function_name));
|
31
|
+
|
32
|
+
// Helper to retrieve Datadog::VERSION::STRING
|
33
|
+
VALUE datadog_gem_version(void);
|
34
|
+
|
35
|
+
static inline ddog_CharSlice char_slice_from_ruby_string(VALUE string) {
|
36
|
+
ENFORCE_TYPE(string, T_STRING);
|
37
|
+
ddog_CharSlice char_slice = {.ptr = RSTRING_PTR(string), .len = RSTRING_LEN(string)};
|
38
|
+
return char_slice;
|
39
|
+
}
|
40
|
+
|
41
|
+
__attribute__((warn_unused_result))
|
42
|
+
ddog_Vec_Tag convert_tags(VALUE tags_as_array);
|
43
|
+
|
44
|
+
static inline VALUE ruby_string_from_error(const ddog_Error *error) {
|
45
|
+
ddog_CharSlice char_slice = ddog_Error_message(error);
|
46
|
+
return rb_str_new(char_slice.ptr, char_slice.len);
|
47
|
+
}
|
48
|
+
|
49
|
+
static inline VALUE get_error_details_and_drop(ddog_Error *error) {
|
50
|
+
VALUE result = ruby_string_from_error(error);
|
51
|
+
ddog_Error_drop(error);
|
52
|
+
return result;
|
53
|
+
}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# rubocop:disable Style/StderrPuts
|
2
|
+
# rubocop:disable Style/GlobalVars
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require_relative '../libdatadog_extconf_helpers'
|
6
|
+
|
7
|
+
def skip_building_extension!(reason)
|
8
|
+
$stderr.puts(
|
9
|
+
"WARN: Skipping build of libdatadog_api (#{reason}). Some functionality will not be available."
|
10
|
+
)
|
11
|
+
|
12
|
+
fail_install_if_missing_extension = ENV['DD_FAIL_INSTALL_IF_MISSING_EXTENSION'].to_s.strip.downcase == 'true'
|
13
|
+
|
14
|
+
if fail_install_if_missing_extension
|
15
|
+
require 'mkmf'
|
16
|
+
Logging.message("[datadog] Failure cause: #{reason}")
|
17
|
+
else
|
18
|
+
File.write('Makefile', 'all install clean: # dummy makefile that does nothing')
|
19
|
+
end
|
20
|
+
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
if ENV['DD_NO_EXTENSION'].to_s.strip.downcase == 'true'
|
25
|
+
skip_building_extension!('the `DD_NO_EXTENSION` environment variable is/was set to `true` during installation')
|
26
|
+
end
|
27
|
+
skip_building_extension!('current Ruby VM is not supported') if RUBY_ENGINE != 'ruby'
|
28
|
+
skip_building_extension!('Microsoft Windows is not supported') if Gem.win_platform?
|
29
|
+
skip_building_extension!('issue setting up `libdatadog` gem') if Datadog::LibdatadogExtconfHelpers.libdatadog_issue?
|
30
|
+
|
31
|
+
require 'mkmf'
|
32
|
+
|
33
|
+
# Because we can't control what compiler versions our customers use, shipping with -Werror by default is a no-go.
|
34
|
+
# But we can enable it in CI, so that we quickly spot any new warnings that just got introduced.
|
35
|
+
append_cflags '-Werror' if ENV['DATADOG_GEM_CI'] == 'true'
|
36
|
+
|
37
|
+
# Older gcc releases may not default to C99 and we need to ask for this. This is also used:
|
38
|
+
# * by upstream Ruby -- search for gnu99 in the codebase
|
39
|
+
# * by msgpack, another datadog gem dependency
|
40
|
+
# (https://github.com/msgpack/msgpack-ruby/blob/18ce08f6d612fe973843c366ac9a0b74c4e50599/ext/msgpack/extconf.rb#L8)
|
41
|
+
append_cflags '-std=gnu99'
|
42
|
+
|
43
|
+
# Allow defining variables at any point in a function
|
44
|
+
append_cflags '-Wno-declaration-after-statement'
|
45
|
+
|
46
|
+
# If we forget to include a Ruby header, the function call may still appear to work, but then
|
47
|
+
# cause a segfault later. Let's ensure that never happens.
|
48
|
+
append_cflags '-Werror-implicit-function-declaration'
|
49
|
+
|
50
|
+
# Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
|
51
|
+
append_cflags '-Wunused-parameter'
|
52
|
+
|
53
|
+
# The native extension is not intended to expose any symbols/functions for other native libraries to use;
|
54
|
+
# the sole exception being `Init_libdatadog_api` which needs to be visible for Ruby to call it when
|
55
|
+
# it `dlopen`s the library.
|
56
|
+
#
|
57
|
+
# By setting this compiler flag, we tell it to assume that everything is private unless explicitly stated.
|
58
|
+
# For more details see https://gcc.gnu.org/wiki/Visibility
|
59
|
+
append_cflags '-fvisibility=hidden'
|
60
|
+
|
61
|
+
# Avoid legacy C definitions
|
62
|
+
append_cflags '-Wold-style-definition'
|
63
|
+
|
64
|
+
# Enable all other compiler warnings
|
65
|
+
append_cflags '-Wall'
|
66
|
+
append_cflags '-Wextra'
|
67
|
+
|
68
|
+
if ENV['DDTRACE_DEBUG'] == 'true'
|
69
|
+
$defs << '-DDD_DEBUG'
|
70
|
+
CONFIG['optflags'] = '-O0'
|
71
|
+
CONFIG['debugflags'] = '-ggdb3'
|
72
|
+
end
|
73
|
+
|
74
|
+
# If we got here, libdatadog is available and loaded
|
75
|
+
ENV['PKG_CONFIG_PATH'] = "#{ENV['PKG_CONFIG_PATH']}:#{Libdatadog.pkgconfig_folder}"
|
76
|
+
Logging.message("[datadog] PKG_CONFIG_PATH set to #{ENV['PKG_CONFIG_PATH'].inspect}\n")
|
77
|
+
$stderr.puts("Using libdatadog #{Libdatadog::VERSION} from #{Libdatadog.pkgconfig_folder}")
|
78
|
+
|
79
|
+
unless pkg_config('datadog_profiling_with_rpath')
|
80
|
+
Logging.message("[datadog] Ruby detected the pkg-config command is #{$PKGCONFIG.inspect}\n")
|
81
|
+
|
82
|
+
if Datadog::LibdatadogExtconfHelpers.pkg_config_missing?
|
83
|
+
skip_building_extension!('the `pkg-config` system tool is missing')
|
84
|
+
else
|
85
|
+
skip_building_extension!('there was a problem in setting up the `libdatadog` dependency')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# See comments on the helper methods being used for why we need to additionally set this.
|
90
|
+
# The extremely excessive escaping around ORIGIN below seems to be correct and was determined after a lot of
|
91
|
+
# experimentation. We need to get these special characters across a lot of tools untouched...
|
92
|
+
extra_relative_rpaths = [
|
93
|
+
Datadog::LibdatadogExtconfHelpers.libdatadog_folder_relative_to_native_lib_folder(current_folder: __dir__),
|
94
|
+
*Datadog::LibdatadogExtconfHelpers.libdatadog_folder_relative_to_ruby_extensions_folders,
|
95
|
+
]
|
96
|
+
extra_relative_rpaths.each { |folder| $LDFLAGS += " -Wl,-rpath,$$$\\\\{ORIGIN\\}/#{folder.to_str}" }
|
97
|
+
Logging.message("[datadog] After pkg-config $LDFLAGS were set to: #{$LDFLAGS.inspect}\n")
|
98
|
+
|
99
|
+
# Tag the native extension library with the Ruby version and Ruby platform.
|
100
|
+
# This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
|
101
|
+
# the wrong library is never loaded.
|
102
|
+
# When requiring, we need to use the exact same string, including the version and the platform.
|
103
|
+
EXTENSION_NAME = "libdatadog_api.#{RUBY_VERSION[/\d+.\d+/]}_#{RUBY_PLATFORM}".freeze
|
104
|
+
|
105
|
+
create_makefile(EXTENSION_NAME)
|
106
|
+
|
107
|
+
# rubocop:enable Style/GlobalVars
|
108
|
+
# rubocop:enable Style/StderrPuts
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Developing on macOS
|
2
|
+
|
3
|
+
As of this writing (August 2024), the libdatadog builds on rubygems.org only support Linux.
|
4
|
+
|
5
|
+
We don't officially support using libdatadog for Ruby on other platforms yet, but it is possible to use it for local development on macOS.
|
6
|
+
(**Note that you don't need these instructions if you develop inside docker.**)
|
7
|
+
|
8
|
+
Here's how you can do so:
|
9
|
+
|
10
|
+
1. [Install rust](https://www.rust-lang.org/tools/install)
|
11
|
+
2. Install `cbindgen`: `cargo install cbindgen`
|
12
|
+
3. Clone [libdatadog](https://github.com/datadog/libdatadog)
|
13
|
+
4. Create a folder for building into based on your ruby platform:
|
14
|
+
|
15
|
+
```
|
16
|
+
export DD_RUBY_PLATFORM=`ruby -e 'puts Gem::Platform.local.to_s'`
|
17
|
+
mkdir -p my-libdatadog-build/$DD_RUBY_PLATFORM
|
18
|
+
```
|
19
|
+
|
20
|
+
5. Build libdatadog into this folder: `./build-profiling-ffi.sh my-libdatadog-build/$DD_RUBY_PLATFORM`
|
21
|
+
6. Tell the Ruby where to find libdatadog: `export LIBDATADOG_VENDOR_OVERRIDE=/full/path/to/my-libdatadog-build/` (Notice no platform here)
|
22
|
+
7. Run `bundle exec rake clean compile`
|
23
|
+
|
24
|
+
If you additionally want to run the profiler test suite, also remember to `export DD_PROFILING_MACOS_TESTING=true` and re-run `rake clean compile`.
|
25
|
+
|
26
|
+
These instructions can quickly get outdated, so feel free to open an issue if they're not working (and/or ping @ivoanjo).
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
# Contains a bunch of shared helpers that get used during building of extensions that link to libdatadog
|
8
|
+
module LibdatadogExtconfHelpers
|
9
|
+
# Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
|
10
|
+
# may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
|
11
|
+
LIBDATADOG_VERSION = '~> 12.0.0.1.0'
|
12
|
+
|
13
|
+
# Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
|
14
|
+
# libdatadog are moved after the extension gets compiled.
|
15
|
+
#
|
16
|
+
# Because the libdatadog native library is installed on a non-standard system path, in order for it to be
|
17
|
+
# found by the system dynamic linker (e.g. what takes care of dlopen(), which is used to load
|
18
|
+
# native extensions), we need to add a "runpath" -- a list of folders to search for libdatadog.
|
19
|
+
#
|
20
|
+
# This runpath gets hardcoded at native library linking time. You can look at it using the `readelf` tool in
|
21
|
+
# Linux: e.g. `readelf -d datadog_profiling_native_extension.2.7.3_x86_64-linux.so`.
|
22
|
+
#
|
23
|
+
# In older versions of the datadog gem, we only set as runpath an absolute path to libdatadog.
|
24
|
+
# (This gets set automatically by the call
|
25
|
+
# to `pkg_config('datadog_profiling_with_rpath')` in `extconf.rb`). This worked fine as long as libdatadog was **NOT**
|
26
|
+
# moved from the folder it was present at datadog gem installation/linking time.
|
27
|
+
#
|
28
|
+
# Unfortunately, environments such as Heroku and AWS Elastic Beanstalk move gems around in the filesystem after
|
29
|
+
# installation. Thus, the profiling native extension could not be loaded in these environments
|
30
|
+
# (see https://github.com/DataDog/dd-trace-rb/issues/2067) because libdatadog could not be found.
|
31
|
+
#
|
32
|
+
# To workaround this issue, this method computes the **relative** path between the folder where
|
33
|
+
# native extensions are going to be installed and the folder where libdatadog is installed, and returns it
|
34
|
+
# to be set as an additional runpath. (Yes, you can set multiple runpath folders to be searched).
|
35
|
+
#
|
36
|
+
# This way, if both gems are moved together (and it turns out that they are in these environments),
|
37
|
+
# the relative path can still be traversed to find libdatadog.
|
38
|
+
#
|
39
|
+
# This is incredibly awful, and it's kinda bizarre how it's not possible to just find these paths at runtime
|
40
|
+
# and set them correctly; rather than needing to set stuff at linking-time and then praying to $deity that
|
41
|
+
# weird moves don't happen.
|
42
|
+
#
|
43
|
+
# As a curiosity, `LD_LIBRARY_PATH` can be used to influence the folders that get searched but **CANNOT BE
|
44
|
+
# SET DYNAMICALLY**, e.g. it needs to be set at the start of the process (Ruby VM) and thus it's not something
|
45
|
+
# we could setup when doing a `require`.
|
46
|
+
#
|
47
|
+
def self.libdatadog_folder_relative_to_native_lib_folder(
|
48
|
+
current_folder:,
|
49
|
+
libdatadog_pkgconfig_folder: Libdatadog.pkgconfig_folder
|
50
|
+
)
|
51
|
+
return unless libdatadog_pkgconfig_folder
|
52
|
+
|
53
|
+
native_lib_folder = "#{current_folder}/../../lib/"
|
54
|
+
libdatadog_lib_folder = "#{libdatadog_pkgconfig_folder}/../"
|
55
|
+
|
56
|
+
Pathname.new(libdatadog_lib_folder).relative_path_from(Pathname.new(native_lib_folder)).to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
# In https://github.com/DataDog/dd-trace-rb/pull/3582 we got a report of a customer for which the native extension
|
60
|
+
# only got installed into the extensions folder.
|
61
|
+
#
|
62
|
+
# But then this fix was not enough to fully get them moving because then they started to see the issue from
|
63
|
+
# https://github.com/DataDog/dd-trace-rb/issues/2067 / https://github.com/DataDog/dd-trace-rb/pull/2125 :
|
64
|
+
#
|
65
|
+
# > Profiling was requested but is not supported, profiling disabled: There was an error loading the profiling
|
66
|
+
# > native extension due to 'RuntimeError Failure to load datadog_profiling_native_extension.3.2.2_x86_64-linux
|
67
|
+
# > due to libdatadog_profiling.so: cannot open shared object file: No such file or directory
|
68
|
+
#
|
69
|
+
# The problem is that when loading the native extension from the extensions directory, the relative rpath we add
|
70
|
+
# with the #libdatadog_folder_relative_to_native_lib_folder helper above is not correct, we need to add a relative
|
71
|
+
# rpath to the extensions directory.
|
72
|
+
#
|
73
|
+
# So how do we find the full path where the native extension is placed?
|
74
|
+
# * From https://github.com/ruby/ruby/blob/83f02d42e0a3c39661dc99c049ab9a70ff227d5b/lib/bundler/runtime.rb#L166
|
75
|
+
# `extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"] + Dir["#{Gem.dir}/bundler/gems/extensions/*/*/*"]`
|
76
|
+
# we get that's in one of two fixed subdirectories of `Gem.dir`
|
77
|
+
# * From https://github.com/ruby/ruby/blob/83f02d42e0a3c39661dc99c049ab9a70ff227d5b/lib/rubygems/basic_specification.rb#L111-L115
|
78
|
+
# we get the structure of the subdirectory (platform/extension_api_version/gem_and_version)
|
79
|
+
#
|
80
|
+
# Thus, `Gem.dir` of `/var/app/current/vendor/bundle/ruby/3.2.0` becomes (for instance)
|
81
|
+
# `/var/app/current/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/datadog-2.0.0/` or
|
82
|
+
# `/var/app/current/vendor/bundle/ruby/3.2.0/bundler/gems/extensions/x86_64-linux/3.2.0/datadog-2.0.0/`
|
83
|
+
#
|
84
|
+
# We then compute the relative path between these folders and the libdatadog folder, and use that as a relative path.
|
85
|
+
def self.libdatadog_folder_relative_to_ruby_extensions_folders(
|
86
|
+
gem_dir: Gem.dir,
|
87
|
+
libdatadog_pkgconfig_folder: Libdatadog.pkgconfig_folder
|
88
|
+
)
|
89
|
+
return unless libdatadog_pkgconfig_folder
|
90
|
+
|
91
|
+
# For the purposes of calculating a folder relative to the other, we don't actually NEED to fill in the
|
92
|
+
# platform, extension_api_version and gem version. We're basically just after how many folders it is deep from
|
93
|
+
# the Gem.dir.
|
94
|
+
expected_ruby_extensions_folders = [
|
95
|
+
"#{gem_dir}/extensions/platform/extension_api_version/datadog_version/",
|
96
|
+
"#{gem_dir}/bundler/gems/extensions/platform/extension_api_version/datadog_version/",
|
97
|
+
]
|
98
|
+
libdatadog_lib_folder = "#{libdatadog_pkgconfig_folder}/../"
|
99
|
+
|
100
|
+
expected_ruby_extensions_folders.map do |folder|
|
101
|
+
Pathname.new(libdatadog_lib_folder).relative_path_from(Pathname.new(folder)).to_s
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# mkmf sets $PKGCONFIG after the `pkg_config` gets used in extconf.rb. When `pkg_config` is unsuccessful, we use
|
106
|
+
# this helper to decide if we can show more specific error message vs a generic "something went wrong".
|
107
|
+
def self.pkg_config_missing?(command: $PKGCONFIG) # rubocop:disable Style/GlobalVars
|
108
|
+
pkg_config_available = command && xsystem("#{command} --version")
|
109
|
+
|
110
|
+
pkg_config_available != true
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.try_loading_libdatadog
|
114
|
+
gem 'libdatadog', LIBDATADOG_VERSION
|
115
|
+
require 'libdatadog'
|
116
|
+
nil
|
117
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
118
|
+
if block_given?
|
119
|
+
yield e
|
120
|
+
else
|
121
|
+
e
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.libdatadog_issue?
|
126
|
+
try_loading_libdatadog { |_exception| return true }
|
127
|
+
Libdatadog.pkgconfig_folder.nil?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|