99//! automatically once idle: an empty drain sets the `please_reload` bit (telling PHP workers
1010//! to stop writing), and the subsequent flush performs a final drain before removal.
1111
12+ use crate :: service:: { InstanceId , RuntimeMetadata } ;
1213use base64:: prelude:: BASE64_URL_SAFE_NO_PAD ;
1314use base64:: Engine ;
1415use datadog_ipc:: shm_stats:: {
@@ -18,6 +19,8 @@ use futures::{future::join_all, TryFutureExt};
1819use http:: uri:: PathAndQuery ;
1920use libdd_capabilities_impl:: { HttpClientCapability , NativeCapabilities } ;
2021use libdd_common:: { Endpoint , MutexExt } ;
22+ use libdd_telemetry:: config:: Config ;
23+ use libdd_telemetry:: worker:: TelemetryWorkerHandle ;
2124use libdd_trace_stats:: stats_exporter:: { StatsExporter , StatsMetadata } ;
2225use std:: collections:: HashMap ;
2326use std:: ffi:: CString ;
@@ -104,6 +107,7 @@ fn make_exporter(
104107 s : & SpanConcentratorState ,
105108 endpoint : Endpoint ,
106109 flush_interval : Duration ,
110+ telemetry : Option < TelemetryWorkerHandle > ,
107111) -> StatsExporter < NativeCapabilities , ShmSpanConcentrator > {
108112 StatsExporter :: new (
109113 flush_interval,
@@ -119,7 +123,7 @@ fn make_exporter(
119123 ) ) ,
120124 #[ cfg( feature = "stats-obfuscation" ) ]
121125 "0" ,
122- None ,
126+ telemetry ,
123127 None ,
124128 )
125129}
@@ -135,6 +139,7 @@ pub async fn run_stats_flush_loop(
135139 states : Weak < Mutex < HashMap < ConcentratorKey , Arc < SpanConcentratorState > > > > ,
136140 map_key : ConcentratorKey ,
137141 flush_interval : Duration ,
142+ telemetry : Option < TelemetryWorkerHandle > ,
138143) {
139144 let Some ( arc) = states. upgrade ( ) else {
140145 return ;
@@ -146,7 +151,13 @@ pub async fn run_stats_flush_loop(
146151 let Some ( state) = state else {
147152 return ;
148153 } ;
149- let exporter = make_exporter ( & state, state. endpoint . clone ( ) , flush_interval) ;
154+
155+ let exporter = make_exporter (
156+ & state,
157+ state. endpoint . clone ( ) ,
158+ flush_interval,
159+ telemetry. clone ( ) ,
160+ ) ;
150161
151162 loop {
152163 tokio:: time:: sleep ( flush_interval) . await ;
@@ -191,7 +202,11 @@ pub async fn run_stats_flush_loop(
191202 guard. remove ( & map_key) ;
192203 }
193204 }
194- if let Err ( e) = exporter. send ( true ) . await {
205+ if let Err ( e) =
206+ make_exporter ( & state, state. endpoint . clone ( ) , flush_interval, telemetry)
207+ . send ( true )
208+ . await
209+ {
195210 warn ! ( "Failed final stats flush: {e}" ) ;
196211 }
197212 break ;
@@ -210,6 +225,7 @@ pub async fn run_stats_flush_loop(
210225/// Returns `None` when stats config is not available (agentless or not yet configured).
211226pub ( crate ) fn get_or_create_concentrator (
212227 concentrators : & Arc < Mutex < HashMap < ConcentratorKey , Arc < SpanConcentratorState > > > > ,
228+ telemetry_clients : & crate :: service:: telemetry:: TelemetryCachedClientSet ,
213229 env : & str ,
214230 version : & str ,
215231 runtime_id : & str ,
@@ -270,8 +286,46 @@ pub(crate) fn get_or_create_concentrator(
270286 guard. insert ( map_key. clone ( ) , state. clone ( ) ) ;
271287 let weak = Arc :: downgrade ( concentrators) ;
272288 let flush_interval = config. flush_interval ;
289+
290+ let trace_config = session. get_trace_config ( ) ;
291+ let runtime_metadata = RuntimeMetadata :: new (
292+ trace_config. language . clone ( ) ,
293+ trace_config. language_version . clone ( ) ,
294+ trace_config. tracer_version . clone ( ) ,
295+ ) ;
296+ drop ( trace_config) ;
297+ let process_tags = session. process_tags . lock_or_panic ( ) . clone ( ) ;
298+ let instance_id = InstanceId {
299+ session_id : runtime_id. to_owned ( ) ,
300+ runtime_id : runtime_id. to_owned ( ) ,
301+ } ;
302+ let telemetry = {
303+ let telemetry_mutex = telemetry_clients. get_or_create (
304+ & service_name,
305+ env,
306+ & instance_id,
307+ & runtime_metadata,
308+ || { session
309+ . session_config
310+ . lock_or_panic ( )
311+ . as_ref ( )
312+ . cloned ( )
313+ . unwrap_or_else ( || {
314+ warn ! ( "Session telemetry config unavailable for env={env} version={version} service={service_name}; telemetry disabled in stats" ) ;
315+ Config :: default ( )
316+ } )
317+ } ,
318+ process_tags,
319+ ) ;
320+ let worker = telemetry_mutex
321+ . lock_or_panic ( )
322+ . as_ref ( )
323+ . map ( |c| c. worker . clone ( ) ) ;
324+ worker
325+ } ;
326+
273327 tokio:: spawn ( async move {
274- run_stats_flush_loop ( weak, map_key, flush_interval) . await ;
328+ run_stats_flush_loop ( weak, map_key, flush_interval, telemetry ) . await ;
275329 } ) ;
276330 Some ( state)
277331 }
@@ -292,7 +346,7 @@ pub async fn flush_all_stats_now(
292346 . values ( )
293347 . map ( |s| {
294348 (
295- make_exporter ( s, s. endpoint . clone ( ) , Duration :: from_secs ( 10 ) ) ,
349+ make_exporter ( s, s. endpoint . clone ( ) , Duration :: from_secs ( 10 ) , None ) ,
296350 s. endpoint . clone ( ) ,
297351 )
298352 } )
0 commit comments