@@ -23,6 +23,7 @@ use opentelemetry_http::{HttpClient, ResponseExt};
23
23
use opentelemetry_semantic_conventions as semcov;
24
24
use std:: sync:: Arc ;
25
25
use std:: time:: Duration ;
26
+ use url:: Url ;
26
27
27
28
/// Default Datadog collector endpoint
28
29
const DEFAULT_AGENT_ENDPOINT : & str = "http://127.0.0.1:8126" ;
@@ -197,6 +198,25 @@ impl DatadogPipelineBuilder {
197
198
}
198
199
}
199
200
201
+ // parse the endpoint and append the path based on versions.
202
+ // keep the query and host the same.
203
+ fn build_endpoint ( agent_endpoint : & str , version : & str ) -> Result < Uri , TraceError > {
204
+ // build agent endpoint based on version
205
+ let mut endpoint = agent_endpoint
206
+ . parse :: < Url > ( )
207
+ . map_err :: < Error , _ > ( Into :: into) ?;
208
+ let mut paths = endpoint
209
+ . path_segments ( )
210
+ . map ( |c| c. filter ( |s| !s. is_empty ( ) ) . collect :: < Vec < _ > > ( ) )
211
+ . unwrap_or_default ( ) ;
212
+ paths. push ( version) ;
213
+
214
+ let path_str = paths. join ( "/" ) ;
215
+ endpoint. set_path ( path_str. as_str ( ) ) ;
216
+
217
+ Ok ( endpoint. as_str ( ) . parse ( ) . map_err :: < Error , _ > ( Into :: into) ?)
218
+ }
219
+
200
220
fn build_exporter_with_service_name (
201
221
self ,
202
222
service_name : String ,
@@ -206,10 +226,10 @@ impl DatadogPipelineBuilder {
206
226
service_name,
207
227
..Default :: default ( )
208
228
} ;
209
- let endpoint = self . agent_endpoint + self . version . path ( ) ;
229
+
210
230
let exporter = DatadogExporter :: new (
211
231
model_config,
212
- endpoint . parse ( ) . map_err :: < Error , _ > ( Into :: into ) ?,
232
+ Self :: build_endpoint ( & self . agent_endpoint , self . version . path ( ) ) ?,
213
233
self . version ,
214
234
client,
215
235
self . resource_mapping ,
@@ -266,7 +286,9 @@ impl DatadogPipelineBuilder {
266
286
self
267
287
}
268
288
269
- /// Assign the Datadog collector endpoint
289
+ /// Assign the Datadog collector endpoint.
290
+ ///
291
+ /// The endpoint of the datadog agent, by default it is `http://127.0.0.1:8126`.
270
292
pub fn with_agent_endpoint < T : Into < String > > ( mut self , endpoint : T ) -> Self {
271
293
self . agent_endpoint = endpoint. into ( ) ;
272
294
self
@@ -379,6 +401,7 @@ fn mapping_debug(f: &Option<FieldMapping>) -> String {
379
401
#[ cfg( test) ]
380
402
mod tests {
381
403
use super :: * ;
404
+ use crate :: ApiVersion :: Version05 ;
382
405
383
406
use crate :: exporter:: model:: tests:: get_span;
384
407
@@ -396,4 +419,34 @@ mod tests {
396
419
397
420
assert_eq ! ( traces, expected) ;
398
421
}
422
+
423
+ #[ test]
424
+ fn test_agent_endpoint_with_version ( ) {
425
+ let with_tail_slash =
426
+ DatadogPipelineBuilder :: build_endpoint ( "http://localhost:8126/" , Version05 . path ( ) ) ;
427
+ let without_tail_slash =
428
+ DatadogPipelineBuilder :: build_endpoint ( "http://localhost:8126" , Version05 . path ( ) ) ;
429
+ let with_query = DatadogPipelineBuilder :: build_endpoint (
430
+ "http://localhost:8126?api_key=123" ,
431
+ Version05 . path ( ) ,
432
+ ) ;
433
+ let invalid = DatadogPipelineBuilder :: build_endpoint (
434
+ "http://localhost:klsajfjksfh" ,
435
+ Version05 . path ( ) ,
436
+ ) ;
437
+
438
+ assert_eq ! (
439
+ with_tail_slash. unwrap( ) . to_string( ) ,
440
+ "http://localhost:8126/v0.5/traces"
441
+ ) ;
442
+ assert_eq ! (
443
+ without_tail_slash. unwrap( ) . to_string( ) ,
444
+ "http://localhost:8126/v0.5/traces"
445
+ ) ;
446
+ assert_eq ! (
447
+ with_query. unwrap( ) . to_string( ) ,
448
+ "http://localhost:8126/v0.5/traces?api_key=123"
449
+ ) ;
450
+ assert ! ( invalid. is_err( ) )
451
+ }
399
452
}
0 commit comments