datadog 2.1.0 → 2.3.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 +101 -1
- data/ext/datadog_profiling_loader/extconf.rb +15 -15
- 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 +132 -44
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +49 -26
- 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 +90 -37
- data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +81 -19
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +110 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +57 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +69 -62
- data/ext/datadog_profiling_native_extension/heap_recorder.c +34 -6
- 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 +3 -3
- 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 -126
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +64 -138
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +17 -11
- data/ext/datadog_profiling_native_extension/profiling.c +0 -2
- 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.c +1 -1
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +27 -8
- 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 +20 -7
- data/ext/libdatadog_api/datadog_ruby_common.c +110 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +57 -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/contrib/graphql/appsec_trace.rb +49 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +73 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +68 -0
- data/lib/datadog/appsec/contrib/graphql/integration.rb +41 -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 +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +1 -1
- data/lib/datadog/appsec/extensions.rb +1 -0
- data/lib/datadog/appsec/processor/actions.rb +1 -1
- data/lib/datadog/appsec/response.rb +15 -1
- data/lib/datadog/appsec.rb +1 -0
- data/lib/datadog/core/configuration/components.rb +17 -12
- data/lib/datadog/core/configuration/settings.rb +93 -7
- data/lib/datadog/core/configuration.rb +3 -17
- 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/deprecations.rb +58 -0
- data/lib/datadog/core/diagnostics/environment_logger.rb +8 -11
- data/lib/datadog/core/environment/yjit.rb +5 -0
- data/lib/datadog/core/runtime/ext.rb +1 -0
- data/lib/datadog/core/runtime/metrics.rb +6 -0
- data/lib/datadog/core/telemetry/component.rb +154 -0
- data/lib/datadog/core/telemetry/emitter.rb +9 -11
- data/lib/datadog/core/telemetry/event.rb +132 -26
- data/lib/datadog/core/telemetry/ext.rb +3 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +11 -13
- 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/logging.rb +35 -0
- data/lib/datadog/core/telemetry/metric.rb +167 -0
- data/lib/datadog/core/telemetry/metrics_collection.rb +81 -0
- data/lib/datadog/core/telemetry/metrics_manager.rb +81 -0
- data/lib/datadog/core/telemetry/request.rb +1 -1
- data/lib/datadog/core/telemetry/worker.rb +173 -0
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +102 -0
- data/lib/datadog/core/utils/only_once_successful.rb +76 -0
- data/lib/datadog/core.rb +2 -19
- data/lib/datadog/kit/appsec/events.rb +2 -4
- data/lib/datadog/opentelemetry/sdk/propagator.rb +5 -10
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +15 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +23 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +24 -11
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +17 -17
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +11 -13
- data/lib/datadog/profiling/collectors/info.rb +3 -3
- data/lib/datadog/profiling/collectors/thread_context.rb +4 -2
- data/lib/datadog/profiling/component.rb +85 -90
- data/lib/datadog/profiling/exporter.rb +3 -3
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +410 -0
- data/lib/datadog/profiling/ext.rb +21 -21
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +8 -6
- 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 +31 -25
- 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 +5 -5
- data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +1 -1
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -6
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +9 -4
- data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +3 -2
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +1 -5
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -1
- data/lib/datadog/tracing/contrib/active_support/cache/event.rb +32 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +156 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events.rb +34 -0
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +45 -41
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +17 -40
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +29 -6
- data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +16 -4
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +33 -29
- data/lib/datadog/tracing/contrib/analytics.rb +5 -0
- data/lib/datadog/tracing/contrib/ext.rb +14 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +8 -2
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +166 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +28 -0
- data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/consumer_group_event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +3 -3
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +16 -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/pg/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +4 -1
- 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/racecar/event.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/rails/patcher.rb +7 -0
- data/lib/datadog/tracing/contrib/rails/runner.rb +95 -0
- 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/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +3 -1
- data/lib/datadog/tracing/distributed/datadog.rb +2 -2
- data/lib/datadog/tracing/distributed/propagation.rb +9 -2
- data/lib/datadog/tracing/distributed/trace_context.rb +3 -2
- data/lib/datadog/tracing/metadata/errors.rb +9 -1
- data/lib/datadog/tracing/metadata/ext.rb +4 -0
- data/lib/datadog/tracing/pipeline/span_filter.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 +9 -4
- data/lib/datadog/tracing/trace_operation.rb +7 -3
- data/lib/datadog/tracing/trace_segment.rb +4 -1
- data/lib/datadog/tracing/tracer.rb +9 -2
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -0
- data/lib/datadog/tracing.rb +5 -1
- data/lib/datadog/version.rb +2 -2
- metadata +43 -12
- data/lib/datadog/core/telemetry/client.rb +0 -95
- data/lib/datadog/core/telemetry/heartbeat.rb +0 -33
- data/lib/datadog/profiling/crashtracker.rb +0 -91
- data/lib/datadog/profiling/ext/forking.rb +0 -98
@@ -1,11 +1,16 @@
|
|
1
1
|
# rubocop:disable Style/StderrPuts
|
2
2
|
# rubocop:disable Style/GlobalVars
|
3
3
|
|
4
|
-
require_relative
|
4
|
+
require_relative "native_extension_helpers"
|
5
|
+
require_relative "../libdatadog_extconf_helpers"
|
5
6
|
|
6
7
|
SKIPPED_REASON_FILE = "#{__dir__}/skipped_reason.txt".freeze
|
7
8
|
# Not a problem if the file doesn't exist or we can't delete it
|
8
|
-
|
9
|
+
begin
|
10
|
+
File.delete(SKIPPED_REASON_FILE)
|
11
|
+
rescue
|
12
|
+
nil
|
13
|
+
end
|
9
14
|
|
10
15
|
def skip_building_extension!(reason)
|
11
16
|
fail_install_if_missing_extension =
|
@@ -24,13 +29,13 @@ def skip_building_extension!(reason)
|
|
24
29
|
)
|
25
30
|
|
26
31
|
if fail_install_if_missing_extension
|
27
|
-
require
|
32
|
+
require "mkmf"
|
28
33
|
Logging.message(
|
29
|
-
|
34
|
+
"[datadog] Failure cause: " \
|
30
35
|
"#{Datadog::Profiling::NativeExtensionHelpers::Supported.render_skipped_reason_file(**reason)}\n"
|
31
36
|
)
|
32
37
|
else
|
33
|
-
File.write(
|
38
|
+
File.write("Makefile", "all install clean: # dummy makefile that does nothing")
|
34
39
|
end
|
35
40
|
|
36
41
|
exit
|
@@ -63,17 +68,17 @@ $stderr.puts(
|
|
63
68
|
|
64
69
|
# NOTE: we MUST NOT require 'mkmf' before we check the #skip_building_extension? because the require triggers checks
|
65
70
|
# that may fail on an environment not properly setup for building Ruby extensions.
|
66
|
-
require
|
71
|
+
require "mkmf"
|
67
72
|
|
68
73
|
Logging.message("[datadog] Using compiler:\n")
|
69
|
-
xsystem("#{CONFIG[
|
74
|
+
xsystem("#{CONFIG["CC"]} -v")
|
70
75
|
Logging.message("[datadog] End of compiler information\n")
|
71
76
|
|
72
77
|
# mkmf on modern Rubies actually has an append_cflags that does something similar
|
73
78
|
# (see https://github.com/ruby/ruby/pull/5760), but as usual we need a bit more boilerplate to deal with legacy Rubies
|
74
79
|
def add_compiler_flag(flag)
|
75
80
|
if try_cflags(flag)
|
76
|
-
$CFLAGS <<
|
81
|
+
$CFLAGS << " " << flag
|
77
82
|
else
|
78
83
|
$stderr.puts("WARNING: '#{flag}' not accepted by compiler, skipping it")
|
79
84
|
end
|
@@ -81,23 +86,23 @@ end
|
|
81
86
|
|
82
87
|
# Because we can't control what compiler versions our customers use, shipping with -Werror by default is a no-go.
|
83
88
|
# But we can enable it in CI, so that we quickly spot any new warnings that just got introduced.
|
84
|
-
add_compiler_flag
|
89
|
+
add_compiler_flag "-Werror" if ENV["DATADOG_GEM_CI"] == "true"
|
85
90
|
|
86
91
|
# Older gcc releases may not default to C99 and we need to ask for this. This is also used:
|
87
92
|
# * by upstream Ruby -- search for gnu99 in the codebase
|
88
93
|
# * by msgpack, another datadog gem dependency
|
89
94
|
# (https://github.com/msgpack/msgpack-ruby/blob/18ce08f6d612fe973843c366ac9a0b74c4e50599/ext/msgpack/extconf.rb#L8)
|
90
|
-
add_compiler_flag
|
95
|
+
add_compiler_flag "-std=gnu99"
|
91
96
|
|
92
97
|
# Gets really noisy when we include the MJIT header, let's omit it (TODO: Use #pragma GCC diagnostic instead?)
|
93
|
-
add_compiler_flag
|
98
|
+
add_compiler_flag "-Wno-unused-function"
|
94
99
|
|
95
100
|
# Allow defining variables at any point in a function
|
96
|
-
add_compiler_flag
|
101
|
+
add_compiler_flag "-Wno-declaration-after-statement"
|
97
102
|
|
98
103
|
# If we forget to include a Ruby header, the function call may still appear to work, but then
|
99
104
|
# cause a segfault later. Let's ensure that never happens.
|
100
|
-
add_compiler_flag
|
105
|
+
add_compiler_flag "-Werror-implicit-function-declaration"
|
101
106
|
|
102
107
|
# The native extension is not intended to expose any symbols/functions for other native libraries to use;
|
103
108
|
# the sole exception being `Init_datadog_profiling_native_extension` which needs to be visible for Ruby to call it when
|
@@ -105,22 +110,22 @@ add_compiler_flag '-Werror-implicit-function-declaration'
|
|
105
110
|
#
|
106
111
|
# By setting this compiler flag, we tell it to assume that everything is private unless explicitly stated.
|
107
112
|
# For more details see https://gcc.gnu.org/wiki/Visibility
|
108
|
-
add_compiler_flag
|
113
|
+
add_compiler_flag "-fvisibility=hidden"
|
109
114
|
|
110
115
|
# Avoid legacy C definitions
|
111
|
-
add_compiler_flag
|
116
|
+
add_compiler_flag "-Wold-style-definition"
|
112
117
|
|
113
118
|
# Enable all other compiler warnings
|
114
|
-
add_compiler_flag
|
115
|
-
add_compiler_flag
|
119
|
+
add_compiler_flag "-Wall"
|
120
|
+
add_compiler_flag "-Wextra"
|
116
121
|
|
117
|
-
if ENV[
|
118
|
-
$defs <<
|
119
|
-
CONFIG[
|
120
|
-
CONFIG[
|
122
|
+
if ENV["DDTRACE_DEBUG"] == "true"
|
123
|
+
$defs << "-DDD_DEBUG"
|
124
|
+
CONFIG["optflags"] = "-O0"
|
125
|
+
CONFIG["debugflags"] = "-ggdb3"
|
121
126
|
end
|
122
127
|
|
123
|
-
if RUBY_PLATFORM.include?(
|
128
|
+
if RUBY_PLATFORM.include?("linux")
|
124
129
|
# Supposedly, the correct way to do this is
|
125
130
|
# ```
|
126
131
|
# have_library 'pthread'
|
@@ -128,77 +133,77 @@ if RUBY_PLATFORM.include?('linux')
|
|
128
133
|
# ```
|
129
134
|
# but it's slower to build
|
130
135
|
# so instead we just assume that we have the function we need on Linux, and nowhere else
|
131
|
-
$defs <<
|
136
|
+
$defs << "-DHAVE_PTHREAD_GETCPUCLOCKID"
|
137
|
+
|
138
|
+
# Not available on macOS
|
139
|
+
$defs << "-DHAVE_CLOCK_MONOTONIC_COARSE"
|
132
140
|
end
|
133
141
|
|
134
|
-
have_func
|
142
|
+
have_func "malloc_stats"
|
135
143
|
|
136
144
|
# On older Rubies, rb_postponed_job_preregister/rb_postponed_job_trigger did not exist
|
137
|
-
$defs <<
|
145
|
+
$defs << "-DNO_POSTPONED_TRIGGER" if RUBY_VERSION < "3.3"
|
138
146
|
|
139
147
|
# On older Rubies, M:N threads were not available
|
140
|
-
$defs <<
|
148
|
+
$defs << "-DNO_MN_THREADS_AVAILABLE" if RUBY_VERSION < "3.3"
|
141
149
|
|
142
150
|
# On older Rubies, we did not need to include the ractor header (this was built into the MJIT header)
|
143
|
-
$defs <<
|
151
|
+
$defs << "-DNO_RACTOR_HEADER_INCLUDE" if RUBY_VERSION < "3.3"
|
144
152
|
|
145
153
|
# On older Rubies, some of the Ractor internal APIs were directly accessible
|
146
|
-
$defs <<
|
154
|
+
$defs << "-DUSE_RACTOR_INTERNAL_APIS_DIRECTLY" if RUBY_VERSION < "3.3"
|
147
155
|
|
148
156
|
# On older Rubies, there was no struct rb_native_thread. See private_vm_api_acccess.c for details.
|
149
|
-
$defs <<
|
157
|
+
$defs << "-DNO_RB_NATIVE_THREAD" if RUBY_VERSION < "3.2"
|
150
158
|
|
151
159
|
# On older Rubies, there was no struct rb_thread_sched (it was struct rb_global_vm_lock_struct)
|
152
|
-
$defs <<
|
160
|
+
$defs << "-DNO_RB_THREAD_SCHED" if RUBY_VERSION < "3.2"
|
153
161
|
|
154
162
|
# On older Rubies, the first_lineno inside a location was a VALUE and not a int (https://github.com/ruby/ruby/pull/6430)
|
155
|
-
$defs <<
|
163
|
+
$defs << "-DNO_INT_FIRST_LINENO" if RUBY_VERSION < "3.2"
|
156
164
|
|
157
165
|
# On older Rubies, "pop" was not a primitive operation
|
158
|
-
$defs <<
|
166
|
+
$defs << "-DNO_PRIMITIVE_POP" if RUBY_VERSION < "3.2"
|
159
167
|
|
160
168
|
# On older Rubies, there was no tid member in the internal thread structure
|
161
|
-
$defs <<
|
169
|
+
$defs << "-DNO_THREAD_TID" if RUBY_VERSION < "3.1"
|
162
170
|
|
163
171
|
# On older Rubies, there was no jit_return member on the rb_control_frame_t struct
|
164
|
-
$defs <<
|
172
|
+
$defs << "-DNO_JIT_RETURN" if RUBY_VERSION < "3.1"
|
165
173
|
|
166
174
|
# On older Rubies, rb_gc_force_recycle allowed to free objects in a way that
|
167
175
|
# would be invisible to free tracepoints, finalizers and without cleaning
|
168
176
|
# obj_to_id_tbl mappings.
|
169
|
-
$defs <<
|
170
|
-
|
171
|
-
# On older Rubies, we need to use a backported version of this function. See private_vm_api_access.h for details.
|
172
|
-
$defs << '-DUSE_BACKPORTED_RB_PROFILE_FRAME_METHOD_NAME' if RUBY_VERSION < '3'
|
177
|
+
$defs << "-DHAVE_WORKING_RB_GC_FORCE_RECYCLE" if RUBY_VERSION < "3.1"
|
173
178
|
|
174
179
|
# On older Rubies, there are no Ractors
|
175
|
-
$defs <<
|
180
|
+
$defs << "-DNO_RACTORS" if RUBY_VERSION < "3"
|
176
181
|
|
177
182
|
# On older Rubies, rb_imemo_name did not exist
|
178
|
-
$defs <<
|
183
|
+
$defs << "-DNO_IMEMO_NAME" if RUBY_VERSION < "3"
|
179
184
|
|
180
185
|
# On older Rubies, objects would not move
|
181
|
-
$defs <<
|
186
|
+
$defs << "-DNO_T_MOVED" if RUBY_VERSION < "2.7"
|
182
187
|
|
183
188
|
# On older Rubies, there was no RUBY_SEEN_OBJ_ID flag
|
184
|
-
$defs <<
|
189
|
+
$defs << "-DNO_SEEN_OBJ_ID_FLAG" if RUBY_VERSION < "2.7"
|
185
190
|
|
186
191
|
# On older Rubies, rb_global_vm_lock_struct did not include the owner field
|
187
|
-
$defs <<
|
192
|
+
$defs << "-DNO_GVL_OWNER" if RUBY_VERSION < "2.6"
|
188
193
|
|
189
194
|
# On older Rubies, there was no thread->invoke_arg
|
190
|
-
$defs <<
|
195
|
+
$defs << "-DNO_THREAD_INVOKE_ARG" if RUBY_VERSION < "2.6"
|
191
196
|
|
192
197
|
# If we got here, libdatadog is available and loaded
|
193
|
-
ENV[
|
194
|
-
Logging.message("[datadog] PKG_CONFIG_PATH set to #{ENV[
|
198
|
+
ENV["PKG_CONFIG_PATH"] = "#{ENV["PKG_CONFIG_PATH"]}:#{Libdatadog.pkgconfig_folder}"
|
199
|
+
Logging.message("[datadog] PKG_CONFIG_PATH set to #{ENV["PKG_CONFIG_PATH"].inspect}\n")
|
195
200
|
$stderr.puts("Using libdatadog #{Libdatadog::VERSION} from #{Libdatadog.pkgconfig_folder}")
|
196
201
|
|
197
|
-
unless pkg_config(
|
202
|
+
unless pkg_config("datadog_profiling_with_rpath")
|
198
203
|
Logging.message("[datadog] Ruby detected the pkg-config command is #{$PKGCONFIG.inspect}\n")
|
199
204
|
|
200
205
|
skip_building_extension!(
|
201
|
-
if Datadog::
|
206
|
+
if Datadog::LibdatadogExtconfHelpers.pkg_config_missing?
|
202
207
|
Datadog::Profiling::NativeExtensionHelpers::Supported::PKG_CONFIG_IS_MISSING
|
203
208
|
else
|
204
209
|
# Less specific error message
|
@@ -207,16 +212,18 @@ unless pkg_config('datadog_profiling_with_rpath')
|
|
207
212
|
)
|
208
213
|
end
|
209
214
|
|
210
|
-
unless have_type(
|
215
|
+
unless have_type("atomic_int", ["stdatomic.h"])
|
211
216
|
skip_building_extension!(Datadog::Profiling::NativeExtensionHelpers::Supported::COMPILER_ATOMIC_MISSING)
|
212
217
|
end
|
213
218
|
|
214
|
-
# See comments on the helper
|
219
|
+
# See comments on the helper methods being used for why we need to additionally set this.
|
215
220
|
# The extremely excessive escaping around ORIGIN below seems to be correct and was determined after a lot of
|
216
221
|
# experimentation. We need to get these special characters across a lot of tools untouched...
|
217
|
-
|
218
|
-
|
219
|
-
|
222
|
+
extra_relative_rpaths = [
|
223
|
+
Datadog::LibdatadogExtconfHelpers.libdatadog_folder_relative_to_native_lib_folder(current_folder: __dir__),
|
224
|
+
*Datadog::LibdatadogExtconfHelpers.libdatadog_folder_relative_to_ruby_extensions_folders,
|
225
|
+
]
|
226
|
+
extra_relative_rpaths.each { |folder| $LDFLAGS += " -Wl,-rpath,$$$\\\\{ORIGIN\\}/#{folder.to_str}" }
|
220
227
|
Logging.message("[datadog] After pkg-config $LDFLAGS were set to: #{$LDFLAGS.inspect}\n")
|
221
228
|
|
222
229
|
# Tag the native extension library with the Ruby version and Ruby platform.
|
@@ -235,8 +242,8 @@ if Datadog::Profiling::NativeExtensionHelpers::CAN_USE_MJIT_HEADER
|
|
235
242
|
# use the MJIT header.
|
236
243
|
# Finally, the `COMMON_HEADERS` conflict with the MJIT header so we need to temporarily disable them for this check.
|
237
244
|
original_common_headers = MakeMakefile::COMMON_HEADERS
|
238
|
-
MakeMakefile::COMMON_HEADERS =
|
239
|
-
unless have_macro(
|
245
|
+
MakeMakefile::COMMON_HEADERS = "".freeze
|
246
|
+
unless have_macro("RUBY_MJIT_H", mjit_header_file_name)
|
240
247
|
skip_building_extension!(Datadog::Profiling::NativeExtensionHelpers::Supported::COMPILATION_BROKEN)
|
241
248
|
end
|
242
249
|
MakeMakefile::COMMON_HEADERS = original_common_headers
|
@@ -248,7 +255,7 @@ if Datadog::Profiling::NativeExtensionHelpers::CAN_USE_MJIT_HEADER
|
|
248
255
|
|
249
256
|
# Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
|
250
257
|
# See the comment on the same flag below for why this is done last.
|
251
|
-
add_compiler_flag
|
258
|
+
add_compiler_flag "-Wunused-parameter"
|
252
259
|
|
253
260
|
create_makefile EXTENSION_NAME
|
254
261
|
else
|
@@ -259,23 +266,23 @@ else
|
|
259
266
|
|
260
267
|
create_header
|
261
268
|
|
262
|
-
require
|
263
|
-
dir_config(
|
269
|
+
require "debase/ruby_core_source"
|
270
|
+
dir_config("ruby") # allow user to pass in non-standard core include directory
|
264
271
|
|
265
272
|
Debase::RubyCoreSource
|
266
273
|
.create_makefile_with_core(
|
267
274
|
proc do
|
268
275
|
headers_available =
|
269
|
-
have_header(
|
270
|
-
have_header(
|
271
|
-
(RUBY_VERSION <
|
276
|
+
have_header("vm_core.h") &&
|
277
|
+
have_header("iseq.h") &&
|
278
|
+
(RUBY_VERSION < "3.3" || have_header("ractor_core.h"))
|
272
279
|
|
273
280
|
if headers_available
|
274
281
|
# Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
|
275
282
|
# This is added as late as possible because in some Rubies we support (e.g. 3.3), adding this flag before
|
276
283
|
# checking if internal VM headers are available causes those checks to fail because of this warning (and not
|
277
284
|
# because the headers are not available.)
|
278
|
-
add_compiler_flag
|
285
|
+
add_compiler_flag "-Wunused-parameter"
|
279
286
|
end
|
280
287
|
|
281
288
|
headers_available
|
@@ -166,6 +166,12 @@ struct heap_recorder {
|
|
166
166
|
size_t objects_frozen;
|
167
167
|
} stats_last_update;
|
168
168
|
};
|
169
|
+
|
170
|
+
struct end_heap_allocation_args {
|
171
|
+
struct heap_recorder *heap_recorder;
|
172
|
+
ddog_prof_Slice_Location locations;
|
173
|
+
};
|
174
|
+
|
169
175
|
static heap_record* get_or_create_heap_record(heap_recorder*, ddog_prof_Slice_Location);
|
170
176
|
static void cleanup_heap_record_if_unused(heap_recorder*, heap_record*);
|
171
177
|
static void on_committed_object_record_cleanup(heap_recorder *heap_recorder, object_record *record);
|
@@ -176,6 +182,7 @@ static int st_object_records_iterate(st_data_t, st_data_t, st_data_t);
|
|
176
182
|
static int st_object_records_debug(st_data_t key, st_data_t value, st_data_t extra);
|
177
183
|
static int update_object_record_entry(st_data_t*, st_data_t*, st_data_t, int);
|
178
184
|
static void commit_recording(heap_recorder*, heap_record*, recording);
|
185
|
+
static VALUE end_heap_allocation_recording(VALUE end_heap_allocation_args);
|
179
186
|
|
180
187
|
// ==========================
|
181
188
|
// Heap Recorder External API
|
@@ -219,7 +226,7 @@ void heap_recorder_free(heap_recorder *heap_recorder) {
|
|
219
226
|
st_foreach(heap_recorder->heap_records, st_heap_record_entry_free, 0);
|
220
227
|
st_free_table(heap_recorder->heap_records);
|
221
228
|
|
222
|
-
if (heap_recorder->active_recording.object_record != NULL) {
|
229
|
+
if (heap_recorder->active_recording.object_record != NULL && heap_recorder->active_recording.object_record != &SKIPPED_RECORD) {
|
223
230
|
// If there's a partial object record, clean it up as well
|
224
231
|
object_record_free(heap_recorder->active_recording.object_record);
|
225
232
|
}
|
@@ -340,9 +347,28 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
|
|
340
347
|
};
|
341
348
|
}
|
342
349
|
|
343
|
-
|
350
|
+
// end_heap_allocation_recording_with_rb_protect gets called while the stack_recorder is holding one of the profile
|
351
|
+
// locks. To enable us to correctly unlock the profile on exception, we wrap the call to end_heap_allocation_recording
|
352
|
+
// with an rb_protect.
|
353
|
+
__attribute__((warn_unused_result))
|
354
|
+
int end_heap_allocation_recording_with_rb_protect(struct heap_recorder *heap_recorder, ddog_prof_Slice_Location locations) {
|
355
|
+
int exception_state;
|
356
|
+
struct end_heap_allocation_args end_heap_allocation_args = {
|
357
|
+
.heap_recorder = heap_recorder,
|
358
|
+
.locations = locations,
|
359
|
+
};
|
360
|
+
rb_protect(end_heap_allocation_recording, (VALUE) &end_heap_allocation_args, &exception_state);
|
361
|
+
return exception_state;
|
362
|
+
}
|
363
|
+
|
364
|
+
static VALUE end_heap_allocation_recording(VALUE end_heap_allocation_args) {
|
365
|
+
struct end_heap_allocation_args *args = (struct end_heap_allocation_args *) end_heap_allocation_args;
|
366
|
+
|
367
|
+
struct heap_recorder *heap_recorder = args->heap_recorder;
|
368
|
+
ddog_prof_Slice_Location locations = args->locations;
|
369
|
+
|
344
370
|
if (heap_recorder == NULL) {
|
345
|
-
return;
|
371
|
+
return Qnil;
|
346
372
|
}
|
347
373
|
|
348
374
|
recording active_recording = heap_recorder->active_recording;
|
@@ -356,15 +382,16 @@ void end_heap_allocation_recording(struct heap_recorder *heap_recorder, ddog_pro
|
|
356
382
|
// data required for committing though.
|
357
383
|
heap_recorder->active_recording = (recording) {0};
|
358
384
|
|
359
|
-
if (active_recording.object_record == &SKIPPED_RECORD) {
|
360
|
-
|
361
|
-
return;
|
385
|
+
if (active_recording.object_record == &SKIPPED_RECORD) { // special marker when we decided to skip due to sampling
|
386
|
+
return Qnil;
|
362
387
|
}
|
363
388
|
|
364
389
|
heap_record *heap_record = get_or_create_heap_record(heap_recorder, locations);
|
365
390
|
|
366
391
|
// And then commit the new allocation.
|
367
392
|
commit_recording(heap_recorder, heap_record, active_recording);
|
393
|
+
|
394
|
+
return Qnil;
|
368
395
|
}
|
369
396
|
|
370
397
|
void heap_recorder_prepare_iteration(heap_recorder *heap_recorder) {
|
@@ -815,6 +842,7 @@ VALUE object_record_inspect(object_record *record) {
|
|
815
842
|
if (!ruby_ref_from_id(LONG2NUM(record->obj_id), &ref)) {
|
816
843
|
rb_str_catf(inspect, "object=<invalid>");
|
817
844
|
} else {
|
845
|
+
rb_str_catf(inspect, "value=%p ", (void *) ref);
|
818
846
|
VALUE ruby_inspect = ruby_safe_inspect(ref);
|
819
847
|
if (ruby_inspect != Qnil) {
|
820
848
|
rb_str_catf(inspect, "object=%"PRIsVALUE, ruby_inspect);
|
@@ -114,7 +114,9 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
|
|
114
114
|
// @param locations The stacktrace representing the location of the allocation.
|
115
115
|
//
|
116
116
|
// WARN: It is illegal to call this without previously having called ::start_heap_allocation_recording.
|
117
|
-
|
117
|
+
// WARN: This method rescues exceptions with `rb_protect`, returning the exception state integer for the caller to handle.
|
118
|
+
__attribute__((warn_unused_result))
|
119
|
+
int end_heap_allocation_recording_with_rb_protect(heap_recorder *heap_recorder, ddog_prof_Slice_Location locations);
|
118
120
|
|
119
121
|
// Update the heap recorder to reflect the latest state of the VM and prepare internal structures
|
120
122
|
// for efficient iteration.
|
@@ -2,22 +2,11 @@
|
|
2
2
|
|
3
3
|
#include <stdint.h>
|
4
4
|
|
5
|
-
// Used to mark symbols to be exported to the outside of the extension.
|
6
|
-
// Consider very carefully before tagging a function with this.
|
7
|
-
#define DDTRACE_EXPORT __attribute__ ((visibility ("default")))
|
8
|
-
|
9
|
-
// Used to mark function arguments that are deliberately left unused
|
10
|
-
#ifdef __GNUC__
|
11
|
-
#define DDTRACE_UNUSED __attribute__((unused))
|
12
|
-
#else
|
13
|
-
#define DDTRACE_UNUSED
|
14
|
-
#endif
|
15
|
-
|
16
5
|
// @ivoanjo: After trying to read through https://stackoverflow.com/questions/3437404/min-and-max-in-c I decided I
|
17
6
|
// don't like C and I just implemented this as a function.
|
18
|
-
inline
|
19
|
-
inline
|
20
|
-
inline
|
21
|
-
inline
|
22
|
-
inline
|
23
|
-
inline
|
7
|
+
static inline uint64_t uint64_max_of(uint64_t a, uint64_t b) { return a > b ? a : b; }
|
8
|
+
static inline uint64_t uint64_min_of(uint64_t a, uint64_t b) { return a > b ? b : a; }
|
9
|
+
static inline long long_max_of(long a, long b) { return a > b ? a : b; }
|
10
|
+
static inline long long_min_of(long a, long b) { return a > b ? b : a; }
|
11
|
+
static inline double double_max_of(double a, double b) { return a > b ? a : b; }
|
12
|
+
static inline double double_min_of(double a, double b) { return a > b ? b : a; }
|
@@ -21,7 +21,7 @@ struct call_exporter_without_gvl_arguments {
|
|
21
21
|
bool send_ran;
|
22
22
|
};
|
23
23
|
|
24
|
-
inline
|
24
|
+
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
|
25
25
|
static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
|
26
26
|
static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
|
27
27
|
static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_result);
|
@@ -53,11 +53,11 @@ void http_transport_init(VALUE profiling_module) {
|
|
53
53
|
ok_symbol = ID2SYM(rb_intern_const("ok"));
|
54
54
|
error_symbol = ID2SYM(rb_intern_const("error"));
|
55
55
|
|
56
|
-
library_version_string =
|
56
|
+
library_version_string = datadog_gem_version();
|
57
57
|
rb_global_variable(&library_version_string);
|
58
58
|
}
|
59
59
|
|
60
|
-
inline
|
60
|
+
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
|
61
61
|
ENFORCE_TYPE(string, T_STRING);
|
62
62
|
ddog_ByteSlice byte_slice = {.ptr = (uint8_t *) StringValuePtr(string), .len = RSTRING_LEN(string)};
|
63
63
|
return byte_slice;
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
#include <ruby.h>
|
4
4
|
|
5
|
-
static VALUE log_failure_to_process_tag(VALUE err_details);
|
6
|
-
|
7
5
|
const char *ruby_value_type_to_string(enum ruby_value_type type) {
|
8
6
|
return ruby_value_type_to_char_slice(type).ptr;
|
9
7
|
}
|
@@ -62,87 +60,3 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
|
|
62
60
|
ddog_Error_drop(error);
|
63
61
|
return error_msg_size;
|
64
62
|
}
|
65
|
-
|
66
|
-
__attribute__((warn_unused_result))
|
67
|
-
ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
|
68
|
-
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
69
|
-
|
70
|
-
VALUE exporter_working_mode = rb_ary_entry(exporter_configuration, 0);
|
71
|
-
ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
|
72
|
-
ID working_mode = SYM2ID(exporter_working_mode);
|
73
|
-
|
74
|
-
ID agentless_id = rb_intern("agentless");
|
75
|
-
ID agent_id = rb_intern("agent");
|
76
|
-
|
77
|
-
if (working_mode != agentless_id && working_mode != agent_id) {
|
78
|
-
rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
|
79
|
-
}
|
80
|
-
|
81
|
-
if (working_mode == agentless_id) {
|
82
|
-
VALUE site = rb_ary_entry(exporter_configuration, 1);
|
83
|
-
VALUE api_key = rb_ary_entry(exporter_configuration, 2);
|
84
|
-
ENFORCE_TYPE(site, T_STRING);
|
85
|
-
ENFORCE_TYPE(api_key, T_STRING);
|
86
|
-
|
87
|
-
return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
|
88
|
-
} else { // agent_id
|
89
|
-
VALUE base_url = rb_ary_entry(exporter_configuration, 1);
|
90
|
-
ENFORCE_TYPE(base_url, T_STRING);
|
91
|
-
|
92
|
-
return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
|
93
|
-
}
|
94
|
-
}
|
95
|
-
|
96
|
-
__attribute__((warn_unused_result))
|
97
|
-
ddog_Vec_Tag convert_tags(VALUE tags_as_array) {
|
98
|
-
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
99
|
-
|
100
|
-
long tags_count = RARRAY_LEN(tags_as_array);
|
101
|
-
ddog_Vec_Tag tags = ddog_Vec_Tag_new();
|
102
|
-
|
103
|
-
for (long i = 0; i < tags_count; i++) {
|
104
|
-
VALUE name_value_pair = rb_ary_entry(tags_as_array, i);
|
105
|
-
|
106
|
-
if (!RB_TYPE_P(name_value_pair, T_ARRAY)) {
|
107
|
-
ddog_Vec_Tag_drop(tags);
|
108
|
-
ENFORCE_TYPE(name_value_pair, T_ARRAY);
|
109
|
-
}
|
110
|
-
|
111
|
-
// Note: We can index the array without checking its size first because rb_ary_entry returns Qnil if out of bounds
|
112
|
-
VALUE tag_name = rb_ary_entry(name_value_pair, 0);
|
113
|
-
VALUE tag_value = rb_ary_entry(name_value_pair, 1);
|
114
|
-
|
115
|
-
if (!(RB_TYPE_P(tag_name, T_STRING) && RB_TYPE_P(tag_value, T_STRING))) {
|
116
|
-
ddog_Vec_Tag_drop(tags);
|
117
|
-
ENFORCE_TYPE(tag_name, T_STRING);
|
118
|
-
ENFORCE_TYPE(tag_value, T_STRING);
|
119
|
-
}
|
120
|
-
|
121
|
-
ddog_Vec_Tag_PushResult push_result =
|
122
|
-
ddog_Vec_Tag_push(&tags, char_slice_from_ruby_string(tag_name), char_slice_from_ruby_string(tag_value));
|
123
|
-
|
124
|
-
if (push_result.tag == DDOG_VEC_TAG_PUSH_RESULT_ERR) {
|
125
|
-
// libdatadog validates tags and may catch invalid tags that ddtrace didn't actually catch.
|
126
|
-
// We warn users about such tags, and then just ignore them.
|
127
|
-
|
128
|
-
int exception_state;
|
129
|
-
rb_protect(log_failure_to_process_tag, get_error_details_and_drop(&push_result.err), &exception_state);
|
130
|
-
|
131
|
-
// Since we are calling into Ruby code, it may raise an exception. Ensure that dynamically-allocated tags
|
132
|
-
// get cleaned before propagating the exception.
|
133
|
-
if (exception_state) {
|
134
|
-
ddog_Vec_Tag_drop(tags);
|
135
|
-
rb_jump_tag(exception_state); // "Re-raise" exception
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
return tags;
|
141
|
-
}
|
142
|
-
|
143
|
-
static VALUE log_failure_to_process_tag(VALUE err_details) {
|
144
|
-
VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
|
145
|
-
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
146
|
-
|
147
|
-
return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to add tag to profiling request: %"PRIsVALUE, err_details));
|
148
|
-
}
|
@@ -3,27 +3,10 @@
|
|
3
3
|
#include <datadog/profiling.h>
|
4
4
|
#include "ruby_helpers.h"
|
5
5
|
|
6
|
-
|
7
|
-
ENFORCE_TYPE(string, T_STRING);
|
8
|
-
ddog_CharSlice char_slice = {.ptr = StringValuePtr(string), .len = RSTRING_LEN(string)};
|
9
|
-
return char_slice;
|
10
|
-
}
|
11
|
-
|
12
|
-
inline static VALUE ruby_string_from_vec_u8(ddog_Vec_U8 string) {
|
6
|
+
static inline VALUE ruby_string_from_vec_u8(ddog_Vec_U8 string) {
|
13
7
|
return rb_str_new((char *) string.ptr, string.len);
|
14
8
|
}
|
15
9
|
|
16
|
-
inline static VALUE ruby_string_from_error(const ddog_Error *error) {
|
17
|
-
ddog_CharSlice char_slice = ddog_Error_message(error);
|
18
|
-
return rb_str_new(char_slice.ptr, char_slice.len);
|
19
|
-
}
|
20
|
-
|
21
|
-
inline static VALUE get_error_details_and_drop(ddog_Error *error) {
|
22
|
-
VALUE result = ruby_string_from_error(error);
|
23
|
-
ddog_Error_drop(error);
|
24
|
-
return result;
|
25
|
-
}
|
26
|
-
|
27
10
|
// Utility function to be able to extract an error cstring from a ddog_Error.
|
28
11
|
// Returns the amount of characters written to string (which are necessarily
|
29
12
|
// bounded by capacity - 1 since the string will be null-terminated).
|
@@ -37,10 +20,6 @@ ddog_CharSlice ruby_value_type_to_char_slice(enum ruby_value_type type);
|
|
37
20
|
|
38
21
|
// Returns a dynamically allocated string from the provided char slice.
|
39
22
|
// WARN: The returned string must be explicitly freed with ruby_xfree.
|
40
|
-
inline
|
23
|
+
static inline char* string_from_char_slice(ddog_CharSlice slice) {
|
41
24
|
return ruby_strndup(slice.ptr, slice.len);
|
42
25
|
}
|
43
|
-
|
44
|
-
ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration);
|
45
|
-
|
46
|
-
ddog_Vec_Tag convert_tags(VALUE tags_as_array);
|