datadog 2.12.1 → 2.17.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.
Files changed (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +154 -2
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +16 -14
  4. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  5. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  6. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  7. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  8. data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
  9. data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
  10. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  11. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
  12. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  13. data/ext/datadog_profiling_native_extension/stack_recorder.c +23 -23
  14. data/ext/libdatadog_api/crashtracker.c +11 -12
  15. data/ext/libdatadog_api/crashtracker.h +5 -0
  16. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  17. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  18. data/ext/libdatadog_api/init.c +15 -0
  19. data/ext/libdatadog_api/library_config.c +122 -0
  20. data/ext/libdatadog_api/library_config.h +19 -0
  21. data/ext/libdatadog_api/macos_development.md +3 -3
  22. data/ext/libdatadog_api/process_discovery.c +117 -0
  23. data/ext/libdatadog_api/process_discovery.h +5 -0
  24. data/ext/libdatadog_extconf_helpers.rb +1 -1
  25. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  26. data/lib/datadog/appsec/actions_handler.rb +24 -2
  27. data/lib/datadog/appsec/anonymizer.rb +16 -0
  28. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  29. data/lib/datadog/appsec/api_security.rb +9 -0
  30. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  31. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  32. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  33. data/lib/datadog/appsec/autoload.rb +1 -1
  34. data/lib/datadog/appsec/component.rb +29 -20
  35. data/lib/datadog/appsec/compressed_json.rb +40 -0
  36. data/lib/datadog/appsec/configuration/settings.rb +93 -28
  37. data/lib/datadog/appsec/context.rb +1 -1
  38. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  39. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  40. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  41. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  42. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  43. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  44. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  45. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  46. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  47. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  48. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  49. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  50. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  51. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  52. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  53. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  54. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  55. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  56. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  57. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  58. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
  59. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  60. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +19 -18
  61. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  62. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  63. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  64. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  65. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  66. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  67. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  68. data/lib/datadog/appsec/event.rb +96 -135
  69. data/lib/datadog/appsec/ext.rb +4 -2
  70. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  71. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  72. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  73. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  74. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  75. data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
  76. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  77. data/lib/datadog/appsec/processor.rb +1 -1
  78. data/lib/datadog/appsec/remote.rb +23 -11
  79. data/lib/datadog/appsec/response.rb +6 -6
  80. data/lib/datadog/appsec/security_engine/runner.rb +3 -3
  81. data/lib/datadog/appsec/security_event.rb +39 -0
  82. data/lib/datadog/appsec/utils.rb +0 -2
  83. data/lib/datadog/appsec.rb +1 -1
  84. data/lib/datadog/core/buffer/random.rb +18 -2
  85. data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
  86. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  87. data/lib/datadog/core/configuration/components.rb +50 -31
  88. data/lib/datadog/core/configuration/components_state.rb +23 -0
  89. data/lib/datadog/core/configuration/ext.rb +4 -0
  90. data/lib/datadog/core/configuration/option.rb +79 -43
  91. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  92. data/lib/datadog/core/configuration/options.rb +3 -3
  93. data/lib/datadog/core/configuration/settings.rb +68 -35
  94. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  95. data/lib/datadog/core/configuration.rb +40 -16
  96. data/lib/datadog/core/crashtracking/component.rb +3 -10
  97. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  98. data/lib/datadog/core/encoding.rb +1 -1
  99. data/lib/datadog/core/environment/agent_info.rb +4 -3
  100. data/lib/datadog/core/environment/cgroup.rb +10 -12
  101. data/lib/datadog/core/environment/container.rb +38 -40
  102. data/lib/datadog/core/environment/ext.rb +6 -6
  103. data/lib/datadog/core/environment/git.rb +1 -0
  104. data/lib/datadog/core/environment/identity.rb +3 -3
  105. data/lib/datadog/core/environment/platform.rb +3 -3
  106. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  107. data/lib/datadog/core/error.rb +11 -9
  108. data/lib/datadog/core/logger.rb +2 -2
  109. data/lib/datadog/core/metrics/client.rb +20 -21
  110. data/lib/datadog/core/metrics/logging.rb +5 -5
  111. data/lib/datadog/core/process_discovery.rb +32 -0
  112. data/lib/datadog/core/rate_limiter.rb +4 -2
  113. data/lib/datadog/core/remote/client.rb +40 -32
  114. data/lib/datadog/core/remote/component.rb +6 -9
  115. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  116. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  117. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  118. data/lib/datadog/core/remote/negotiation.rb +9 -9
  119. data/lib/datadog/core/remote/transport/config.rb +4 -3
  120. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  121. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  122. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  123. data/lib/datadog/core/remote/transport/http.rb +22 -57
  124. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  125. data/lib/datadog/core/runtime/metrics.rb +12 -5
  126. data/lib/datadog/core/telemetry/component.rb +78 -53
  127. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  128. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  129. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  130. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  131. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  132. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  133. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  134. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  135. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  136. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  137. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  138. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  139. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  140. data/lib/datadog/core/telemetry/event.rb +17 -472
  141. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  142. data/lib/datadog/core/telemetry/logger.rb +1 -1
  143. data/lib/datadog/core/telemetry/metric.rb +8 -8
  144. data/lib/datadog/core/telemetry/request.rb +4 -4
  145. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  146. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  147. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  148. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  149. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  150. data/lib/datadog/core/telemetry/worker.rb +90 -24
  151. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  152. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  153. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  154. data/lib/datadog/core/transport/http/builder.rb +18 -16
  155. data/lib/datadog/core/transport/http.rb +39 -2
  156. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  157. data/lib/datadog/core/utils/duration.rb +32 -32
  158. data/lib/datadog/core/utils/forking.rb +2 -2
  159. data/lib/datadog/core/utils/network.rb +6 -6
  160. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  161. data/lib/datadog/core/utils/time.rb +20 -0
  162. data/lib/datadog/core/utils/truncation.rb +21 -0
  163. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  164. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  165. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  166. data/lib/datadog/core/worker.rb +1 -1
  167. data/lib/datadog/core/workers/async.rb +29 -12
  168. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  169. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  170. data/lib/datadog/core.rb +8 -0
  171. data/lib/datadog/di/boot.rb +34 -0
  172. data/lib/datadog/di/component.rb +0 -2
  173. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  174. data/lib/datadog/di/probe_notifier_worker.rb +16 -16
  175. data/lib/datadog/di/remote.rb +2 -0
  176. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  177. data/lib/datadog/di/transport/http/api.rb +2 -12
  178. data/lib/datadog/di/transport/http/client.rb +4 -3
  179. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  180. data/lib/datadog/di/transport/http/input.rb +7 -34
  181. data/lib/datadog/di/transport/http.rb +14 -62
  182. data/lib/datadog/di/transport/input.rb +4 -3
  183. data/lib/datadog/di/utils.rb +5 -0
  184. data/lib/datadog/di.rb +5 -32
  185. data/lib/datadog/error_tracking/collector.rb +87 -0
  186. data/lib/datadog/error_tracking/component.rb +167 -0
  187. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  188. data/lib/datadog/error_tracking/configuration.rb +11 -0
  189. data/lib/datadog/error_tracking/ext.rb +18 -0
  190. data/lib/datadog/error_tracking/extensions.rb +16 -0
  191. data/lib/datadog/error_tracking/filters.rb +77 -0
  192. data/lib/datadog/error_tracking.rb +18 -0
  193. data/lib/datadog/kit/appsec/events.rb +12 -0
  194. data/lib/datadog/kit/identity.rb +5 -1
  195. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  196. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  197. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  198. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  199. data/lib/datadog/opentelemetry.rb +2 -1
  200. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  201. data/lib/datadog/profiling/collectors/info.rb +3 -0
  202. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  203. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  204. data/lib/datadog/profiling/exporter.rb +3 -4
  205. data/lib/datadog/profiling/ext.rb +0 -2
  206. data/lib/datadog/profiling/flush.rb +5 -8
  207. data/lib/datadog/profiling/http_transport.rb +5 -59
  208. data/lib/datadog/profiling/scheduler.rb +8 -1
  209. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  210. data/lib/datadog/profiling/tag_builder.rb +1 -5
  211. data/lib/datadog/profiling.rb +6 -2
  212. data/lib/datadog/tracing/analytics.rb +1 -1
  213. data/lib/datadog/tracing/component.rb +15 -12
  214. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  215. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  216. data/lib/datadog/tracing/context_provider.rb +1 -1
  217. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  218. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
  219. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  220. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  221. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  222. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  223. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  224. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  225. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  226. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  227. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  228. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  229. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  230. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  231. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  232. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  233. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  234. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  235. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  236. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  237. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  238. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  239. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  240. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  241. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  242. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  243. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  244. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  245. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  246. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  247. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  248. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  249. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  250. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  251. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  252. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  253. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  254. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  255. data/lib/datadog/tracing/contrib/support.rb +28 -0
  256. data/lib/datadog/tracing/contrib.rb +1 -0
  257. data/lib/datadog/tracing/correlation.rb +9 -2
  258. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  259. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  260. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  261. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  262. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  263. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  264. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  265. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  266. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  267. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  268. data/lib/datadog/tracing/metadata.rb +2 -0
  269. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  270. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  271. data/lib/datadog/tracing/span.rb +10 -1
  272. data/lib/datadog/tracing/span_event.rb +1 -1
  273. data/lib/datadog/tracing/span_operation.rb +46 -16
  274. data/lib/datadog/tracing/sync_writer.rb +1 -2
  275. data/lib/datadog/tracing/trace_digest.rb +9 -2
  276. data/lib/datadog/tracing/trace_operation.rb +44 -24
  277. data/lib/datadog/tracing/trace_segment.rb +6 -4
  278. data/lib/datadog/tracing/tracer.rb +45 -5
  279. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  280. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  281. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  282. data/lib/datadog/tracing/transport/http.rb +11 -44
  283. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  284. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  285. data/lib/datadog/tracing/transport/traces.rb +26 -9
  286. data/lib/datadog/tracing/utils.rb +1 -1
  287. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  288. data/lib/datadog/tracing/writer.rb +2 -6
  289. data/lib/datadog/tracing.rb +16 -3
  290. data/lib/datadog/version.rb +2 -2
  291. data/lib/datadog.rb +2 -3
  292. metadata +80 -19
  293. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  294. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  295. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  296. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  297. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  298. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  299. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  300. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  301. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  302. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -2,12 +2,13 @@
2
2
 
3
3
  require_relative 'emitter'
4
4
  require_relative 'event'
5
- require_relative 'http/transport'
6
5
  require_relative 'metrics_manager'
7
6
  require_relative 'worker'
8
7
  require_relative 'logging'
8
+ require_relative 'transport/http'
9
9
 
10
10
  require_relative '../configuration/ext'
11
+ require_relative '../configuration/agentless_settings_resolver'
11
12
  require_relative '../utils/forking'
12
13
 
13
14
  module Datadog
@@ -15,8 +16,10 @@ module Datadog
15
16
  module Telemetry
16
17
  # Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
17
18
  # Note: Telemetry does not spawn its worker thread in fork processes, thus no telemetry is sent in forked processes.
19
+ #
20
+ # @api private
18
21
  class Component
19
- attr_reader :enabled, :logger
22
+ attr_reader :enabled, :logger, :transport, :worker
20
23
 
21
24
  include Core::Utils::Forking
22
25
  include Telemetry::Logging
@@ -25,89 +28,100 @@ module Datadog
25
28
  enabled = settings.telemetry.enabled
26
29
  agentless_enabled = settings.telemetry.agentless_enabled
27
30
 
28
- if !agentless_enabled && agent_settings.adapter != Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
29
- enabled = false
30
- logger.debug { "Telemetry disabled. Agent network adapter not supported: #{agent_settings.adapter}" }
31
- end
32
-
33
31
  if agentless_enabled && settings.api_key.nil?
34
32
  enabled = false
35
- logger.debug { 'Telemetry disabled. Agentless telemetry requires an DD_API_KEY variable to be set.' }
33
+ logger.debug { 'Telemetry disabled. Agentless telemetry requires a DD_API_KEY variable to be set.' }
36
34
  end
37
35
 
38
- transport = if agentless_enabled
39
- Datadog::Core::Telemetry::Http::Transport.build_agentless_transport(
40
- api_key: settings.api_key,
41
- dd_site: settings.site,
42
- url_override: settings.telemetry.agentless_url_override
43
- )
44
- else
45
- Datadog::Core::Telemetry::Http::Transport.build_agent_transport(agent_settings)
46
- end
47
-
48
36
  Telemetry::Component.new(
49
- http_transport: transport,
37
+ settings: settings,
38
+ agent_settings: agent_settings,
50
39
  enabled: enabled,
51
- metrics_enabled: enabled && settings.telemetry.metrics_enabled,
52
- heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
53
- metrics_aggregation_interval_seconds: settings.telemetry.metrics_aggregation_interval_seconds,
54
- dependency_collection: settings.telemetry.dependency_collection,
55
40
  logger: logger,
56
- shutdown_timeout_seconds: settings.telemetry.shutdown_timeout_seconds,
57
- log_collection_enabled: settings.telemetry.log_collection_enabled
58
41
  )
59
42
  end
60
43
 
61
44
  # @param enabled [Boolean] Determines whether telemetry events should be sent to the API
62
- # @param metrics_enabled [Boolean] Determines whether telemetry metrics should be sent to the API
63
- # @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
64
- # @param metrics_aggregation_interval_seconds [Float] How frequently metrics will be aggregated, in seconds.
65
- # @param [Boolean] dependency_collection Whether to send the `app-dependencies-loaded` event
66
- def initialize(
67
- heartbeat_interval_seconds:,
68
- metrics_aggregation_interval_seconds:,
69
- dependency_collection:,
45
+ def initialize( # standard:disable Metrics/MethodLength
46
+ settings:,
47
+ agent_settings:,
70
48
  logger:,
71
- http_transport:,
72
- shutdown_timeout_seconds:,
73
- enabled: true,
74
- metrics_enabled: true,
75
- log_collection_enabled: true
49
+ enabled:
76
50
  )
77
51
  @enabled = enabled
78
- @log_collection_enabled = log_collection_enabled
52
+ @log_collection_enabled = settings.telemetry.log_collection_enabled
79
53
  @logger = logger
80
54
 
81
55
  @metrics_manager = MetricsManager.new(
82
- enabled: enabled && metrics_enabled,
83
- aggregation_interval: metrics_aggregation_interval_seconds
56
+ enabled: @enabled && settings.telemetry.metrics_enabled,
57
+ aggregation_interval: settings.telemetry.metrics_aggregation_interval_seconds,
84
58
  )
85
59
 
60
+ @stopped = false
61
+
62
+ return unless @enabled
63
+
64
+ @transport = if settings.telemetry.agentless_enabled
65
+ agent_settings = Core::Configuration::AgentlessSettingsResolver.call(
66
+ settings,
67
+ host_prefix: 'instrumentation-telemetry-intake',
68
+ url_override: settings.telemetry.agentless_url_override,
69
+ url_override_source: 'c.telemetry.agentless_url_override',
70
+ logger: logger,
71
+ )
72
+ Telemetry::Transport::HTTP.agentless_telemetry(
73
+ agent_settings: agent_settings,
74
+ logger: logger,
75
+ # api_key should have already validated to be
76
+ # not nil by +build+ method above.
77
+ api_key: settings.api_key,
78
+ )
79
+ else
80
+ Telemetry::Transport::HTTP.agent_telemetry(
81
+ agent_settings: agent_settings, logger: logger,
82
+ )
83
+ end
84
+
86
85
  @worker = Telemetry::Worker.new(
87
86
  enabled: @enabled,
88
- heartbeat_interval_seconds: heartbeat_interval_seconds,
89
- metrics_aggregation_interval_seconds: metrics_aggregation_interval_seconds,
90
- emitter: Emitter.new(http_transport: http_transport),
87
+ heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
88
+ metrics_aggregation_interval_seconds: settings.telemetry.metrics_aggregation_interval_seconds,
89
+ emitter: Emitter.new(
90
+ @transport,
91
+ logger: @logger,
92
+ debug: settings.telemetry.debug,
93
+ ),
91
94
  metrics_manager: @metrics_manager,
92
- dependency_collection: dependency_collection,
95
+ dependency_collection: settings.telemetry.dependency_collection,
93
96
  logger: logger,
94
- shutdown_timeout: shutdown_timeout_seconds
97
+ shutdown_timeout: settings.telemetry.shutdown_timeout_seconds,
95
98
  )
96
-
97
- @stopped = false
98
-
99
- @worker.start
100
99
  end
101
100
 
102
101
  def disable!
103
102
  @enabled = false
104
- @worker.enabled = false
103
+ @worker&.enabled = false
104
+ end
105
+
106
+ def start(initial_event_is_change = false)
107
+ return if !@enabled
108
+
109
+ initial_event = if initial_event_is_change
110
+ Event::SynthAppClientConfigurationChange.new
111
+ else
112
+ Event::AppStarted.new
113
+ end
114
+
115
+ @worker.start(initial_event)
105
116
  end
106
117
 
107
- def stop!
118
+ def shutdown!
108
119
  return if @stopped
109
120
 
110
- @worker.stop(true)
121
+ if defined?(@worker)
122
+ @worker&.stop(true)
123
+ end
124
+
111
125
  @stopped = true
112
126
  end
113
127
 
@@ -129,6 +143,17 @@ module Datadog
129
143
  @worker.enqueue(event)
130
144
  end
131
145
 
146
+ # Wait for the worker to send out all events that have already
147
+ # been queued, up to 15 seconds. Returns whether all events have
148
+ # been flushed.
149
+ #
150
+ # @api private
151
+ def flush
152
+ return if !@enabled || forked?
153
+
154
+ @worker.flush
155
+ end
156
+
132
157
  # Report configuration changes caused by Remote Configuration.
133
158
  def client_configuration_change!(changes)
134
159
  return if !@enabled || forked?
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'request'
4
- require_relative 'http/transport'
4
+ require_relative '../transport/response'
5
5
  require_relative '../utils/sequence'
6
6
  require_relative '../utils/forking'
7
7
 
@@ -10,26 +10,38 @@ module Datadog
10
10
  module Telemetry
11
11
  # Class that emits telemetry events
12
12
  class Emitter
13
- attr_reader :http_transport
13
+ attr_reader :transport, :logger
14
14
 
15
15
  extend Core::Utils::Forking
16
16
 
17
- # @param http_transport [Datadog::Core::Telemetry::Http::Transport] Transport object that can be used to send
18
- # telemetry requests via the agent
19
- def initialize(http_transport:)
20
- @http_transport = http_transport
17
+ # @param transport [Datadog::Core::Telemetry::Transport::Telemetry::Transport]
18
+ # Transport object that can be used to send telemetry requests
19
+ def initialize(transport, logger: Datadog.logger, debug: false)
20
+ @transport = transport
21
+ @logger = logger
22
+ @debug = !!debug
23
+ end
24
+
25
+ def debug?
26
+ @debug
21
27
  end
22
28
 
23
29
  # Retrieves and emits a TelemetryRequest object based on the request type specified
24
30
  def request(event)
25
31
  seq_id = self.class.sequence.next
26
- payload = Request.build_payload(event, seq_id)
27
- res = @http_transport.request(request_type: event.type, payload: payload.to_json)
28
- Datadog.logger.debug { "Telemetry sent for event `#{event.type}` (code: #{res.code.inspect})" }
32
+ payload = Request.build_payload(event, seq_id, debug: debug?)
33
+ res = @transport.send_telemetry(request_type: event.type, payload: payload)
34
+ logger.debug { "Telemetry sent for event `#{event.type}` (response code: #{res.code})" }
29
35
  res
30
36
  rescue => e
31
- Datadog.logger.debug("Unable to send telemetry request for event `#{event.type rescue 'unknown'}`: #{e}")
32
- Telemetry::Http::InternalErrorResponse.new(e)
37
+ logger.debug {
38
+ "Unable to send telemetry request for event `#{begin
39
+ event.type
40
+ rescue
41
+ "unknown"
42
+ end}`: #{e}"
43
+ }
44
+ Core::Transport::InternalErrorResponse.new(e)
33
45
  end
34
46
 
35
47
  # Initializes a Sequence object to track seq_id if not already initialized; else returns stored
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'app-client-configuration-change' event
10
+ class AppClientConfigurationChange < Base
11
+ attr_reader :changes, :origin
12
+
13
+ def type
14
+ 'app-client-configuration-change'
15
+ end
16
+
17
+ def initialize(changes, origin)
18
+ super()
19
+ @changes = changes
20
+ @origin = origin
21
+ end
22
+
23
+ def payload
24
+ {configuration: configuration}
25
+ end
26
+
27
+ def configuration
28
+ config = Datadog.configuration
29
+ seq_id = Event.configuration_sequence.next
30
+
31
+ res = @changes.map do |name, value|
32
+ {
33
+ name: name,
34
+ value: value,
35
+ origin: @origin,
36
+ seq_id: seq_id,
37
+ }
38
+ end
39
+
40
+ unless config.dig('appsec', 'sca_enabled').nil?
41
+ res << {
42
+ name: 'appsec.sca_enabled',
43
+ value: config.appsec.sca_enabled,
44
+ origin: 'code',
45
+ seq_id: seq_id,
46
+ }
47
+ end
48
+
49
+ res
50
+ end
51
+
52
+ def ==(other)
53
+ other.is_a?(AppClientConfigurationChange) && other.changes == @changes && other.origin == @origin
54
+ end
55
+
56
+ alias_method :eql?, :==
57
+
58
+ def hash
59
+ [self.class, @changes, @origin].hash
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'app-closing' event
10
+ class AppClosing < Base
11
+ def type
12
+ 'app-closing'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'app-dependencies-loaded' event
10
+ class AppDependenciesLoaded < Base
11
+ def type
12
+ 'app-dependencies-loaded'
13
+ end
14
+
15
+ def payload
16
+ {dependencies: dependencies}
17
+ end
18
+
19
+ private
20
+
21
+ def dependencies
22
+ Gem.loaded_specs.collect do |name, gem|
23
+ {
24
+ name: name,
25
+ version: gem.version.to_s,
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'app-heartbeat' event
10
+ class AppHeartbeat < Base
11
+ def type
12
+ 'app-heartbeat'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'app-integrations-change' event
10
+ class AppIntegrationsChange < Base
11
+ def type
12
+ 'app-integrations-change'
13
+ end
14
+
15
+ def payload
16
+ {integrations: integrations}
17
+ end
18
+
19
+ private
20
+
21
+ def integrations
22
+ instrumented_integrations = Datadog.configuration.tracing.instrumented_integrations
23
+ Datadog.registry.map do |integration|
24
+ is_instrumented = instrumented_integrations.include?(integration.name)
25
+
26
+ is_enabled = is_instrumented && integration.klass.patcher.patch_successful
27
+
28
+ version = integration.klass.class.version&.to_s
29
+
30
+ res = {
31
+ name: integration.name.to_s,
32
+ enabled: is_enabled,
33
+ version: version,
34
+ compatible: integration.klass.class.compatible?,
35
+ error: (patch_error(integration) if is_instrumented && !is_enabled),
36
+ # TODO: Track if integration is instrumented by manual configuration or by auto instrumentation
37
+ # auto_enabled: is_enabled && ???,
38
+ }
39
+ res.reject! { |_, v| v.nil? }
40
+ res
41
+ end
42
+ end
43
+
44
+ def patch_error(integration)
45
+ patch_error_result = integration.klass.patcher.patch_error_result
46
+ return patch_error_result.compact.to_s if patch_error_result
47
+
48
+ # If no error occurred during patching, but integration is still not instrumented
49
+ "Available?: #{integration.klass.class.available?}" \
50
+ ", Loaded? #{integration.klass.class.loaded?}" \
51
+ ", Compatible? #{integration.klass.class.compatible?}" \
52
+ ", Patchable? #{integration.klass.class.patchable?}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'app-started' event
10
+ class AppStarted < Base
11
+ def type
12
+ 'app-started'
13
+ end
14
+
15
+ def payload
16
+ {
17
+ products: products,
18
+ configuration: configuration,
19
+ install_signature: install_signature,
20
+ # DEV: Not implemented yet
21
+ # error: error, # Start-up errors
22
+ }
23
+ end
24
+
25
+ private
26
+
27
+ def products
28
+ # @type var products: Hash[Symbol, Hash[Symbol, Object]]
29
+ products = {
30
+ appsec: {
31
+ enabled: Datadog::AppSec.enabled?,
32
+ },
33
+ profiler: {
34
+ enabled: Datadog::Profiling.enabled?,
35
+ },
36
+ dynamic_instrumentation: {
37
+ enabled: defined?(Datadog::DI) && Datadog::DI.respond_to?(:enabled?) && Datadog::DI.enabled?,
38
+ }
39
+ }
40
+
41
+ if (unsupported_reason = Datadog::Profiling.unsupported_reason)
42
+ products[:profiler][:error] = {
43
+ code: 1, # Error code. 0 if no error.
44
+ message: unsupported_reason,
45
+ }
46
+ end
47
+
48
+ products
49
+ end
50
+
51
+ TARGET_OPTIONS = %w[
52
+ dynamic_instrumentation.enabled
53
+ logger.level
54
+ profiling.advanced.code_provenance_enabled
55
+ profiling.advanced.endpoint.collection.enabled
56
+ profiling.enabled
57
+ runtime_metrics.enabled
58
+ tracing.analytics.enabled
59
+ tracing.propagation_style_extract
60
+ tracing.propagation_style_inject
61
+ tracing.enabled
62
+ tracing.log_injection
63
+ tracing.partial_flush.enabled
64
+ tracing.partial_flush.min_spans_threshold
65
+ tracing.report_hostname
66
+ tracing.sampling.rate_limit
67
+ ].freeze
68
+
69
+ # standard:disable Metrics/AbcSize
70
+ # standard:disable Metrics/MethodLength
71
+ def configuration
72
+ config = Datadog.configuration
73
+ seq_id = Event.configuration_sequence.next
74
+
75
+ list = [
76
+ conf_value('DD_GIT_REPOSITORY_URL', Core::Environment::Git.git_repository_url, seq_id, 'env_var'),
77
+ conf_value('DD_GIT_COMMIT_SHA', Core::Environment::Git.git_commit_sha, seq_id, 'env_var'),
78
+
79
+ conf_value('DD_AGENT_HOST', config.agent.host, seq_id),
80
+ conf_value('DD_AGENT_TRANSPORT', agent_transport(config), seq_id),
81
+ conf_value('DD_TRACE_SAMPLE_RATE', to_value(config.tracing.sampling.default_rate), seq_id),
82
+ conf_value(
83
+ 'DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED',
84
+ config.tracing.contrib.global_default_service_name.enabled,
85
+ seq_id
86
+ ),
87
+ conf_value(
88
+ 'DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED',
89
+ config.tracing.contrib.peer_service_defaults,
90
+ seq_id
91
+ ),
92
+ ]
93
+
94
+ peer_service_mapping_str = ''
95
+ unless config.tracing.contrib.peer_service_mapping.empty?
96
+ peer_service_mapping = config.tracing.contrib.peer_service_mapping
97
+ peer_service_mapping_str = peer_service_mapping.map { |key, value| "#{key}:#{value}" }.join(',')
98
+ end
99
+ list << conf_value('DD_TRACE_PEER_SERVICE_MAPPING', peer_service_mapping_str, seq_id)
100
+
101
+ # Whitelist of configuration options to send in additional payload object
102
+ TARGET_OPTIONS.each do |option|
103
+ split_option = option.split('.')
104
+ list << conf_value(option, to_value(config.dig(*split_option)), seq_id)
105
+ end
106
+
107
+ # Add some more custom additional payload values here
108
+ list.push(
109
+ conf_value('tracing.auto_instrument.enabled', !defined?(Datadog::AutoInstrument::LOADED).nil?, seq_id),
110
+ conf_value(
111
+ 'tracing.writer_options.buffer_size',
112
+ to_value(config.tracing.writer_options[:buffer_size]),
113
+ seq_id
114
+ ),
115
+ conf_value(
116
+ 'tracing.writer_options.flush_interval',
117
+ to_value(config.tracing.writer_options[:flush_interval]),
118
+ seq_id
119
+ ),
120
+ conf_value(
121
+ 'tracing.opentelemetry.enabled',
122
+ !defined?(Datadog::OpenTelemetry::LOADED).nil?,
123
+ seq_id
124
+ ),
125
+ )
126
+ list << conf_value('logger.instance', config.logger.instance.class.to_s, seq_id) if config.logger.instance
127
+ if config.respond_to?('appsec')
128
+ list << conf_value('appsec.enabled', config.dig('appsec', 'enabled'), seq_id)
129
+ list << conf_value('appsec.sca_enabled', config.dig('appsec', 'sca_enabled'), seq_id)
130
+ end
131
+ list << conf_value('ci.enabled', config.dig('ci', 'enabled'), seq_id) if config.respond_to?('ci')
132
+
133
+ list.reject! { |entry| entry[:value].nil? }
134
+ list
135
+ end
136
+ # standard:enable Metrics/AbcSize
137
+ # standard:enable Metrics/MethodLength
138
+
139
+ def agent_transport(config)
140
+ adapter = Core::Configuration::AgentSettingsResolver.call(config).adapter
141
+ if adapter == Datadog::Core::Transport::Ext::UnixSocket::ADAPTER
142
+ 'UDS'
143
+ else
144
+ 'TCP'
145
+ end
146
+ end
147
+
148
+ def conf_value(name, value, seq_id, origin = 'code')
149
+ {
150
+ name: name,
151
+ value: value,
152
+ origin: origin,
153
+ seq_id: seq_id,
154
+ }
155
+ end
156
+
157
+ def to_value(value)
158
+ # TODO: Add float if telemetry starts accepting it
159
+ case value
160
+ when Integer, String, true, false, nil
161
+ value
162
+ else
163
+ value.to_s
164
+ end
165
+ end
166
+
167
+ def install_signature
168
+ config = Datadog.configuration
169
+ {
170
+ install_id: config.dig('telemetry', 'install_id'),
171
+ install_type: config.dig('telemetry', 'install_type'),
172
+ install_time: config.dig('telemetry', 'install_time'),
173
+ }
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Telemetry
6
+ module Event
7
+ # Base class for all Telemetry V2 events.
8
+ class Base
9
+ # The type of the event.
10
+ # It must be one of the stings defined in the Telemetry V2
11
+ # specification for event names.
12
+ def type
13
+ raise NotImplementedError, 'Must be implemented by subclass'
14
+ end
15
+
16
+ # The JSON payload for the event.
17
+ def payload
18
+ {}
19
+ end
20
+
21
+ # Override equality to allow for deduplication
22
+ # The basic implementation is to check if the other object is an instance of the same class.
23
+ # This works for events that have no attributes.
24
+ # For events with attributes, you should override this method to compare the attributes.
25
+ def ==(other)
26
+ other.is_a?(self.class)
27
+ end
28
+
29
+ # @see #==
30
+ alias_method :eql?, :==
31
+
32
+ # @see #==
33
+ def hash
34
+ self.class.hash
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'generate_metrics'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module Event
9
+ # Telemetry class for the 'distributions' event
10
+ class Distributions < GenerateMetrics
11
+ def type
12
+ 'distributions'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end