mirror of
https://github.com/ocaml-tracing/ocaml-opentelemetry.git
synced 2026-03-07 18:37:56 -05:00
Merge branch 'master' into configurable-scope-storage
* master: fix ocurl: have ticker thread stop when work queue is closed fix get_url test to take config.url into account add get_url test with explicit config url chore: makefile update generated code opentelemetry: in Trace, change default span kind chore: migrate to OTEL proto files 1.0 CI: run on 5.0; run on every branch push remove use of String.ends_with for compat with 4.08 remove trailing slash from url shorter name for the instrumentation library use named signals
This commit is contained in:
commit
ed90772a57
18 changed files with 119 additions and 50 deletions
3
.github/workflows/main.yml
vendored
3
.github/workflows/main.yml
vendored
|
|
@ -3,8 +3,6 @@ name: build
|
|||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
@ -18,6 +16,7 @@ jobs:
|
|||
ocaml-compiler:
|
||||
- 4.08.x
|
||||
- 4.13.x
|
||||
- 5.0.x
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
|
|
|||
3
Makefile
3
Makefile
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
OPTS=--profile=release
|
||||
OPTS=--profile=release --ignore-promoted-rules
|
||||
|
||||
all:
|
||||
@dune build @all $(OPTS)
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,14 @@ end = struct
|
|||
(* send the content to the remote endpoint/path *)
|
||||
let send (_self : t) ~(config : Config.t) ~path ~decode (bod : string) :
|
||||
('a, error) result Lwt.t =
|
||||
let full_url = config.url ^ path in
|
||||
let url =
|
||||
let url = config.url in
|
||||
if url <> "" && String.get url (String.length url - 1) = '/' then
|
||||
String.sub url 0 (String.length url - 1)
|
||||
else
|
||||
url
|
||||
in
|
||||
let full_url = url ^ path in
|
||||
let uri = Uri.of_string full_url in
|
||||
|
||||
let open Cohttp in
|
||||
|
|
@ -552,6 +559,9 @@ end
|
|||
|
||||
let create_backend ?(stop = Atomic.make false) ?(config = Config.make ()) () =
|
||||
debug_ := config.debug;
|
||||
|
||||
if config.url <> get_url () then set_url config.url;
|
||||
|
||||
let module B =
|
||||
Backend
|
||||
(struct
|
||||
|
|
|
|||
|
|
@ -66,8 +66,17 @@ end
|
|||
(** start a thread in the background, running [f()] *)
|
||||
let start_bg_thread (f : unit -> unit) : Thread.t =
|
||||
let run () =
|
||||
(* block some signals: USR1 USR2 TERM PIPE ALARM STOP, see [$ kill -L] *)
|
||||
ignore (Thread.sigmask Unix.SIG_BLOCK [ 10; 12; 13; 14; 15; 19 ] : _ list);
|
||||
let signals =
|
||||
[
|
||||
Sys.sigusr1;
|
||||
Sys.sigusr2;
|
||||
Sys.sigterm;
|
||||
Sys.sigpipe;
|
||||
Sys.sigalrm;
|
||||
Sys.sigstop;
|
||||
]
|
||||
in
|
||||
ignore (Thread.sigmask Unix.SIG_BLOCK signals : _ list);
|
||||
f ()
|
||||
in
|
||||
Thread.create run ()
|
||||
|
|
@ -114,7 +123,14 @@ end = struct
|
|||
Pbrt.Encoder.reset encoder;
|
||||
encode x encoder;
|
||||
let data = Pbrt.Encoder.to_string encoder in
|
||||
let url = config.Config.url ^ path in
|
||||
let url =
|
||||
let url = config.Config.url in
|
||||
if url <> "" && String.get url (String.length url - 1) = '/' then
|
||||
String.sub url 0 (String.length url - 1)
|
||||
else
|
||||
url
|
||||
in
|
||||
let url = url ^ path in
|
||||
if !debug_ || config.debug then
|
||||
Printf.eprintf "opentelemetry: send http POST to %s (%dB)\n%!" url
|
||||
(String.length data);
|
||||
|
|
@ -420,10 +436,12 @@ let create_backend ?(stop = Atomic.make false)
|
|||
let setup_ticker_thread ~stop ~sleep_ms (module B : Collector.BACKEND) () =
|
||||
let sleep_s = float sleep_ms /. 1000. in
|
||||
let tick_loop () =
|
||||
while not @@ Atomic.get stop do
|
||||
Thread.delay sleep_s;
|
||||
B.tick ()
|
||||
done
|
||||
try
|
||||
while not @@ Atomic.get stop do
|
||||
Thread.delay sleep_s;
|
||||
B.tick ()
|
||||
done
|
||||
with B_queue.Closed -> ()
|
||||
in
|
||||
start_bg_thread tick_loop
|
||||
|
||||
|
|
@ -432,6 +450,8 @@ let setup_ ?(stop = Atomic.make false) ?(config : Config.t = Config.make ()) ()
|
|||
let ((module B) as backend) = create_backend ~stop ~config () in
|
||||
Opentelemetry.Collector.set_backend backend;
|
||||
|
||||
if config.url <> get_url () then set_url config.url;
|
||||
|
||||
if config.ticker_thread then (
|
||||
let sleep_ms = min 5_000 (max 2 config.batch_timeout_ms) in
|
||||
ignore (setup_ticker_thread ~stop ~sleep_ms backend () : Thread.t)
|
||||
|
|
|
|||
18
src/dune
18
src/dune
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets status_types.ml status_types.mli status_pb.ml status_pb.mli
|
||||
status_pp.ml status_pp.mli)
|
||||
(deps
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets common_types.ml common_types.mli common_pb.ml common_pb.mli
|
||||
common_pp.ml common_pp.mli)
|
||||
(deps
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets resource_types.ml resource_types.mli resource_pb.ml resource_pb.mli
|
||||
resource_pp.ml resource_pp.mli)
|
||||
(deps
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets trace_types.ml trace_types.mli trace_pb.ml trace_pb.mli trace_pp.ml
|
||||
trace_pp.mli)
|
||||
(deps
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets metrics_types.ml metrics_types.mli metrics_pb.ml metrics_pb.mli
|
||||
metrics_pp.ml metrics_pp.mli)
|
||||
(deps
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets logs_types.ml logs_types.mli logs_pb.ml logs_pb.mli logs_pp.ml
|
||||
logs_pp.mli)
|
||||
(deps
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets metrics_service_types.ml metrics_service_types.mli
|
||||
metrics_service_pp.ml metrics_service_pp.mli metrics_service_pb.ml
|
||||
metrics_service_pb.mli)
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets trace_service_types.ml trace_service_types.mli trace_service_pp.ml
|
||||
trace_service_pp.mli trace_service_pb.ml trace_service_pb.mli)
|
||||
(deps
|
||||
|
|
@ -112,7 +112,7 @@
|
|||
|
||||
(rule
|
||||
(alias lint)
|
||||
(mode fallback)
|
||||
(mode promote)
|
||||
(targets logs_service_types.ml logs_service_types.mli logs_service_pp.ml
|
||||
logs_service_pp.mli logs_service_pb.ml logs_service_pb.mli)
|
||||
(deps
|
||||
|
|
|
|||
|
|
@ -244,8 +244,8 @@ let rec decode_logs_data d =
|
|||
|
||||
let rec decode_log_record_flags d =
|
||||
match Pbrt.Decoder.int_as_varint d with
|
||||
| 0 -> (Logs_types.Log_record_flag_unspecified:Logs_types.log_record_flags)
|
||||
| 255 -> (Logs_types.Log_record_flag_trace_flags_mask:Logs_types.log_record_flags)
|
||||
| 0 -> (Logs_types.Log_record_flags_do_not_use:Logs_types.log_record_flags)
|
||||
| 255 -> (Logs_types.Log_record_flags_trace_flags_mask:Logs_types.log_record_flags)
|
||||
| _ -> Pbrt.Decoder.malformed_variant "log_record_flags"
|
||||
|
||||
let rec encode_severity_number (v:Logs_types.severity_number) encoder =
|
||||
|
|
@ -344,5 +344,5 @@ let rec encode_logs_data (v:Logs_types.logs_data) encoder =
|
|||
|
||||
let rec encode_log_record_flags (v:Logs_types.log_record_flags) encoder =
|
||||
match v with
|
||||
| Logs_types.Log_record_flag_unspecified -> Pbrt.Encoder.int_as_varint (0) encoder
|
||||
| Logs_types.Log_record_flag_trace_flags_mask -> Pbrt.Encoder.int_as_varint 255 encoder
|
||||
| Logs_types.Log_record_flags_do_not_use -> Pbrt.Encoder.int_as_varint (0) encoder
|
||||
| Logs_types.Log_record_flags_trace_flags_mask -> Pbrt.Encoder.int_as_varint 255 encoder
|
||||
|
|
|
|||
|
|
@ -67,5 +67,5 @@ let rec pp_logs_data fmt (v:Logs_types.logs_data) =
|
|||
|
||||
let rec pp_log_record_flags fmt (v:Logs_types.log_record_flags) =
|
||||
match v with
|
||||
| Logs_types.Log_record_flag_unspecified -> Format.fprintf fmt "Log_record_flag_unspecified"
|
||||
| Logs_types.Log_record_flag_trace_flags_mask -> Format.fprintf fmt "Log_record_flag_trace_flags_mask"
|
||||
| Logs_types.Log_record_flags_do_not_use -> Format.fprintf fmt "Log_record_flags_do_not_use"
|
||||
| Logs_types.Log_record_flags_trace_flags_mask -> Format.fprintf fmt "Log_record_flags_trace_flags_mask"
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ type logs_data = {
|
|||
}
|
||||
|
||||
type log_record_flags =
|
||||
| Log_record_flag_unspecified
|
||||
| Log_record_flag_trace_flags_mask
|
||||
| Log_record_flags_do_not_use
|
||||
| Log_record_flags_trace_flags_mask
|
||||
|
||||
let rec default_severity_number () = (Severity_number_unspecified:severity_number)
|
||||
|
||||
|
|
@ -113,4 +113,4 @@ let rec default_logs_data
|
|||
resource_logs;
|
||||
}
|
||||
|
||||
let rec default_log_record_flags () = (Log_record_flag_unspecified:log_record_flags)
|
||||
let rec default_log_record_flags () = (Log_record_flags_do_not_use:log_record_flags)
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ type logs_data = {
|
|||
}
|
||||
|
||||
type log_record_flags =
|
||||
| Log_record_flag_unspecified
|
||||
| Log_record_flag_trace_flags_mask
|
||||
| Log_record_flags_do_not_use
|
||||
| Log_record_flags_trace_flags_mask
|
||||
|
||||
|
||||
(** {2 Default values} *)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ type exponential_histogram_data_point_mutable = {
|
|||
mutable exemplars : Metrics_types.exemplar list;
|
||||
mutable min : float option;
|
||||
mutable max : float option;
|
||||
mutable zero_threshold : float;
|
||||
}
|
||||
|
||||
let default_exponential_histogram_data_point_mutable () : exponential_histogram_data_point_mutable = {
|
||||
|
|
@ -132,6 +133,7 @@ let default_exponential_histogram_data_point_mutable () : exponential_histogram_
|
|||
exemplars = [];
|
||||
min = None;
|
||||
max = None;
|
||||
zero_threshold = 0.;
|
||||
}
|
||||
|
||||
type exponential_histogram_mutable = {
|
||||
|
|
@ -625,6 +627,11 @@ let rec decode_exponential_histogram_data_point d =
|
|||
end
|
||||
| Some (13, pk) ->
|
||||
Pbrt.Decoder.unexpected_payload "Message(exponential_histogram_data_point), field(13)" pk
|
||||
| Some (14, Pbrt.Bits64) -> begin
|
||||
v.zero_threshold <- Pbrt.Decoder.float_as_bits64 d;
|
||||
end
|
||||
| Some (14, pk) ->
|
||||
Pbrt.Decoder.unexpected_payload "Message(exponential_histogram_data_point), field(14)" pk
|
||||
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
|
||||
done;
|
||||
({
|
||||
|
|
@ -641,6 +648,7 @@ let rec decode_exponential_histogram_data_point d =
|
|||
Metrics_types.exemplars = v.exemplars;
|
||||
Metrics_types.min = v.min;
|
||||
Metrics_types.max = v.max;
|
||||
Metrics_types.zero_threshold = v.zero_threshold;
|
||||
} : Metrics_types.exponential_histogram_data_point)
|
||||
|
||||
let rec decode_exponential_histogram d =
|
||||
|
|
@ -924,8 +932,8 @@ let rec decode_metrics_data d =
|
|||
|
||||
let rec decode_data_point_flags d =
|
||||
match Pbrt.Decoder.int_as_varint d with
|
||||
| 0 -> (Metrics_types.Flag_none:Metrics_types.data_point_flags)
|
||||
| 1 -> (Metrics_types.Flag_no_recorded_value:Metrics_types.data_point_flags)
|
||||
| 0 -> (Metrics_types.Data_point_flags_do_not_use:Metrics_types.data_point_flags)
|
||||
| 1 -> (Metrics_types.Data_point_flags_no_recorded_value_mask:Metrics_types.data_point_flags)
|
||||
| _ -> Pbrt.Decoder.malformed_variant "data_point_flags"
|
||||
|
||||
let rec encode_exemplar_value (v:Metrics_types.exemplar_value) encoder =
|
||||
|
|
@ -1138,6 +1146,8 @@ let rec encode_exponential_histogram_data_point (v:Metrics_types.exponential_his
|
|||
Pbrt.Encoder.float_as_bits64 x encoder;
|
||||
| None -> ();
|
||||
end;
|
||||
Pbrt.Encoder.key (14, Pbrt.Bits64) encoder;
|
||||
Pbrt.Encoder.float_as_bits64 v.Metrics_types.zero_threshold encoder;
|
||||
()
|
||||
|
||||
let rec encode_exponential_histogram (v:Metrics_types.exponential_histogram) encoder =
|
||||
|
|
@ -1268,5 +1278,5 @@ let rec encode_metrics_data (v:Metrics_types.metrics_data) encoder =
|
|||
|
||||
let rec encode_data_point_flags (v:Metrics_types.data_point_flags) encoder =
|
||||
match v with
|
||||
| Metrics_types.Flag_none -> Pbrt.Encoder.int_as_varint (0) encoder
|
||||
| Metrics_types.Flag_no_recorded_value -> Pbrt.Encoder.int_as_varint 1 encoder
|
||||
| Metrics_types.Data_point_flags_do_not_use -> Pbrt.Encoder.int_as_varint (0) encoder
|
||||
| Metrics_types.Data_point_flags_no_recorded_value_mask -> Pbrt.Encoder.int_as_varint 1 encoder
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ let rec pp_exponential_histogram_data_point fmt (v:Metrics_types.exponential_his
|
|||
Pbrt.Pp.pp_record_field ~first:false "exemplars" (Pbrt.Pp.pp_list pp_exemplar) fmt v.Metrics_types.exemplars;
|
||||
Pbrt.Pp.pp_record_field ~first:false "min" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.Metrics_types.min;
|
||||
Pbrt.Pp.pp_record_field ~first:false "max" (Pbrt.Pp.pp_option Pbrt.Pp.pp_float) fmt v.Metrics_types.max;
|
||||
Pbrt.Pp.pp_record_field ~first:false "zero_threshold" Pbrt.Pp.pp_float fmt v.Metrics_types.zero_threshold;
|
||||
in
|
||||
Pbrt.Pp.pp_brk pp_i fmt ()
|
||||
|
||||
|
|
@ -172,5 +173,5 @@ let rec pp_metrics_data fmt (v:Metrics_types.metrics_data) =
|
|||
|
||||
let rec pp_data_point_flags fmt (v:Metrics_types.data_point_flags) =
|
||||
match v with
|
||||
| Metrics_types.Flag_none -> Format.fprintf fmt "Flag_none"
|
||||
| Metrics_types.Flag_no_recorded_value -> Format.fprintf fmt "Flag_no_recorded_value"
|
||||
| Metrics_types.Data_point_flags_do_not_use -> Format.fprintf fmt "Data_point_flags_do_not_use"
|
||||
| Metrics_types.Data_point_flags_no_recorded_value_mask -> Format.fprintf fmt "Data_point_flags_no_recorded_value_mask"
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ type exponential_histogram_data_point = {
|
|||
exemplars : exemplar list;
|
||||
min : float option;
|
||||
max : float option;
|
||||
zero_threshold : float;
|
||||
}
|
||||
|
||||
type exponential_histogram = {
|
||||
|
|
@ -136,8 +137,8 @@ type metrics_data = {
|
|||
}
|
||||
|
||||
type data_point_flags =
|
||||
| Flag_none
|
||||
| Flag_no_recorded_value
|
||||
| Data_point_flags_do_not_use
|
||||
| Data_point_flags_no_recorded_value_mask
|
||||
|
||||
let rec default_exemplar_value () : exemplar_value = As_double (0.)
|
||||
|
||||
|
|
@ -247,6 +248,7 @@ let rec default_exponential_histogram_data_point
|
|||
?exemplars:((exemplars:exemplar list) = [])
|
||||
?min:((min:float option) = None)
|
||||
?max:((max:float option) = None)
|
||||
?zero_threshold:((zero_threshold:float) = 0.)
|
||||
() : exponential_histogram_data_point = {
|
||||
attributes;
|
||||
start_time_unix_nano;
|
||||
|
|
@ -261,6 +263,7 @@ let rec default_exponential_histogram_data_point
|
|||
exemplars;
|
||||
min;
|
||||
max;
|
||||
zero_threshold;
|
||||
}
|
||||
|
||||
let rec default_exponential_histogram
|
||||
|
|
@ -343,4 +346,4 @@ let rec default_metrics_data
|
|||
resource_metrics;
|
||||
}
|
||||
|
||||
let rec default_data_point_flags () = (Flag_none:data_point_flags)
|
||||
let rec default_data_point_flags () = (Data_point_flags_do_not_use:data_point_flags)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ type exponential_histogram_data_point = {
|
|||
exemplars : exemplar list;
|
||||
min : float option;
|
||||
max : float option;
|
||||
zero_threshold : float;
|
||||
}
|
||||
|
||||
type exponential_histogram = {
|
||||
|
|
@ -139,8 +140,8 @@ type metrics_data = {
|
|||
}
|
||||
|
||||
type data_point_flags =
|
||||
| Flag_none
|
||||
| Flag_no_recorded_value
|
||||
| Data_point_flags_do_not_use
|
||||
| Data_point_flags_no_recorded_value_mask
|
||||
|
||||
|
||||
(** {2 Default values} *)
|
||||
|
|
@ -233,6 +234,7 @@ val default_exponential_histogram_data_point :
|
|||
?exemplars:exemplar list ->
|
||||
?min:float option ->
|
||||
?max:float option ->
|
||||
?zero_threshold:float ->
|
||||
unit ->
|
||||
exponential_histogram_data_point
|
||||
(** [default_exponential_histogram_data_point ()] is the default value for type [exponential_histogram_data_point] *)
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ module Globals = struct
|
|||
let service_instance_id = ref None
|
||||
|
||||
let instrumentation_library =
|
||||
default_instrumentation_scope ~version:"0.2" ~name:"ocaml-opentelemetry" ()
|
||||
default_instrumentation_scope ~version:"0.2" ~name:"ocaml-otel" ()
|
||||
|
||||
(** Global attributes, initially set
|
||||
via OTEL_RESOURCE_ATTRIBUTES and modifiable
|
||||
|
|
@ -507,10 +507,11 @@ module Globals = struct
|
|||
List.rev_append (List.filter not_redundant !global_attributes) into
|
||||
|
||||
(** Default span kind in {!Span.create}.
|
||||
This will be used in all spans that do not specify [~kind] explicitly.
|
||||
This will be used in all spans that do not specify [~kind] explicitly;
|
||||
it is set to "internal", following directions from the [.proto] file.
|
||||
It can be convenient to set "client" or "server" uniformly in here.
|
||||
@since 0.4 *)
|
||||
let default_span_kind = ref Proto.Trace.Span_kind_unspecified
|
||||
let default_span_kind = ref Proto.Trace.Span_kind_internal
|
||||
|
||||
let mk_attributes ?(service_name = !service_name) ?(attrs = []) () : _ list =
|
||||
let l = List.map _conv_key_value attrs in
|
||||
|
|
@ -1011,8 +1012,8 @@ module Logs = struct
|
|||
let pp_severity = Logs_pp.pp_severity_number
|
||||
|
||||
type flags = Logs_types.log_record_flags =
|
||||
| Log_record_flag_unspecified
|
||||
| Log_record_flag_trace_flags_mask
|
||||
| Log_record_flags_do_not_use
|
||||
| Log_record_flags_trace_flags_mask
|
||||
|
||||
let pp_flags = Logs_pp.pp_log_record_flags
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
(tests
|
||||
(names test_trace_context)
|
||||
(libraries opentelemetry))
|
||||
(names test_trace_context test_get_url)
|
||||
(libraries
|
||||
opentelemetry
|
||||
opentelemetry-client-ocurl
|
||||
opentelemetry-client-cohttp-lwt))
|
||||
|
|
|
|||
2
tests/test_get_url.expected
Normal file
2
tests/test_get_url.expected
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ocurl url = http://localhost:3000
|
||||
cohttp url = http://localhost:3000
|
||||
17
tests/test_get_url.ml
Normal file
17
tests/test_get_url.ml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
let url = "http://localhost:3000"
|
||||
|
||||
let ocurl () =
|
||||
let config = Opentelemetry_client_ocurl.Config.make ~url () in
|
||||
Opentelemetry_client_ocurl.with_setup ~config () @@ fun () ->
|
||||
let url = Opentelemetry_client_ocurl.get_url () in
|
||||
print_endline @@ Printf.sprintf "ocurl url = %s" url
|
||||
|
||||
let cohttp () =
|
||||
let config = Opentelemetry_client_cohttp_lwt.Config.make ~url () in
|
||||
Opentelemetry_client_cohttp_lwt.with_setup ~config () @@ fun () ->
|
||||
let url = Opentelemetry_client_cohttp_lwt.get_url () in
|
||||
print_endline @@ Printf.sprintf "cohttp url = %s" url
|
||||
|
||||
let () =
|
||||
ocurl ();
|
||||
cohttp ()
|
||||
2
vendor/opentelemetry-proto
vendored
2
vendor/opentelemetry-proto
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 6459e1aae1c22e273ac92be86016f0ae55a2430a
|
||||
Subproject commit c4dfbc51f3cd4089778555a2ac5d9bc093ed2956
|
||||
Loading…
Add table
Reference in a new issue