@@ -270,17 +270,33 @@ impl Default for OpenTelemetryHandle {
270270const DEFAULT_OTLP_SERVICE_NAME : & str = "amaru" ;
271271const DEFAULT_OTLP_METRIC_URL : & str = "http://localhost:4318/v1/metrics" ;
272272
273+ /// Context hints supplied by the caller to refine observability defaults.
274+ pub trait ObservabilityHints {
275+ /// The address the node will listen on, if known at this point.
276+ /// Used to build the default `service.instance.id` resource attribute.
277+ fn listen_address ( & self ) -> Option < & str > ;
278+ }
279+
273280#[ expect( clippy:: panic) ]
274- pub fn setup_open_telemetry ( subscriber : & mut TracingSubscriber < Registry > ) -> ( OpenTelemetryHandle , DelayedWarning ) {
281+ pub fn setup_open_telemetry (
282+ subscriber : & mut TracingSubscriber < Registry > ,
283+ hints : & impl ObservabilityHints ,
284+ ) -> ( OpenTelemetryHandle , DelayedWarning ) {
275285 use opentelemetry:: KeyValue ;
276286 use opentelemetry_sdk:: { Resource , metrics:: Temporality } ;
277287
278288 let service_name =
279289 var ( "OTEL_SERVICE_NAME" ) . unwrap_or_else ( |_| DEFAULT_OTLP_SERVICE_NAME . to_string ( ) ) . trim ( ) . to_string ( ) ;
280- let service_instance_id = var ( "OTEL_SERVICE_INSTANCE_ID" ) . ok ( ) ;
290+ let service_instance_id: Option < String > =
291+ var ( "OTEL_SERVICE_INSTANCE_ID" ) . ok ( ) . map ( |v| v. trim ( ) . to_string ( ) ) . filter ( |v| !v. is_empty ( ) ) . or_else ( || {
292+ let listen_addr = hints. listen_address ( ) ?;
293+ let hostname = sysinfo:: System :: host_name ( ) . unwrap_or_else ( || "localhost" . to_string ( ) ) ;
294+ let port = listen_addr. trim ( ) . rsplit ( ':' ) . next ( ) ?;
295+ Some ( format ! ( "{hostname}:{port}" ) )
296+ } ) ;
281297 let mut attributes = vec ! [ KeyValue :: new( SERVICE_NAME , service_name. clone( ) ) ] ;
282- if let Some ( id ) = service_instance_id. filter ( |value| !value . trim ( ) . is_empty ( ) ) {
283- attributes. push ( KeyValue :: new ( SERVICE_INSTANCE_ID , id ) ) ;
298+ if let Some ( instance_id ) = service_instance_id {
299+ attributes. push ( KeyValue :: new ( SERVICE_INSTANCE_ID , instance_id ) ) ;
284300 }
285301 let resource = Resource :: builder ( ) . with_attributes ( attributes) . build ( ) ;
286302
@@ -465,11 +481,12 @@ pub fn setup_observability(
465481 with_open_telemetry : bool ,
466482 with_json_traces : bool ,
467483 color : bool ,
484+ hints : & impl ObservabilityHints ,
468485) -> ( Option < SdkMeterProvider > , Box < dyn FnOnce ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > > ) {
469486 let mut subscriber = TracingSubscriber :: new ( ) ;
470487
471488 let ( OpenTelemetryHandle { metrics, teardown } , warning_otlp) = if with_open_telemetry {
472- setup_open_telemetry ( & mut subscriber)
489+ setup_open_telemetry ( & mut subscriber, hints )
473490 } else {
474491 ( OpenTelemetryHandle :: default ( ) , None )
475492 } ;
0 commit comments