mirror of
https://github.com/ocaml-tracing/ocaml-trace.git
synced 2026-03-13 14:06:24 -04:00
refactor tef: move writer into its own file
This commit is contained in:
parent
46242cd817
commit
92d0a07168
5 changed files with 271 additions and 191 deletions
18
src/tef/common_.ml
Normal file
18
src/tef/common_.ml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
let[@inline] int64_of_trace_id_ (id : Trace_core.trace_id) : int64 =
|
||||||
|
if id == Trace_core.Collector.dummy_trace_id then
|
||||||
|
0L
|
||||||
|
else
|
||||||
|
Bytes.get_int64_le (Bytes.unsafe_of_string id) 0
|
||||||
|
|
||||||
|
module Mock_ = struct
|
||||||
|
let enabled = ref false
|
||||||
|
let now = ref 0
|
||||||
|
|
||||||
|
(* used to mock timing *)
|
||||||
|
let get_now_ns () : float =
|
||||||
|
let x = !now in
|
||||||
|
incr now;
|
||||||
|
float_of_int x *. 1000.
|
||||||
|
|
||||||
|
let get_tid_ () : int = 3
|
||||||
|
end
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
trace.core
|
trace.core
|
||||||
trace.private.util
|
trace.private.util
|
||||||
trace.subscriber
|
trace.subscriber
|
||||||
|
trace.stdext
|
||||||
mtime
|
mtime
|
||||||
mtime.clock.os
|
mtime.clock.os
|
||||||
unix
|
unix
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,13 @@
|
||||||
open Trace_core
|
open Trace_core
|
||||||
open Trace_private_util
|
open Trace_private_util
|
||||||
open Event
|
open Event
|
||||||
|
open Common_
|
||||||
module Sub = Trace_subscriber
|
module Sub = Trace_subscriber
|
||||||
module A = Trace_core.Internal_.Atomic_
|
module A = Trace_core.Internal_.Atomic_
|
||||||
|
module Writer = Writer
|
||||||
|
|
||||||
let on_tracing_error = ref (fun s -> Printf.eprintf "trace-tef error: %s\n%!" s)
|
let on_tracing_error = ref (fun s -> Printf.eprintf "trace-tef error: %s\n%!" s)
|
||||||
|
|
||||||
let[@inline] int64_of_trace_id_ (id : Trace_core.trace_id) : int64 =
|
|
||||||
if id == Trace_core.Collector.dummy_trace_id then
|
|
||||||
0L
|
|
||||||
else
|
|
||||||
Bytes.get_int64_le (Bytes.unsafe_of_string id) 0
|
|
||||||
|
|
||||||
module Mock_ = struct
|
|
||||||
let enabled = ref false
|
|
||||||
let now = ref 0
|
|
||||||
|
|
||||||
(* used to mock timing *)
|
|
||||||
let get_now_ns () : float =
|
|
||||||
let x = !now in
|
|
||||||
incr now;
|
|
||||||
float_of_int x *. 1000.
|
|
||||||
|
|
||||||
let get_tid_ () : int = 3
|
|
||||||
end
|
|
||||||
|
|
||||||
module Span_tbl = Hashtbl.Make (struct
|
module Span_tbl = Hashtbl.Make (struct
|
||||||
include Int64
|
include Int64
|
||||||
|
|
||||||
|
|
@ -38,178 +21,6 @@ type span_info = {
|
||||||
mutable data: (string * Sub.user_data) list;
|
mutable data: (string * Sub.user_data) list;
|
||||||
}
|
}
|
||||||
|
|
||||||
(** Writer: knows how to write entries to a file in TEF format *)
|
|
||||||
module Writer = struct
|
|
||||||
type t = {
|
|
||||||
oc: out_channel;
|
|
||||||
jsonl: bool; (** JSONL mode, one json event per line *)
|
|
||||||
mutable first: bool; (** first event? useful in json mode *)
|
|
||||||
buf: Buffer.t; (** Buffer to write into *)
|
|
||||||
must_close: bool; (** Do we have to close the underlying channel [oc]? *)
|
|
||||||
pid: int;
|
|
||||||
}
|
|
||||||
(** A writer to a [out_channel]. It writes JSON entries in an array and closes
|
|
||||||
the array at the end. *)
|
|
||||||
|
|
||||||
let create ~(mode : [ `Single | `Jsonl ]) ~out () : t =
|
|
||||||
let jsonl = mode = `Jsonl in
|
|
||||||
let oc, must_close =
|
|
||||||
match out with
|
|
||||||
| `Stdout -> stdout, false
|
|
||||||
| `Stderr -> stderr, false
|
|
||||||
| `File path -> open_out path, true
|
|
||||||
| `File_append path ->
|
|
||||||
open_out_gen [ Open_creat; Open_wronly; Open_append ] 0o644 path, true
|
|
||||||
| `Output oc -> oc, false
|
|
||||||
in
|
|
||||||
let pid =
|
|
||||||
if !Mock_.enabled then
|
|
||||||
2
|
|
||||||
else
|
|
||||||
Unix.getpid ()
|
|
||||||
in
|
|
||||||
if not jsonl then output_char oc '[';
|
|
||||||
{ oc; jsonl; first = true; pid; must_close; buf = Buffer.create 2_048 }
|
|
||||||
|
|
||||||
let close (self : t) : unit =
|
|
||||||
if self.jsonl then
|
|
||||||
output_char self.oc '\n'
|
|
||||||
else
|
|
||||||
output_char self.oc ']';
|
|
||||||
flush self.oc;
|
|
||||||
if self.must_close then close_out self.oc
|
|
||||||
|
|
||||||
let with_ ~mode ~out f =
|
|
||||||
let writer = create ~mode ~out () in
|
|
||||||
Fun.protect ~finally:(fun () -> close writer) (fun () -> f writer)
|
|
||||||
|
|
||||||
let[@inline] flush (self : t) : unit = flush self.oc
|
|
||||||
|
|
||||||
(** Emit "," if we need, and get the buffer ready *)
|
|
||||||
let emit_sep_and_start_ (self : t) =
|
|
||||||
Buffer.reset self.buf;
|
|
||||||
if self.jsonl then
|
|
||||||
Buffer.add_char self.buf '\n'
|
|
||||||
else if self.first then
|
|
||||||
self.first <- false
|
|
||||||
else
|
|
||||||
Buffer.add_string self.buf ",\n"
|
|
||||||
|
|
||||||
let char = Buffer.add_char
|
|
||||||
let raw_string = Buffer.add_string
|
|
||||||
|
|
||||||
let str_val (buf : Buffer.t) (s : string) =
|
|
||||||
char buf '"';
|
|
||||||
let encode_char c =
|
|
||||||
match c with
|
|
||||||
| '"' -> raw_string buf {|\"|}
|
|
||||||
| '\\' -> raw_string buf {|\\|}
|
|
||||||
| '\n' -> raw_string buf {|\n|}
|
|
||||||
| '\b' -> raw_string buf {|\b|}
|
|
||||||
| '\r' -> raw_string buf {|\r|}
|
|
||||||
| '\t' -> raw_string buf {|\t|}
|
|
||||||
| _ when Char.code c <= 0x1f ->
|
|
||||||
raw_string buf {|\u00|};
|
|
||||||
Printf.bprintf buf "%02x" (Char.code c)
|
|
||||||
| c -> char buf c
|
|
||||||
in
|
|
||||||
String.iter encode_char s;
|
|
||||||
char buf '"'
|
|
||||||
|
|
||||||
let pp_user_data_ (out : Buffer.t) : Sub.user_data -> unit = function
|
|
||||||
| U_none -> raw_string out "null"
|
|
||||||
| U_int i -> Printf.bprintf out "%d" i
|
|
||||||
| U_bool b -> Printf.bprintf out "%b" b
|
|
||||||
| U_string s -> str_val out s
|
|
||||||
| U_float f -> Printf.bprintf out "%g" f
|
|
||||||
|
|
||||||
(* emit args, if not empty. [ppv] is used to print values. *)
|
|
||||||
let emit_args_o_ ppv (out : Buffer.t) args : unit =
|
|
||||||
if args <> [] then (
|
|
||||||
Printf.bprintf out {json|,"args": {|json};
|
|
||||||
List.iteri
|
|
||||||
(fun i (n, value) ->
|
|
||||||
if i > 0 then raw_string out ",";
|
|
||||||
Printf.bprintf out {json|"%s":%a|json} n ppv value)
|
|
||||||
args;
|
|
||||||
char out '}'
|
|
||||||
)
|
|
||||||
|
|
||||||
let emit_duration_event ~tid ~name ~start ~end_ ~args (self : t) : unit =
|
|
||||||
let dur = end_ -. start in
|
|
||||||
let ts = start in
|
|
||||||
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"cat":"","tid": %d,"dur": %.2f,"ts": %.2f,"name":%a,"ph":"X"%a}|json}
|
|
||||||
self.pid tid dur ts str_val name
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
args;
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
|
|
||||||
let emit_manual_begin ~tid ~name ~(id : trace_id) ~ts ~args
|
|
||||||
~(flavor : Sub.flavor option) (self : t) : unit =
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"cat":"trace","id":%Ld,"tid": %d,"ts": %.2f,"name":%a,"ph":"%c"%a}|json}
|
|
||||||
self.pid (int64_of_trace_id_ id) tid ts str_val name
|
|
||||||
(match flavor with
|
|
||||||
| None | Some Async -> 'b'
|
|
||||||
| Some Sync -> 'B')
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
args;
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
|
|
||||||
let emit_manual_end ~tid ~name ~(id : trace_id) ~ts
|
|
||||||
~(flavor : Sub.flavor option) ~args (self : t) : unit =
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"cat":"trace","id":%Ld,"tid": %d,"ts": %.2f,"name":%a,"ph":"%c"%a}|json}
|
|
||||||
self.pid (int64_of_trace_id_ id) tid ts str_val name
|
|
||||||
(match flavor with
|
|
||||||
| None | Some Async -> 'e'
|
|
||||||
| Some Sync -> 'E')
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
args;
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
|
|
||||||
let emit_instant_event ~tid ~name ~ts ~args (self : t) : unit =
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"cat":"","tid": %d,"ts": %.2f,"name":%a,"ph":"I"%a}|json}
|
|
||||||
self.pid tid ts str_val name
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
args;
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
|
|
||||||
let emit_name_thread ~tid ~name (self : t) : unit =
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"tid": %d,"name":"thread_name","ph":"M"%a}|json} self.pid
|
|
||||||
tid
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
[ "name", U_string name ];
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
|
|
||||||
let emit_name_process ~name (self : t) : unit =
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"name":"process_name","ph":"M"%a}|json} self.pid
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
[ "name", U_string name ];
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
|
|
||||||
let emit_counter ~name ~tid ~ts (self : t) f : unit =
|
|
||||||
emit_sep_and_start_ self;
|
|
||||||
Printf.bprintf self.buf
|
|
||||||
{json|{"pid":%d,"tid":%d,"ts":%.2f,"name":"c","ph":"C"%a}|json} self.pid
|
|
||||||
tid ts
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
[ name, U_float f ];
|
|
||||||
Buffer.output_buffer self.oc self.buf
|
|
||||||
end
|
|
||||||
|
|
||||||
let block_signals () =
|
let block_signals () =
|
||||||
try
|
try
|
||||||
ignore
|
ignore
|
||||||
|
|
|
||||||
170
src/tef/writer.ml
Normal file
170
src/tef/writer.ml
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
open Trace_core
|
||||||
|
open Common_
|
||||||
|
module Sub = Trace_subscriber
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
oc: out_channel;
|
||||||
|
jsonl: bool; (** JSONL mode, one json event per line *)
|
||||||
|
mutable first: bool; (** first event? useful in json mode *)
|
||||||
|
buf: Buffer.t; (** Buffer to write into *)
|
||||||
|
must_close: bool; (** Do we have to close the underlying channel [oc]? *)
|
||||||
|
pid: int;
|
||||||
|
}
|
||||||
|
|
||||||
|
let create ~(mode : [ `Single | `Jsonl ]) ~out () : t =
|
||||||
|
let jsonl = mode = `Jsonl in
|
||||||
|
let oc, must_close =
|
||||||
|
match out with
|
||||||
|
| `Stdout -> stdout, false
|
||||||
|
| `Stderr -> stderr, false
|
||||||
|
| `File path -> open_out path, true
|
||||||
|
| `File_append path ->
|
||||||
|
open_out_gen [ Open_creat; Open_wronly; Open_append ] 0o644 path, true
|
||||||
|
| `Output oc -> oc, false
|
||||||
|
in
|
||||||
|
let pid =
|
||||||
|
if !Mock_.enabled then
|
||||||
|
2
|
||||||
|
else
|
||||||
|
Unix.getpid ()
|
||||||
|
in
|
||||||
|
if not jsonl then output_char oc '[';
|
||||||
|
{ oc; jsonl; first = true; pid; must_close; buf = Buffer.create 2_048 }
|
||||||
|
|
||||||
|
let close (self : t) : unit =
|
||||||
|
if self.jsonl then
|
||||||
|
output_char self.oc '\n'
|
||||||
|
else
|
||||||
|
output_char self.oc ']';
|
||||||
|
flush self.oc;
|
||||||
|
if self.must_close then close_out self.oc
|
||||||
|
|
||||||
|
let with_ ~mode ~out f =
|
||||||
|
let writer = create ~mode ~out () in
|
||||||
|
Fun.protect ~finally:(fun () -> close writer) (fun () -> f writer)
|
||||||
|
|
||||||
|
let[@inline] flush (self : t) : unit = flush self.oc
|
||||||
|
|
||||||
|
(** Emit "," if we need, and get the buffer ready *)
|
||||||
|
let emit_sep_and_start_ (self : t) =
|
||||||
|
Buffer.reset self.buf;
|
||||||
|
if self.jsonl then
|
||||||
|
Buffer.add_char self.buf '\n'
|
||||||
|
else if self.first then
|
||||||
|
self.first <- false
|
||||||
|
else
|
||||||
|
Buffer.add_string self.buf ",\n"
|
||||||
|
|
||||||
|
let char = Buffer.add_char
|
||||||
|
let raw_string = Buffer.add_string
|
||||||
|
|
||||||
|
let str_val (buf : Buffer.t) (s : string) =
|
||||||
|
char buf '"';
|
||||||
|
let encode_char c =
|
||||||
|
match c with
|
||||||
|
| '"' -> raw_string buf {|\"|}
|
||||||
|
| '\\' -> raw_string buf {|\\|}
|
||||||
|
| '\n' -> raw_string buf {|\n|}
|
||||||
|
| '\b' -> raw_string buf {|\b|}
|
||||||
|
| '\r' -> raw_string buf {|\r|}
|
||||||
|
| '\t' -> raw_string buf {|\t|}
|
||||||
|
| _ when Char.code c <= 0x1f ->
|
||||||
|
raw_string buf {|\u00|};
|
||||||
|
Printf.bprintf buf "%02x" (Char.code c)
|
||||||
|
| c -> char buf c
|
||||||
|
in
|
||||||
|
String.iter encode_char s;
|
||||||
|
char buf '"'
|
||||||
|
|
||||||
|
let pp_user_data_ (out : Buffer.t) : Sub.user_data -> unit = function
|
||||||
|
| U_none -> raw_string out "null"
|
||||||
|
| U_int i -> Printf.bprintf out "%d" i
|
||||||
|
| U_bool b -> Printf.bprintf out "%b" b
|
||||||
|
| U_string s -> str_val out s
|
||||||
|
| U_float f -> Printf.bprintf out "%g" f
|
||||||
|
|
||||||
|
(* emit args, if not empty. [ppv] is used to print values. *)
|
||||||
|
let emit_args_o_ ppv (out : Buffer.t) args : unit =
|
||||||
|
if args <> [] then (
|
||||||
|
Printf.bprintf out {json|,"args": {|json};
|
||||||
|
List.iteri
|
||||||
|
(fun i (n, value) ->
|
||||||
|
if i > 0 then raw_string out ",";
|
||||||
|
Printf.bprintf out {json|"%s":%a|json} n ppv value)
|
||||||
|
args;
|
||||||
|
char out '}'
|
||||||
|
)
|
||||||
|
|
||||||
|
let emit_duration_event ~tid ~name ~start ~end_ ~args (self : t) : unit =
|
||||||
|
let dur = end_ -. start in
|
||||||
|
let ts = start in
|
||||||
|
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"cat":"","tid": %d,"dur": %.2f,"ts": %.2f,"name":%a,"ph":"X"%a}|json}
|
||||||
|
self.pid tid dur ts str_val name
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
args;
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
|
|
||||||
|
let emit_manual_begin ~tid ~name ~(id : trace_id) ~ts ~args
|
||||||
|
~(flavor : Sub.flavor option) (self : t) : unit =
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"cat":"trace","id":%Ld,"tid": %d,"ts": %.2f,"name":%a,"ph":"%c"%a}|json}
|
||||||
|
self.pid (int64_of_trace_id_ id) tid ts str_val name
|
||||||
|
(match flavor with
|
||||||
|
| None | Some Async -> 'b'
|
||||||
|
| Some Sync -> 'B')
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
args;
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
|
|
||||||
|
let emit_manual_end ~tid ~name ~(id : trace_id) ~ts
|
||||||
|
~(flavor : Sub.flavor option) ~args (self : t) : unit =
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"cat":"trace","id":%Ld,"tid": %d,"ts": %.2f,"name":%a,"ph":"%c"%a}|json}
|
||||||
|
self.pid (int64_of_trace_id_ id) tid ts str_val name
|
||||||
|
(match flavor with
|
||||||
|
| None | Some Async -> 'e'
|
||||||
|
| Some Sync -> 'E')
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
args;
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
|
|
||||||
|
let emit_instant_event ~tid ~name ~ts ~args (self : t) : unit =
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"cat":"","tid": %d,"ts": %.2f,"name":%a,"ph":"I"%a}|json}
|
||||||
|
self.pid tid ts str_val name
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
args;
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
|
|
||||||
|
let emit_name_thread ~tid ~name (self : t) : unit =
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"tid": %d,"name":"thread_name","ph":"M"%a}|json} self.pid
|
||||||
|
tid
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
[ "name", U_string name ];
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
|
|
||||||
|
let emit_name_process ~name (self : t) : unit =
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"name":"process_name","ph":"M"%a}|json} self.pid
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
[ "name", U_string name ];
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
|
|
||||||
|
let emit_counter ~name ~tid ~ts (self : t) f : unit =
|
||||||
|
emit_sep_and_start_ self;
|
||||||
|
Printf.bprintf self.buf
|
||||||
|
{json|{"pid":%d,"tid":%d,"ts":%.2f,"name":"c","ph":"C"%a}|json} self.pid tid
|
||||||
|
ts
|
||||||
|
(emit_args_o_ pp_user_data_)
|
||||||
|
[ name, U_float f ];
|
||||||
|
Buffer.output_buffer self.oc self.buf
|
||||||
80
src/tef/writer.mli
Normal file
80
src/tef/writer.mli
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
(** Writer: knows how to write entries to a file in TEF format *)
|
||||||
|
|
||||||
|
open Trace_core
|
||||||
|
module Sub = Trace_subscriber
|
||||||
|
|
||||||
|
type t
|
||||||
|
(** A writer to a [out_channel]. It writes JSON entries in an array and closes
|
||||||
|
the array at the end. *)
|
||||||
|
|
||||||
|
val create :
|
||||||
|
mode:[ `Jsonl | `Single ] ->
|
||||||
|
out:
|
||||||
|
[< `File of trace_id
|
||||||
|
| `File_append of trace_id
|
||||||
|
| `Output of out_channel
|
||||||
|
| `Stderr
|
||||||
|
| `Stdout
|
||||||
|
] ->
|
||||||
|
unit ->
|
||||||
|
t
|
||||||
|
|
||||||
|
val flush : t -> unit
|
||||||
|
val close : t -> unit
|
||||||
|
|
||||||
|
val with_ :
|
||||||
|
mode:[ `Jsonl | `Single ] ->
|
||||||
|
out:
|
||||||
|
[< `File of trace_id
|
||||||
|
| `File_append of trace_id
|
||||||
|
| `Output of out_channel
|
||||||
|
| `Stderr
|
||||||
|
| `Stdout
|
||||||
|
] ->
|
||||||
|
(t -> 'a) ->
|
||||||
|
'a
|
||||||
|
(** [with_ ~mode ~out f] creates a writer and calls [f] with it.
|
||||||
|
@param mode
|
||||||
|
choose between jsonl (easier to read and write) and single (single json
|
||||||
|
object, directly usable in perfetto) *)
|
||||||
|
|
||||||
|
val emit_duration_event :
|
||||||
|
tid:int ->
|
||||||
|
name:trace_id ->
|
||||||
|
start:float ->
|
||||||
|
end_:float ->
|
||||||
|
args:(trace_id * Sub.user_data) list ->
|
||||||
|
t ->
|
||||||
|
unit
|
||||||
|
|
||||||
|
val emit_manual_begin :
|
||||||
|
tid:int ->
|
||||||
|
name:trace_id ->
|
||||||
|
id:trace_id ->
|
||||||
|
ts:float ->
|
||||||
|
args:(trace_id * Sub.user_data) list ->
|
||||||
|
flavor:Sub.flavor option ->
|
||||||
|
t ->
|
||||||
|
unit
|
||||||
|
|
||||||
|
val emit_manual_end :
|
||||||
|
tid:int ->
|
||||||
|
name:trace_id ->
|
||||||
|
id:trace_id ->
|
||||||
|
ts:float ->
|
||||||
|
flavor:Sub.flavor option ->
|
||||||
|
args:(trace_id * Sub.user_data) list ->
|
||||||
|
t ->
|
||||||
|
unit
|
||||||
|
|
||||||
|
val emit_instant_event :
|
||||||
|
tid:int ->
|
||||||
|
name:trace_id ->
|
||||||
|
ts:float ->
|
||||||
|
args:(trace_id * Sub.user_data) list ->
|
||||||
|
t ->
|
||||||
|
unit
|
||||||
|
|
||||||
|
val emit_name_thread : tid:int -> name:trace_id -> t -> unit
|
||||||
|
val emit_name_process : name:trace_id -> t -> unit
|
||||||
|
val emit_counter : name:trace_id -> tid:int -> ts:float -> t -> float -> unit
|
||||||
Loading…
Add table
Reference in a new issue