diff --git a/src/lwt/opentelemetry_lwt.ml b/src/lwt/opentelemetry_lwt.ml index a780bc6c..d458eca2 100644 --- a/src/lwt/opentelemetry_lwt.ml +++ b/src/lwt/opentelemetry_lwt.ml @@ -4,6 +4,8 @@ open Opentelemetry module Span_id = Span_id module Trace_id = Trace_id module Span = Span +module Globals = Globals +module Timestamp_ns = Timestamp_ns module Trace = struct open Proto.Trace diff --git a/src/opentelemetry.ml b/src/opentelemetry.ml index b61246e1..f9948875 100644 --- a/src/opentelemetry.ml +++ b/src/opentelemetry.ml @@ -153,6 +153,36 @@ end = struct let of_bytes b = assert(Bytes.length b=8); b end +(** Process-wide metadata, environment variables, etc. *) +module Globals = struct + open Proto.Common + + let service_name = ref "unknown_service" + (** Main service name metadata *) + + let service_namespace = ref None + (** Namespace for the service *) + + let instrumentation_library = + default_instrumentation_library + ~name:"ocaml-opentelemetry" () (* TODO: version, perhaps with dune subst? *) + + (** Global attributes, set via OTEL_RESOURCE_ATTRIBUTE *) + let global_attributes : key_value list = + let parse_pair s = match String.split_on_char '=' s with + | [a;b] -> default_key_value ~key:a ~value:(Some (String_value b)) () + | _ -> failwith (Printf.sprintf "invalid attribute: %S" s) + in + try + Sys.getenv "OTEL_RESOURCE_ATTRIBUTE" |> String.split_on_char ',' + |> List.map parse_pair + with _ -> [] + + (* add global attributes to this list *) + let merge_global_attributes_ into : _ list = + let not_redundant kv = List.for_all (fun kv' -> kv.key <> kv'.key) into in + List.rev_append (List.filter not_redundant global_attributes) into +end (* TODO: Event.t, use it in Span *) @@ -241,7 +271,7 @@ end = struct ?(kind=Span_kind_unspecified) ?(id=Span_id.create()) ?trace_state - ?service_name + ?(service_name= !Globals.service_name) ?(attrs=[]) ?status ~trace_id ?parent ?(links=[]) @@ -263,13 +293,17 @@ end = struct default_key_value ~key:k ~value ()) attrs in - let l = match service_name with + let l = + default_key_value ~key:"service.name" + ~value:(Some (String_value service_name)) () :: l + in + let l = match !Globals.service_namespace with | None -> l | Some v -> - default_key_value ~key:"service.name" + default_key_value ~key:"service.namespace" ~value:(Some (String_value v)) () :: l in - l + l |> Globals.merge_global_attributes_ in let links = @@ -305,7 +339,9 @@ module Trace = struct (** Sync emitter *) let emit (spans:span list) : unit = let ils = - default_instrumentation_library_spans ~spans () in + default_instrumentation_library_spans + ~instrumentation_library:(Some Globals.instrumentation_library) + ~spans () in let rs = default_resource_spans ~instrumentation_library_spans:[ils] () in Collector.send_trace [rs] ~over:(fun () -> ()) ~ret:(fun () -> ()) @@ -396,7 +432,9 @@ module Metrics = struct (** Emit some metrics to the collector (sync). *) let emit (l:t list) : unit = let lm = - default_instrumentation_library_metrics ~metrics:l () in + default_instrumentation_library_metrics + ~instrumentation_library:(Some Globals.instrumentation_library) + ~metrics:l () in let rm = default_resource_metrics ~instrumentation_library_metrics:[lm] () in Collector.send_metrics [rm] ~over:ignore ~ret:ignore diff --git a/tests/emit1.ml b/tests/emit1.ml index 17a621c1..52296b86 100644 --- a/tests/emit1.ml +++ b/tests/emit1.ml @@ -3,20 +3,18 @@ module T = Opentelemetry let spf = Printf.sprintf let (let@) f x = f x -let service_name = "t1" - let run () = Printf.printf "collector is on %S\n%!" (Opentelemetry_client_ocurl.get_url()); let i = ref 0 in while true do let@ (tr,sp) = T.Trace.with_ ~kind:T.Span.Span_kind_producer - ~service_name "loop.outer" ~attrs:["i", `Int !i] in + "loop.outer" ~attrs:["i", `Int !i] in for j=0 to 4 do let@ (_,sp) = T.Trace.with_ ~kind:T.Span.Span_kind_internal ~trace_id:tr ~parent:sp - ~service_name ~attrs:["j", `Int j] + ~attrs:["j", `Int j] "loop.inner" in Unix.sleepf 2.; @@ -34,7 +32,6 @@ let run () = let@ _ = T.Trace.with_ ~kind:T.Span.Span_kind_internal ~trace_id:tr ~parent:sp - ~service_name "alloc" in (* allocate some stuff *) let _arr = Sys.opaque_identity @@ Array.make (25 * 25551) 42.0 in @@ -47,4 +44,6 @@ let run () = done let () = + T.Globals.service_name := Some "t1"; + T.Globals.service_namespace := Some "ocaml-otel.test"; Opentelemetry_client_ocurl.with_setup run