From b3747cfc8e0e273e49a65f5f721e69bea5c6c12d Mon Sep 17 00:00:00 2001 From: Corentin Leruth Date: Fri, 4 Oct 2024 18:10:34 +0200 Subject: [PATCH 1/2] add links to scope --- .../opentelemetry_client_ocurl.ml | 1 + src/core/opentelemetry.ml | 106 ++++++++++-------- .../cohttp/opentelemetry_cohttp_lwt.ml | 9 +- src/trace/opentelemetry_trace.ml | 8 +- 4 files changed, 74 insertions(+), 50 deletions(-) diff --git a/src/client-ocurl/opentelemetry_client_ocurl.ml b/src/client-ocurl/opentelemetry_client_ocurl.ml index d67be711..a0a9c39d 100644 --- a/src/client-ocurl/opentelemetry_client_ocurl.ml +++ b/src/client-ocurl/opentelemetry_client_ocurl.ml @@ -38,6 +38,7 @@ module Self_trace = struct span_id = dummy_span_id; attrs = []; events = []; + links = []; } in f scope diff --git a/src/core/opentelemetry.ml b/src/core/opentelemetry.ml index e4e3128a..4b030787 100644 --- a/src/core/opentelemetry.ml +++ b/src/core/opentelemetry.ml @@ -751,6 +751,49 @@ end = struct default_span_event ~time_unix_nano ~name ~attributes:attrs () end +(** Span Link + + A pointer from the current span to another span in the same trace or in a + different trace. For example, this can be used in batching operations, + where a single batch handler processes multiple requests from different + traces or when the handler receives a request from a different project. +*) +module Span_link : sig + open Proto.Trace + + type t = span_link + + val make : + trace_id:Trace_id.t -> + span_id:Span_id.t -> + ?trace_state:string -> + ?attrs:key_value list -> + ?dropped_attributes_count:int -> + unit -> + t + + val of_span_ctx : ?attrs:key_value list -> Span_ctx.t -> t +end = struct + open Proto.Trace + + type t = span_link + + let make ~trace_id ~span_id ?trace_state ?(attrs = []) + ?dropped_attributes_count () : t = + let attributes = List.map _conv_key_value attrs in + let dropped_attributes_count = + Option.map Int32.of_int dropped_attributes_count + in + default_span_link + ~trace_id:(Trace_id.to_bytes trace_id) + ~span_id:(Span_id.to_bytes span_id) ?trace_state ~attributes + ?dropped_attributes_count () + + let[@inline] of_span_ctx ?attrs (ctx : Span_ctx.t) : t = + make ~trace_id:(Span_ctx.trace_id ctx) ~span_id:(Span_ctx.parent_id ctx) + ?attrs () +end + (** {2 Scopes} *) (** Scopes. @@ -763,6 +806,7 @@ module Scope = struct span_id: Span_id.t; mutable events: Event.t list; mutable attrs: key_value list; + mutable links: Span_link.t list; } (** Turn the scope into a span context *) @@ -791,7 +835,7 @@ module Scope = struct scope.events <- ev :: scope.events ) - (** Add an attr to the scope. It will be aggregated into the span. + (** Add attributes to the scope. It will be aggregated into the span. Note that this takes a function that produces attributes, and will only call it if there is an instrumentation backend. *) @@ -799,6 +843,14 @@ module Scope = struct if Collector.has_backend () then scope.attrs <- List.rev_append (attrs ()) scope.attrs + (** Add links to the scope. It will be aggregated into the span. + + Note that this takes a function that produces links, and will only + call it if there is an instrumentation backend. *) + let[@inline] add_links (scope : t) (links : unit -> Span_link.t list) : unit = + if Collector.has_backend () then + scope.links <- List.rev_append (links ()) scope.links + (** The opaque key necessary to access/set the ambient scope with {!Ambient_context}. *) let ambient_scope_key : t Ambient_context.key = Ambient_context.create_key () @@ -820,49 +872,6 @@ end (** {2 Traces} *) -(** Span Link - - A pointer from the current span to another span in the same trace or in a - different trace. For example, this can be used in batching operations, - where a single batch handler processes multiple requests from different - traces or when the handler receives a request from a different project. -*) -module Span_link : sig - open Proto.Trace - - type t = span_link - - val make : - trace_id:Trace_id.t -> - span_id:Span_id.t -> - ?trace_state:string -> - ?attrs:key_value list -> - ?dropped_attributes_count:int -> - unit -> - t - - val of_span_ctx : ?attrs:key_value list -> Span_ctx.t -> t -end = struct - open Proto.Trace - - type t = span_link - - let make ~trace_id ~span_id ?trace_state ?(attrs = []) - ?dropped_attributes_count () : t = - let attributes = List.map _conv_key_value attrs in - let dropped_attributes_count = - Option.map Int32.of_int dropped_attributes_count - in - default_span_link - ~trace_id:(Trace_id.to_bytes trace_id) - ~span_id:(Span_id.to_bytes span_id) ?trace_state ~attributes - ?dropped_attributes_count () - - let[@inline] of_span_ctx ?attrs ctx : t = - make ~trace_id:(Span_ctx.trace_id ctx) ~span_id:(Span_ctx.parent_id ctx) - ?attrs () -end - (** Spans. A Span is the workhorse of traces, it indicates an operation that @@ -1007,6 +1016,7 @@ module Trace = struct span_id: Span_id.t; mutable events: Event.t list; mutable attrs: Span.key_value list; + mutable links: Span_link.t list; } [@@deprecated "use Scope.t"] @@ -1016,7 +1026,7 @@ module Trace = struct let with_' ?(force_new_trace_id = false) ?trace_state ?service_name ?(attrs : (string * [< value ]) list = []) ?kind ?trace_id ?parent ?scope - ?links name cb = + ?(links = []) name cb = let scope = if force_new_trace_id then None @@ -1039,7 +1049,7 @@ module Trace = struct in let start_time = Timestamp_ns.now_unix_ns () in let span_id = Span_id.create () in - let scope = { trace_id; span_id; events = []; attrs } in + let scope = { trace_id; span_id; events = []; attrs; links } in (* called once we're done, to emit a span *) let finally res = let status = @@ -1055,8 +1065,8 @@ module Trace = struct (* TODO: should the attrs passed to with_ go on the Span (in Span.create) or on the ResourceSpan (in emit)? (question also applies to Opentelemetry_lwt.Trace.with) *) - Span.create ?kind ~trace_id ?parent ?links ~id:span_id ?trace_state - ~attrs:scope.attrs ~events:scope.events ~start_time + Span.create ?kind ~trace_id ?parent ~links:scope.links ~id:span_id + ?trace_state ~attrs:scope.attrs ~events:scope.events ~start_time ~end_time:(Timestamp_ns.now_unix_ns ()) ~status name in diff --git a/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml b/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml index 9adb3902..a3ffc715 100644 --- a/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml +++ b/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml @@ -112,7 +112,14 @@ end = struct (match Traceparent.of_value v with | Ok (trace_id, parent_id) -> Some - Otel.Trace.{ trace_id; span_id = parent_id; events = []; attrs = [] } + Otel.Trace. + { + trace_id; + span_id = parent_id; + events = []; + attrs = []; + links = []; + } | Error _ -> None) let remove_trace_context req = diff --git a/src/trace/opentelemetry_trace.ml b/src/trace/opentelemetry_trace.ml index 8dfb1d13..a27788e9 100644 --- a/src/trace/opentelemetry_trace.ml +++ b/src/trace/opentelemetry_trace.ml @@ -122,7 +122,13 @@ module Internal = struct in let new_scope = - { Scope.span_id = otel_id; trace_id; events = []; attrs = data } + { + Scope.span_id = otel_id; + trace_id; + events = []; + attrs = data; + links = []; + } in let start_time = Timestamp_ns.now_unix_ns () in From 41f1f434705b3bfe678a62e2747b492c87dee1a4 Mon Sep 17 00:00:00 2001 From: Corentin Leruth Date: Mon, 7 Oct 2024 15:28:19 +0200 Subject: [PATCH 2/2] add Scope.make --- src/client-ocurl/opentelemetry_client_ocurl.ml | 8 +------- src/core/opentelemetry.ml | 6 +++++- src/integrations/cohttp/opentelemetry_cohttp_lwt.ml | 10 +--------- src/trace/opentelemetry_trace.ml | 10 +--------- 4 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/client-ocurl/opentelemetry_client_ocurl.ml b/src/client-ocurl/opentelemetry_client_ocurl.ml index a0a9c39d..d724f1c3 100644 --- a/src/client-ocurl/opentelemetry_client_ocurl.ml +++ b/src/client-ocurl/opentelemetry_client_ocurl.ml @@ -33,13 +33,7 @@ module Self_trace = struct else ( (* do nothing *) let scope = - { - Scope.trace_id = dummy_trace_id_; - span_id = dummy_span_id; - attrs = []; - events = []; - links = []; - } + Scope.make ~trace_id:dummy_trace_id_ ~span_id:dummy_span_id () in f scope ) diff --git a/src/core/opentelemetry.ml b/src/core/opentelemetry.ml index 4b030787..4cd7124e 100644 --- a/src/core/opentelemetry.ml +++ b/src/core/opentelemetry.ml @@ -809,6 +809,10 @@ module Scope = struct mutable links: Span_link.t list; } + let make ~trace_id ~span_id ?(events = []) ?(attrs = []) ?(links = []) () : t + = + { trace_id; span_id; events; attrs; links } + (** Turn the scope into a span context *) let[@inline] to_span_ctx (self : t) : Span_ctx.t = Span_ctx.make ~trace_id:self.trace_id ~parent_id:self.span_id () @@ -1049,7 +1053,7 @@ module Trace = struct in let start_time = Timestamp_ns.now_unix_ns () in let span_id = Span_id.create () in - let scope = { trace_id; span_id; events = []; attrs; links } in + let scope = Scope.make ~trace_id ~span_id ~attrs ~links () in (* called once we're done, to emit a span *) let finally res = let status = diff --git a/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml b/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml index a3ffc715..a0dee06f 100644 --- a/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml +++ b/src/integrations/cohttp/opentelemetry_cohttp_lwt.ml @@ -111,15 +111,7 @@ end = struct | Some v -> (match Traceparent.of_value v with | Ok (trace_id, parent_id) -> - Some - Otel.Trace. - { - trace_id; - span_id = parent_id; - events = []; - attrs = []; - links = []; - } + Some (Otel.Scope.make ~trace_id ~span_id:parent_id ()) | Error _ -> None) let remove_trace_context req = diff --git a/src/trace/opentelemetry_trace.ml b/src/trace/opentelemetry_trace.ml index a27788e9..9c53c33e 100644 --- a/src/trace/opentelemetry_trace.ml +++ b/src/trace/opentelemetry_trace.ml @@ -121,15 +121,7 @@ module Internal = struct | None, None -> None in - let new_scope = - { - Scope.span_id = otel_id; - trace_id; - events = []; - attrs = data; - links = []; - } - in + let new_scope = Otel.Scope.make ~trace_id ~span_id:otel_id ~attrs:data () in let start_time = Timestamp_ns.now_unix_ns () in let sb =