mirror of
https://github.com/ocaml-tracing/ocaml-trace.git
synced 2026-03-10 04:35:44 -04:00
Compare commits
No commits in common. "main" and "v0.11" have entirely different histories.
45 changed files with 42 additions and 1068 deletions
28
.github/workflows/format.yml
vendored
28
.github/workflows/format.yml
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
name: format
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
format:
|
|
||||||
name: format
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
ocaml-compiler:
|
|
||||||
- '5.3'
|
|
||||||
runs-on: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@main
|
|
||||||
- name: Use OCaml ${{ matrix.ocaml-compiler }}
|
|
||||||
uses: ocaml/setup-ocaml@v3
|
|
||||||
with:
|
|
||||||
ocaml-compiler: ${{ matrix.ocaml-compiler }}
|
|
||||||
dune-cache: true
|
|
||||||
allow-prerelease-opam: true
|
|
||||||
|
|
||||||
- run: opam install ocamlformat.0.27.0
|
|
||||||
- run: opam exec -- make format-check
|
|
||||||
|
|
||||||
2
.github/workflows/gh-pages.yml
vendored
2
.github/workflows/gh-pages.yml
vendored
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
- run: opam pin odoc 3.1.0 -y -n
|
- run: opam pin odoc 3.1.0 -y -n
|
||||||
# crash with 2.4, see https://github.com/ocaml/odoc/issues/1066
|
# crash with 2.4, see https://github.com/ocaml/odoc/issues/1066
|
||||||
- name: Deps
|
- name: Deps
|
||||||
run: opam install odig thread-local-storage trace trace-tef trace-fuchsia ppx_trace
|
run: opam install odig trace trace-tef trace-fuchsia ppx_trace
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: opam exec -- odig odoc --cache-dir=_doc/ trace trace-tef trace-fuchsia ppx_trace
|
run: opam exec -- odig odoc --cache-dir=_doc/ trace trace-tef trace-fuchsia ppx_trace
|
||||||
|
|
|
||||||
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
|
|
@ -47,7 +47,7 @@ jobs:
|
||||||
- run: opam exec -- dune runtest -p trace-tef,trace-fuchsia
|
- run: opam exec -- dune runtest -p trace-tef,trace-fuchsia
|
||||||
|
|
||||||
# with depopts
|
# with depopts
|
||||||
- run: opam install hmap thread-local-storage
|
- run: opam install hmap
|
||||||
- run: opam exec -- dune build '@install' -p trace,trace-tef,trace-fuchsia
|
- run: opam exec -- dune build '@install' -p trace,trace-tef,trace-fuchsia
|
||||||
|
|
||||||
- run: opam install picos_aux
|
- run: opam install picos_aux
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,3 @@
|
||||||
# 0.12
|
|
||||||
|
|
||||||
- use `current_span` when entering spans or sending messages
|
|
||||||
- add `Trace.Ambient_span_provider.t` concept, to track the current span.
|
|
||||||
It is not part of the collector and is optional.
|
|
||||||
- add `trace.thread-local-storage` optional library that implements the `Ambient_span_provider.t`
|
|
||||||
- add a runtime events collector, + test, in `trace-runtime-events`
|
|
||||||
- add `{thread,process}_sort_index` extension + TEF support
|
|
||||||
|
|
||||||
# 0.11
|
# 0.11
|
||||||
|
|
||||||
- entire rework of the collector, now lighter, and using an open sum type
|
- entire rework of the collector, now lighter, and using an open sum type
|
||||||
|
|
|
||||||
6
Makefile
6
Makefile
|
|
@ -14,12 +14,6 @@ test-autopromote:
|
||||||
doc:
|
doc:
|
||||||
@dune build $(DUNE_OPTS) @doc
|
@dune build $(DUNE_OPTS) @doc
|
||||||
|
|
||||||
format:
|
|
||||||
@dune build @fmt --auto-promote
|
|
||||||
|
|
||||||
format-check:
|
|
||||||
@dune build @fmt --ignore-promoted-rules
|
|
||||||
|
|
||||||
WATCH?= @install @runtest
|
WATCH?= @install @runtest
|
||||||
watch:
|
watch:
|
||||||
dune build $(DUNE_OPTS) -w $(WATCH)
|
dune build $(DUNE_OPTS) -w $(WATCH)
|
||||||
|
|
|
||||||
19
dune-project
19
dune-project
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
(generate_opam_files true)
|
(generate_opam_files true)
|
||||||
|
|
||||||
(version 0.12)
|
(version 0.11)
|
||||||
|
|
||||||
(source
|
(source
|
||||||
(github ocaml-tracing/ocaml-trace))
|
(github ocaml-tracing/ocaml-trace))
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
dune)
|
dune)
|
||||||
(depopts
|
(depopts
|
||||||
unix
|
unix
|
||||||
(thread-local-storage (>= 0.2))
|
|
||||||
(mtime
|
(mtime
|
||||||
(>= 2.0)))
|
(>= 2.0)))
|
||||||
(tags
|
(tags
|
||||||
|
|
@ -92,20 +91,4 @@
|
||||||
(tags
|
(tags
|
||||||
(trace tracing fuchsia)))
|
(trace tracing fuchsia)))
|
||||||
|
|
||||||
(package
|
|
||||||
(name trace-runtime-events)
|
|
||||||
(synopsis
|
|
||||||
"A simple collector relying on runtime-events for OCaml 5. Some assembly required.")
|
|
||||||
(depends
|
|
||||||
(ocaml
|
|
||||||
(>= 5.1))
|
|
||||||
(trace
|
|
||||||
(= :version))
|
|
||||||
(ppx_trace (and (= :version) :with-test))
|
|
||||||
base-bigarray
|
|
||||||
base-unix
|
|
||||||
dune)
|
|
||||||
(tags
|
|
||||||
(trace tracing trace runtime-events)))
|
|
||||||
|
|
||||||
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project
|
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# This file is generated by dune, edit dune-project instead
|
# This file is generated by dune, edit dune-project instead
|
||||||
opam-version: "2.0"
|
opam-version: "2.0"
|
||||||
version: "0.12"
|
version: "0.11"
|
||||||
synopsis: "A ppx-based preprocessor for trace"
|
synopsis: "A ppx-based preprocessor for trace"
|
||||||
maintainer: ["Simon Cruanes"]
|
maintainer: ["Simon Cruanes"]
|
||||||
authors: ["Simon Cruanes"]
|
authors: ["Simon Cruanes"]
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
(** Access/set the current span from some ambient context.
|
|
||||||
@since 0.12 *)
|
|
||||||
|
|
||||||
open Types
|
|
||||||
|
|
||||||
module Callbacks = struct
|
|
||||||
type 'st t = {
|
|
||||||
with_current_span_set_to: 'a. 'st -> span -> (span -> 'a) -> 'a;
|
|
||||||
(** [with_current_span_set_to span f] sets the span as current span,
|
|
||||||
enters [f span], and restores the previous current span if any *)
|
|
||||||
get_current_span: 'st -> span option;
|
|
||||||
(** Access the current span from some ambient scope. This is only
|
|
||||||
supported for collectors that provide a [current_span_wrap] field.
|
|
||||||
*)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| ASP_none
|
|
||||||
| ASP_some : 'st * 'st Callbacks.t -> t
|
|
||||||
|
|
@ -82,7 +82,8 @@ end
|
||||||
This is only relevant to implementors of tracing backends; to instrument
|
This is only relevant to implementors of tracing backends; to instrument
|
||||||
your code you only need to look at the {!Trace} module.
|
your code you only need to look at the {!Trace} module.
|
||||||
|
|
||||||
The definition changed since 0.11 to a record of callbacks + a state *)
|
The definition changed since NEXT_RELEASE to a record of callbacks + a state
|
||||||
|
*)
|
||||||
type t =
|
type t =
|
||||||
| C_none (** No collector. *)
|
| C_none (** No collector. *)
|
||||||
| C_some : 'st * 'st Callbacks.t -> t
|
| C_some : 'st * 'st Callbacks.t -> t
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
(** A few core extensions.
|
(** A few core extensions.
|
||||||
|
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
open Types
|
open Types
|
||||||
|
|
||||||
|
|
@ -8,10 +8,6 @@ open Types
|
||||||
type extension_event +=
|
type extension_event +=
|
||||||
| Extension_set_thread_name of string
|
| Extension_set_thread_name of string
|
||||||
| Extension_set_process_name of string
|
| Extension_set_process_name of string
|
||||||
| Extension_set_thread_sort_index of int
|
|
||||||
(** https://github.com/google/perfetto/pull/3273/changes#diff-ecec88c33adb7591ee6aa88e29b62ad52ef443611cba5e0f0ecac9b5725afdba
|
|
||||||
*)
|
|
||||||
| Extension_set_process_sort_index of int
|
|
||||||
|
|
||||||
(** Specialized parameters *)
|
(** Specialized parameters *)
|
||||||
type extension_parameter +=
|
type extension_parameter +=
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ module A = Atomic_
|
||||||
module Collector = Collector
|
module Collector = Collector
|
||||||
module Level = Level
|
module Level = Level
|
||||||
module Core_ext = Core_ext
|
module Core_ext = Core_ext
|
||||||
module Ambient_span_provider = Ambient_span_provider
|
|
||||||
|
|
||||||
type collector = Collector.t
|
type collector = Collector.t
|
||||||
|
|
||||||
|
|
@ -16,17 +15,8 @@ let collector : collector A.t = A.make Collector.C_none
|
||||||
let default_level_ = A.make Level.Trace
|
let default_level_ = A.make Level.Trace
|
||||||
let current_level_ = A.make Level.Trace
|
let current_level_ = A.make Level.Trace
|
||||||
|
|
||||||
(** Global provider of span context *)
|
|
||||||
let ambient_span_provider : Ambient_span_provider.t A.t =
|
|
||||||
A.make Ambient_span_provider.ASP_none
|
|
||||||
|
|
||||||
(* ## implementation ## *)
|
(* ## implementation ## *)
|
||||||
|
|
||||||
let[@inline] option_or_ a f =
|
|
||||||
match a with
|
|
||||||
| Some _ -> a
|
|
||||||
| None -> f ()
|
|
||||||
|
|
||||||
let data_empty_build_ () = []
|
let data_empty_build_ () = []
|
||||||
let[@inline] enabled () = Collector.is_some (A.get collector)
|
let[@inline] enabled () = Collector.is_some (A.get collector)
|
||||||
let[@inline] get_default_level () = A.get default_level_
|
let[@inline] get_default_level () = A.get default_level_
|
||||||
|
|
@ -37,21 +27,8 @@ let[@inline] get_current_level () = A.get current_level_
|
||||||
let[@inline] check_level_ ~level st (cbs : _ Collector.Callbacks.t) : bool =
|
let[@inline] check_level_ ~level st (cbs : _ Collector.Callbacks.t) : bool =
|
||||||
Level.leq level (A.get current_level_) && cbs.enabled st level
|
Level.leq level (A.get current_level_) && cbs.enabled st level
|
||||||
|
|
||||||
let[@inline] current_span () =
|
|
||||||
match A.get ambient_span_provider with
|
|
||||||
| ASP_none -> None
|
|
||||||
| ASP_some (st, cbs) -> cbs.get_current_span st
|
|
||||||
|
|
||||||
let[@inline] with_current_span_set_to sp f =
|
|
||||||
match A.get ambient_span_provider with
|
|
||||||
| ASP_none -> f sp
|
|
||||||
| ASP_some (st, cbs) -> cbs.with_current_span_set_to st sp f
|
|
||||||
|
|
||||||
let parent_of_span_opt_opt = function
|
let parent_of_span_opt_opt = function
|
||||||
| None ->
|
| None -> P_unknown
|
||||||
(match current_span () with
|
|
||||||
| None -> P_unknown
|
|
||||||
| Some p -> P_some p)
|
|
||||||
| Some None -> P_none
|
| Some None -> P_none
|
||||||
| Some (Some p) -> P_some p
|
| Some (Some p) -> P_some p
|
||||||
|
|
||||||
|
|
@ -69,10 +46,7 @@ let with_span_collector_ st (cbs : _ Collector.Callbacks.t) ?__FUNCTION__
|
||||||
enter_span_st st cbs ?__FUNCTION__ ~__FILE__ ~__LINE__ ~level ?parent
|
enter_span_st st cbs ?__FUNCTION__ ~__FILE__ ~__LINE__ ~level ?parent
|
||||||
?params ?data name
|
?params ?data name
|
||||||
in
|
in
|
||||||
match
|
match f sp with
|
||||||
(* set [sp] as current span before calling [f sp] *)
|
|
||||||
with_current_span_set_to sp f
|
|
||||||
with
|
|
||||||
| res ->
|
| res ->
|
||||||
cbs.exit_span st sp;
|
cbs.exit_span st sp;
|
||||||
res
|
res
|
||||||
|
|
@ -119,7 +93,6 @@ let[@inline] add_data_to_span sp data : unit =
|
||||||
let message_collector_ st (cbs : _ Collector.Callbacks.t) ~level ?span
|
let message_collector_ st (cbs : _ Collector.Callbacks.t) ~level ?span
|
||||||
?(params = []) ?(data = data_empty_build_) msg : unit =
|
?(params = []) ?(data = data_empty_build_) msg : unit =
|
||||||
let data = data () in
|
let data = data () in
|
||||||
let span = option_or_ span current_span in
|
|
||||||
cbs.message st ~level ~span ~params ~data msg
|
cbs.message st ~level ~span ~params ~data msg
|
||||||
|
|
||||||
let[@inline] message ?(level = A.get default_level_) ?span ?params ?data msg :
|
let[@inline] message ?(level = A.get default_level_) ?span ?params ?data msg :
|
||||||
|
|
@ -176,8 +149,6 @@ let with_setup_collector c f =
|
||||||
setup_collector c;
|
setup_collector c;
|
||||||
Fun.protect ~finally:shutdown f
|
Fun.protect ~finally:shutdown f
|
||||||
|
|
||||||
let set_ambient_context_provider p = A.set ambient_span_provider p
|
|
||||||
|
|
||||||
type extension_event = Types.extension_event = ..
|
type extension_event = Types.extension_event = ..
|
||||||
|
|
||||||
let[@inline] extension_event ?(level = A.get default_level_) ev : unit =
|
let[@inline] extension_event ?(level = A.get default_level_) ev : unit =
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
include module type of Types
|
include module type of Types
|
||||||
module Collector = Collector
|
module Collector = Collector
|
||||||
module Level = Level
|
module Level = Level
|
||||||
module Ambient_span_provider = Ambient_span_provider
|
|
||||||
|
|
||||||
(**/**)
|
(**/**)
|
||||||
|
|
||||||
|
|
@ -55,10 +54,10 @@ val with_span :
|
||||||
@param level
|
@param level
|
||||||
optional level for this span. since 0.7. Default is set via
|
optional level for this span. since 0.7. Default is set via
|
||||||
{!set_default_level}.
|
{!set_default_level}.
|
||||||
@param parent the span's parent, if any. since 0.11.
|
@param parent the span's parent, if any. since NEXT_RELEASE.
|
||||||
@param params
|
@param params
|
||||||
extension parameters, used to communicate additional information to the
|
extension parameters, used to communicate additional information to the
|
||||||
collector. It might be collector-specific. since 0.11.
|
collector. It might be collector-specific. since NEXT_RELEASE.
|
||||||
|
|
||||||
Depending on the collector, this might clash with some forms of cooperative
|
Depending on the collector, this might clash with some forms of cooperative
|
||||||
concurrency in which [with_span (fun span -> …)] might contain a yield
|
concurrency in which [with_span (fun span -> …)] might contain a yield
|
||||||
|
|
@ -84,7 +83,7 @@ val enter_span :
|
||||||
@param level
|
@param level
|
||||||
optional level for this span. since 0.7. Default is set via
|
optional level for this span. since 0.7. Default is set via
|
||||||
{!set_default_level}.
|
{!set_default_level}.
|
||||||
@param parent the span's parent, if any. since 0.11.
|
@param parent the span's parent, if any. since NEXT_RELEASE.
|
||||||
@param params see {!with_span}. *)
|
@param params see {!with_span}. *)
|
||||||
|
|
||||||
val exit_span : span -> unit
|
val exit_span : span -> unit
|
||||||
|
|
@ -115,7 +114,7 @@ val message :
|
||||||
the surrounding span, if any. This might be ignored by the collector.
|
the surrounding span, if any. This might be ignored by the collector.
|
||||||
@param params
|
@param params
|
||||||
extension parameters, used to communicate additional information to the
|
extension parameters, used to communicate additional information to the
|
||||||
collector. It might be collector-specific. since 0.11. *)
|
collector. It might be collector-specific. since NEXT_RELEASE. *)
|
||||||
|
|
||||||
val messagef :
|
val messagef :
|
||||||
?level:Level.t ->
|
?level:Level.t ->
|
||||||
|
|
@ -134,13 +133,13 @@ val set_thread_name : string -> unit
|
||||||
(** Give a name to the current thread. This might be used by the collector to
|
(** Give a name to the current thread. This might be used by the collector to
|
||||||
display traces in a more informative way.
|
display traces in a more informative way.
|
||||||
|
|
||||||
Uses {!Core_ext.Extension_set_thread_name} since 0.11 *)
|
Uses {!Core_ext.Extension_set_thread_name} since NEXT_RELEASE *)
|
||||||
|
|
||||||
val set_process_name : string -> unit
|
val set_process_name : string -> unit
|
||||||
(** Give a name to the current process. This might be used by the collector to
|
(** Give a name to the current process. This might be used by the collector to
|
||||||
display traces in a more informative way.
|
display traces in a more informative way.
|
||||||
|
|
||||||
Uses {!Core_ext.Extension_set_process_name} since 0.11 *)
|
Uses {!Core_ext.Extension_set_process_name} since NEXT_RELEASE *)
|
||||||
|
|
||||||
val metric :
|
val metric :
|
||||||
?level:Level.t ->
|
?level:Level.t ->
|
||||||
|
|
@ -151,7 +150,7 @@ val metric :
|
||||||
unit
|
unit
|
||||||
(** Emit a metric. Metrics are an extensible type, each collector might support
|
(** Emit a metric. Metrics are an extensible type, each collector might support
|
||||||
a different subset.
|
a different subset.
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val counter_int :
|
val counter_int :
|
||||||
?level:Level.t ->
|
?level:Level.t ->
|
||||||
|
|
@ -181,22 +180,6 @@ val counter_float :
|
||||||
{!set_default_level}.
|
{!set_default_level}.
|
||||||
@param data metadata for this metric (since 0.4) *)
|
@param data metadata for this metric (since 0.4) *)
|
||||||
|
|
||||||
val current_span : unit -> span option
|
|
||||||
(** Access the current span from some ambient scope, {b if supported}. This is
|
|
||||||
only supported if a {!Ambient_span_provider} has been set up.
|
|
||||||
@since 0.12 *)
|
|
||||||
|
|
||||||
val with_current_span_set_to : span -> (span -> 'a) -> 'a
|
|
||||||
(** [with_current_span_set_to span f] sets the span as current span, enters
|
|
||||||
[f span], and restores the previous current span (if any).
|
|
||||||
|
|
||||||
This is only supported if a {!Ambient_span_provider} has been set up,
|
|
||||||
otherwise it is a no-op.
|
|
||||||
|
|
||||||
Automatically called by {!with_span}.
|
|
||||||
|
|
||||||
@since 0.12 *)
|
|
||||||
|
|
||||||
(** {2 Collector} *)
|
(** {2 Collector} *)
|
||||||
|
|
||||||
type collector = Collector.t
|
type collector = Collector.t
|
||||||
|
|
@ -223,14 +206,7 @@ val shutdown : unit -> unit
|
||||||
val with_setup_collector : Collector.t -> (unit -> 'a) -> 'a
|
val with_setup_collector : Collector.t -> (unit -> 'a) -> 'a
|
||||||
(** [with_setup_collector c f] installs [c], calls [f()], and shutdowns [c] once
|
(** [with_setup_collector c f] installs [c], calls [f()], and shutdowns [c] once
|
||||||
[f()] is done.
|
[f()] is done.
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
(** {2 ambient span provider} *)
|
|
||||||
|
|
||||||
val set_ambient_context_provider : Ambient_span_provider.t -> unit
|
|
||||||
(** Install a provider for {!current_span} and {!with_current_span_set_to}. The
|
|
||||||
default provider does nothing (ie [current_span ()] is always [None]).
|
|
||||||
@since 0.12 *)
|
|
||||||
|
|
||||||
(** {2 Extensions} *)
|
(** {2 Extensions} *)
|
||||||
|
|
||||||
|
|
@ -242,7 +218,7 @@ val extension_event : ?level:Level.t -> extension_event -> unit
|
||||||
(** Trigger an extension event, whose meaning depends on the library that
|
(** Trigger an extension event, whose meaning depends on the library that
|
||||||
defines it. Some collectors will simply ignore it. This does nothing if no
|
defines it. Some collectors will simply ignore it. This does nothing if no
|
||||||
collector is setup.
|
collector is setup.
|
||||||
@param level filtering level, since 0.11
|
@param level filtering level, since NEXT_RELEASE
|
||||||
@since 0.8 *)
|
@since 0.8 *)
|
||||||
|
|
||||||
(** {2 Core extensions} *)
|
(** {2 Core extensions} *)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
(** Main type definitions *)
|
(** Main type definitions *)
|
||||||
|
|
||||||
type span = ..
|
type span = ..
|
||||||
(** A span. Its representation is defined by the current collector.
|
(** A span. Its representation is defined by the current collector. *)
|
||||||
|
|
||||||
This representation changed in 0.11 (from [int64] to an open sum type) *)
|
|
||||||
|
|
||||||
(** Information about a span's parent span, if any.
|
(** Information about a span's parent span, if any.
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
type parent =
|
type parent =
|
||||||
| P_unknown (** Parent is not specified at this point *)
|
| P_unknown (** Parent is not specified at this point *)
|
||||||
| P_none (** We know the current span has no parent *)
|
| P_none (** We know the current span has no parent *)
|
||||||
|
|
@ -34,8 +32,8 @@ type extension_event = ..
|
||||||
type extension_parameter = ..
|
type extension_parameter = ..
|
||||||
(** An extension parameter, used to carry information for spans/messages/metrics
|
(** An extension parameter, used to carry information for spans/messages/metrics
|
||||||
that can be backend-specific or just not envisioned by [trace].
|
that can be backend-specific or just not envisioned by [trace].
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
type metric = ..
|
type metric = ..
|
||||||
(** A metric, can be of many types. See {!Core_ext} for some builtin metrics.
|
(** A metric, can be of many types. See {!Core_ext} for some builtin metrics.
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
(library
|
|
||||||
(name trace_runtime_events)
|
|
||||||
(public_name trace-runtime-events)
|
|
||||||
(synopsis "Simple collector that emits events via Runtime_events")
|
|
||||||
(libraries
|
|
||||||
trace.core
|
|
||||||
trace.util
|
|
||||||
(re_export runtime_events)))
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
(** Simple backend that emits trace events via Runtime_events.
|
|
||||||
|
|
||||||
This backend allows trace spans, messages, and metrics to be collected by
|
|
||||||
external tools using the OCaml Runtime_events system. *)
|
|
||||||
|
|
||||||
open Trace_core
|
|
||||||
|
|
||||||
(* Register custom event types for strings *)
|
|
||||||
module String_type = struct
|
|
||||||
let max_len = 1024
|
|
||||||
|
|
||||||
let encode buf s =
|
|
||||||
let len = min (String.length s) (max_len - 1) in
|
|
||||||
Bytes.blit_string s 0 buf 0 len;
|
|
||||||
len
|
|
||||||
|
|
||||||
let decode buf len = Bytes.sub_string buf 0 len
|
|
||||||
let ty = Runtime_events.Type.register ~encode ~decode
|
|
||||||
end
|
|
||||||
|
|
||||||
module String_int = struct
|
|
||||||
let max_len = 1024
|
|
||||||
|
|
||||||
let encode buf (s, i) =
|
|
||||||
let len = min (String.length s) (max_len - 9) in
|
|
||||||
Bytes.set_int64_le buf 0 (Int64.of_int i);
|
|
||||||
Bytes.blit_string s 0 buf 8 len;
|
|
||||||
len + 8
|
|
||||||
|
|
||||||
let decode buf len =
|
|
||||||
let i = Bytes.get_int64_le buf 0 in
|
|
||||||
Bytes.sub_string buf 8 (len - 8), Int64.to_int i
|
|
||||||
|
|
||||||
let ty = Runtime_events.Type.register ~encode ~decode
|
|
||||||
end
|
|
||||||
|
|
||||||
module String_float = struct
|
|
||||||
let max_len = 1024
|
|
||||||
|
|
||||||
let encode buf (s, f) =
|
|
||||||
let len = min (String.length s) (max_len - 9) in
|
|
||||||
Bytes.set_int64_le buf 0 (Int64.bits_of_float f);
|
|
||||||
Bytes.blit_string s 0 buf 8 len;
|
|
||||||
len + 8
|
|
||||||
|
|
||||||
let decode buf len =
|
|
||||||
let i = Bytes.get_int64_le buf 0 in
|
|
||||||
Bytes.sub_string buf 8 (len - 8), Int64.float_of_bits i
|
|
||||||
|
|
||||||
let ty = Runtime_events.Type.register ~encode ~decode
|
|
||||||
end
|
|
||||||
|
|
||||||
module Events = struct
|
|
||||||
(* Define event tags *)
|
|
||||||
type Runtime_events.User.tag +=
|
|
||||||
| Tag_span_enter
|
|
||||||
| Tag_span_exit
|
|
||||||
| Tag_message
|
|
||||||
| Tag_metric_int
|
|
||||||
| Tag_metric_float
|
|
||||||
|
|
||||||
(* Register user events *)
|
|
||||||
let span_enter_event =
|
|
||||||
Runtime_events.User.register "trace.span.enter" Tag_span_enter
|
|
||||||
String_type.ty
|
|
||||||
|
|
||||||
let span_exit_event =
|
|
||||||
Runtime_events.User.register "trace.span.exit" Tag_span_exit String_type.ty
|
|
||||||
|
|
||||||
let message_event =
|
|
||||||
Runtime_events.User.register "trace.message" Tag_message String_type.ty
|
|
||||||
|
|
||||||
let metric_int_event =
|
|
||||||
Runtime_events.User.register "trace.metric.int" Tag_metric_int String_int.ty
|
|
||||||
|
|
||||||
let metric_float_event =
|
|
||||||
Runtime_events.User.register "trace.metric.float" Tag_metric_float
|
|
||||||
String_float.ty
|
|
||||||
end
|
|
||||||
|
|
||||||
(* Span representation *)
|
|
||||||
type span_info = { name: string }
|
|
||||||
type Trace_core.span += Span_runtime_events of span_info
|
|
||||||
|
|
||||||
(* Collector state *)
|
|
||||||
type st = {
|
|
||||||
active: bool Trace_core.Internal_.Atomic_.t;
|
|
||||||
start_events: bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
let create ?(start_events = true) () : st =
|
|
||||||
{ active = Trace_core.Internal_.Atomic_.make true; start_events }
|
|
||||||
|
|
||||||
(* Collector callbacks *)
|
|
||||||
let init (self : st) = if self.start_events then Runtime_events.start ()
|
|
||||||
|
|
||||||
let shutdown (self : st) =
|
|
||||||
Trace_core.Internal_.Atomic_.set self.active false;
|
|
||||||
Runtime_events.pause ()
|
|
||||||
|
|
||||||
let enabled _ _ = true
|
|
||||||
|
|
||||||
let enter_span (_self : st) ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_ ~level:_
|
|
||||||
~params:_ ~data:_ ~parent:_ name : span =
|
|
||||||
Runtime_events.User.write Events.span_enter_event name;
|
|
||||||
Span_runtime_events { name }
|
|
||||||
|
|
||||||
let exit_span (_self : st) sp =
|
|
||||||
match sp with
|
|
||||||
| Span_runtime_events info ->
|
|
||||||
Runtime_events.User.write Events.span_exit_event info.name
|
|
||||||
| _ -> ()
|
|
||||||
|
|
||||||
let add_data_to_span _st _sp _data =
|
|
||||||
(* Runtime_events doesn't support adding data to spans after creation,
|
|
||||||
so we just ignore this *)
|
|
||||||
()
|
|
||||||
|
|
||||||
let message (_self : st) ~level:_ ~params:_ ~data:_ ~span:_ msg : unit =
|
|
||||||
Runtime_events.User.write Events.message_event msg
|
|
||||||
|
|
||||||
let metric (_self : st) ~level:_ ~params:_ ~data:_ name m : unit =
|
|
||||||
match m with
|
|
||||||
| Core_ext.Metric_int n ->
|
|
||||||
Runtime_events.User.write Events.metric_int_event (name, n)
|
|
||||||
| Core_ext.Metric_float f ->
|
|
||||||
Runtime_events.User.write Events.metric_float_event (name, f)
|
|
||||||
| _ -> ()
|
|
||||||
|
|
||||||
let extension _self ~level:_ _ev =
|
|
||||||
(* Extension events like set_thread_name, set_process_name could be
|
|
||||||
emitted as custom events if needed *)
|
|
||||||
()
|
|
||||||
|
|
||||||
(* Create collector *)
|
|
||||||
let callbacks : st Collector.Callbacks.t =
|
|
||||||
Collector.Callbacks.make ~init ~shutdown ~enabled ~enter_span ~exit_span
|
|
||||||
~add_data_to_span ~message ~metric ~extension ()
|
|
||||||
|
|
||||||
let collector ?(start_events = true) () : Collector.t =
|
|
||||||
let st = create ~start_events () in
|
|
||||||
Collector.C_some (st, callbacks)
|
|
||||||
|
|
||||||
(* Setup function *)
|
|
||||||
let setup ?(start_events = true) () =
|
|
||||||
Trace_core.setup_collector (collector ~start_events ())
|
|
||||||
|
|
||||||
(* Convenience wrapper *)
|
|
||||||
let with_setup ?start_events f =
|
|
||||||
setup ?start_events ();
|
|
||||||
Fun.protect ~finally:Trace_core.shutdown f
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
(** Simple collector that emits trace events via Runtime_events.
|
|
||||||
|
|
||||||
@since 0.12 *)
|
|
||||||
|
|
||||||
(** {2 Event types for decoding} *)
|
|
||||||
|
|
||||||
module String_type : sig
|
|
||||||
val ty : string Runtime_events.Type.t
|
|
||||||
end
|
|
||||||
|
|
||||||
module String_int : sig
|
|
||||||
val ty : (string * int) Runtime_events.Type.t
|
|
||||||
end
|
|
||||||
|
|
||||||
module String_float : sig
|
|
||||||
val ty : (string * float) Runtime_events.Type.t
|
|
||||||
end
|
|
||||||
|
|
||||||
(** Custom events *)
|
|
||||||
module Events : sig
|
|
||||||
type Runtime_events.User.tag +=
|
|
||||||
| Tag_span_enter
|
|
||||||
| Tag_span_exit
|
|
||||||
| Tag_message
|
|
||||||
| Tag_metric_int
|
|
||||||
| Tag_metric_float
|
|
||||||
|
|
||||||
val span_enter_event : string Runtime_events.User.t
|
|
||||||
val span_exit_event : string Runtime_events.User.t
|
|
||||||
val message_event : string Runtime_events.User.t
|
|
||||||
val metric_int_event : (string * int) Runtime_events.User.t
|
|
||||||
val metric_float_event : (string * float) Runtime_events.User.t
|
|
||||||
end
|
|
||||||
|
|
||||||
(** {2 Collector} *)
|
|
||||||
|
|
||||||
val collector : ?start_events:bool -> unit -> Trace_core.Collector.t
|
|
||||||
(** [collector ~start_events ()] creates a new collector that emits events via
|
|
||||||
Runtime_events.
|
|
||||||
|
|
||||||
@param start_events
|
|
||||||
if [true] (default), automatically call [Runtime_events.start()] when the
|
|
||||||
collector is initialized. *)
|
|
||||||
|
|
||||||
val setup : ?start_events:bool -> unit -> unit
|
|
||||||
(** [setup ~start_events ()] sets up the Runtime_events collector as the global
|
|
||||||
collector.
|
|
||||||
|
|
||||||
See {!collector} *)
|
|
||||||
|
|
||||||
val with_setup : ?start_events:bool -> (unit -> 'a) -> 'a
|
|
||||||
(** [with_setup ~start_events f] runs [f ()] with the Runtime_events collector
|
|
||||||
enabled, and shuts it down when done.
|
|
||||||
|
|
||||||
See {!collector} *)
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
(library
|
(library
|
||||||
(name trace_simple)
|
(name trace_simple)
|
||||||
(public_name trace.simple)
|
(public_name trace.simple)
|
||||||
(synopsis "simple type for spans")
|
(synopsis "simple type for spans")
|
||||||
(libraries trace.core trace.util))
|
(libraries trace.core trace.util))
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
This is a concrete representation of spans that is convenient to manipulate.
|
This is a concrete representation of spans that is convenient to manipulate.
|
||||||
|
|
||||||
@since 0.11 *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
open Trace_core
|
open Trace_core
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,27 +142,12 @@ open struct
|
||||||
Writer.emit_name_process ~pid:self.pid ~name buf;
|
Writer.emit_name_process ~pid:self.pid ~name buf;
|
||||||
self.exporter.on_json buf
|
self.exporter.on_json buf
|
||||||
|
|
||||||
let on_thread_sort_index_ (self : st) ~tid i : unit =
|
|
||||||
let@ buf = Trace_util.Rpool.with_ self.buf_pool in
|
|
||||||
Writer.emit_thread_sort_index ~pid:self.pid ~tid i buf;
|
|
||||||
self.exporter.on_json buf
|
|
||||||
|
|
||||||
let on_process_sort_index_ (self : st) i : unit =
|
|
||||||
let@ buf = Trace_util.Rpool.with_ self.buf_pool in
|
|
||||||
Writer.emit_process_sort_index ~pid:self.pid i buf;
|
|
||||||
self.exporter.on_json buf
|
|
||||||
|
|
||||||
let extension (self : st) ~level:_ ev =
|
let extension (self : st) ~level:_ ev =
|
||||||
match ev with
|
match ev with
|
||||||
| Core_ext.Extension_set_thread_name name ->
|
| Core_ext.Extension_set_thread_name name ->
|
||||||
let tid = Trace_util.Mock_.get_tid () in
|
let tid = Trace_util.Mock_.get_tid () in
|
||||||
on_name_thread_ self ~tid name
|
on_name_thread_ self ~tid name
|
||||||
| Core_ext.Extension_set_process_name name -> on_name_process_ self name
|
| Core_ext.Extension_set_process_name name -> on_name_process_ self name
|
||||||
| Core_ext.Extension_set_process_sort_index idx ->
|
|
||||||
on_process_sort_index_ self idx
|
|
||||||
| Core_ext.Extension_set_thread_sort_index idx ->
|
|
||||||
let tid = Trace_util.Mock_.get_tid () in
|
|
||||||
on_thread_sort_index_ self ~tid idx
|
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,19 +75,6 @@ let emit_name_thread ~pid ~tid ~name buf : unit =
|
||||||
(emit_args_o_ pp_user_data_)
|
(emit_args_o_ pp_user_data_)
|
||||||
[ "name", `String name ]
|
[ "name", `String name ]
|
||||||
|
|
||||||
let emit_process_sort_index ~pid i buf : unit =
|
|
||||||
Printf.bprintf buf
|
|
||||||
{json|{"pid":%d,"name":"process_sort_index","ph":"M"%a}|json} pid
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
[ "sort_index", `Int i ]
|
|
||||||
|
|
||||||
let emit_thread_sort_index ~pid ~tid i buf : unit =
|
|
||||||
Printf.bprintf buf
|
|
||||||
{json|{"pid":%d,"tid": %d,"name":"thread_sort_index","ph":"M"%a}|json} pid
|
|
||||||
tid
|
|
||||||
(emit_args_o_ pp_user_data_)
|
|
||||||
[ "sort_index", `Int i ]
|
|
||||||
|
|
||||||
let emit_name_process ~pid ~name buf : unit =
|
let emit_name_process ~pid ~name buf : unit =
|
||||||
Printf.bprintf buf {json|{"pid":%d,"name":"process_name","ph":"M"%a}|json} pid
|
Printf.bprintf buf {json|{"pid":%d,"name":"process_name","ph":"M"%a}|json} pid
|
||||||
(emit_args_o_ pp_user_data_)
|
(emit_args_o_ pp_user_data_)
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,6 @@ val emit_instant_event :
|
||||||
|
|
||||||
val emit_name_thread : pid:int -> tid:int -> name:string -> Buffer.t -> unit
|
val emit_name_thread : pid:int -> tid:int -> name:string -> Buffer.t -> unit
|
||||||
val emit_name_process : pid:int -> name:string -> Buffer.t -> unit
|
val emit_name_process : pid:int -> name:string -> Buffer.t -> unit
|
||||||
val emit_process_sort_index : pid:int -> int -> Buffer.t -> unit
|
|
||||||
val emit_thread_sort_index : pid:int -> tid:int -> int -> Buffer.t -> unit
|
|
||||||
|
|
||||||
val emit_counter :
|
val emit_counter :
|
||||||
pid:int -> tid:int -> name:string -> ts:float -> Buffer.t -> float -> unit
|
pid:int -> tid:int -> name:string -> ts:float -> Buffer.t -> float -> unit
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
(library
|
|
||||||
(name trace_thread_local_storage)
|
|
||||||
(public_name trace.thread-local-storage)
|
|
||||||
(synopsis "Use thread-local-storage for ambient spans")
|
|
||||||
(optional) ; thread-local-storage
|
|
||||||
(libraries trace.core thread-local-storage))
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
open Trace_core
|
|
||||||
|
|
||||||
let k_span : span Thread_local_storage.t = Thread_local_storage.create ()
|
|
||||||
|
|
||||||
open struct
|
|
||||||
let get_current_span () = Thread_local_storage.get_opt k_span
|
|
||||||
|
|
||||||
let with_current_span_set_to () span f =
|
|
||||||
let prev_span =
|
|
||||||
try Thread_local_storage.get_exn k_span
|
|
||||||
with Thread_local_storage.Not_set -> Collector.dummy_span
|
|
||||||
in
|
|
||||||
Thread_local_storage.set k_span span;
|
|
||||||
|
|
||||||
match f span with
|
|
||||||
| res ->
|
|
||||||
Thread_local_storage.set k_span prev_span;
|
|
||||||
res
|
|
||||||
| exception exn ->
|
|
||||||
let bt = Printexc.get_raw_backtrace () in
|
|
||||||
Thread_local_storage.set k_span prev_span;
|
|
||||||
Printexc.raise_with_backtrace exn bt
|
|
||||||
|
|
||||||
let callbacks : unit Ambient_span_provider.Callbacks.t =
|
|
||||||
{ get_current_span; with_current_span_set_to }
|
|
||||||
end
|
|
||||||
|
|
||||||
let provider : Ambient_span_provider.t = ASP_some ((), callbacks)
|
|
||||||
let setup () = Trace_core.set_ambient_context_provider provider
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
(** use [thread-local-storage] to store ambient spans.
|
|
||||||
|
|
||||||
This doesn't work with cooperative concurrency (Eio, Lwt, etc) but is fine
|
|
||||||
in a threaded context.
|
|
||||||
|
|
||||||
@since 0.12 *)
|
|
||||||
|
|
||||||
open Trace_core
|
|
||||||
|
|
||||||
val k_span : span Thread_local_storage.t
|
|
||||||
(** Key to access the current span *)
|
|
||||||
|
|
||||||
val provider : Ambient_span_provider.t
|
|
||||||
(** Provider that uses [Thread_local_storage] to store the current ambient span.
|
|
||||||
This works well when concurrency is based on thread, or if there is no
|
|
||||||
concurrency. *)
|
|
||||||
|
|
||||||
val setup : unit -> unit
|
|
||||||
(** Install the provider *)
|
|
||||||
|
|
@ -17,10 +17,10 @@
|
||||||
(unix -> time_util.unix.ml)
|
(unix -> time_util.unix.ml)
|
||||||
(-> time_util.dummy.ml))
|
(-> time_util.dummy.ml))
|
||||||
(select
|
(select
|
||||||
unix_util.ml
|
unix_util.ml
|
||||||
from
|
from
|
||||||
(unix -> unix_util.real.ml)
|
(unix -> unix_util.real.ml)
|
||||||
(-> unix_util.dummy.ml))
|
(-> unix_util.dummy.ml))
|
||||||
(select
|
(select
|
||||||
domain_util.ml
|
domain_util.ml
|
||||||
from
|
from
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
; Marker library: only present on OCaml 5+, used as a proxy for Domain availability.
|
|
||||||
|
|
||||||
(library
|
|
||||||
(name ocaml5)
|
|
||||||
(modules ocaml5)
|
|
||||||
(enabled_if
|
|
||||||
(>= %{ocaml_version} 5)))
|
|
||||||
|
|
||||||
(executable
|
|
||||||
(name t_domains)
|
|
||||||
(modules t_domains)
|
|
||||||
(libraries
|
|
||||||
trace
|
|
||||||
; use the marker library to pick between the real test and the quine fallback.
|
|
||||||
(select
|
|
||||||
t_domains.ml
|
|
||||||
from
|
|
||||||
(ocaml5 threads -> t_domains.real.ml)
|
|
||||||
(-> t_domains.quine.ml))))
|
|
||||||
|
|
||||||
(rule
|
|
||||||
(alias runtest)
|
|
||||||
(package trace)
|
|
||||||
(action
|
|
||||||
(progn
|
|
||||||
(with-stdout-to
|
|
||||||
t_domains.output
|
|
||||||
(run %{exe:t_domains.exe} %{dep:t_domains.expected}))
|
|
||||||
(diff t_domains.expected t_domains.output))))
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
(* Marker module: presence indicates OCaml 5+ (and thus Domain availability). *)
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
=== domain concurrency ===
|
|
||||||
domain-0: enter=10000 exit=10000 msg=10000
|
|
||||||
domain-1: enter=10000 exit=10000 msg=10000
|
|
||||||
domain-2: enter=10000 exit=10000 msg=10000
|
|
||||||
domain-3: enter=10000 exit=10000 msg=10000
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
(* When Domain is unavailable (OCaml < 5), echo the expected file
|
|
||||||
so the diff always passes. The file is passed as argv[1] by the dune rule. *)
|
|
||||||
let () =
|
|
||||||
let ic = open_in Sys.argv.(1) in
|
|
||||||
(try
|
|
||||||
while true do
|
|
||||||
print_char (input_char ic)
|
|
||||||
done
|
|
||||||
with End_of_file -> ());
|
|
||||||
close_in ic
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
(* Test concurrent span recording across multiple domains (OCaml 5+).
|
|
||||||
Each domain runs [iters] spans. We embed the recording thread's id into
|
|
||||||
the span value so that exit events can be attributed to the right domain,
|
|
||||||
then verify that every domain has exactly [iters] enters and exits. *)
|
|
||||||
|
|
||||||
let ( let@ ) = ( @@ )
|
|
||||||
let iters = 10_000
|
|
||||||
|
|
||||||
(* Custom span type that carries the thread id of the recording domain. *)
|
|
||||||
type Trace_core.span += Thread_span of int
|
|
||||||
|
|
||||||
let make_recorder () =
|
|
||||||
let log = Queue.create () in
|
|
||||||
let mu = Mutex.create () in
|
|
||||||
let add x =
|
|
||||||
Mutex.lock mu;
|
|
||||||
Queue.add x log;
|
|
||||||
Mutex.unlock mu
|
|
||||||
in
|
|
||||||
let enter_span () ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_ ~level:_ ~params:_
|
|
||||||
~data:_ ~parent:_ _name =
|
|
||||||
let tid = Thread.id (Thread.self ()) in
|
|
||||||
add (`Enter tid);
|
|
||||||
Thread_span tid
|
|
||||||
in
|
|
||||||
let exit_span () sp =
|
|
||||||
match sp with
|
|
||||||
| Thread_span tid -> add (`Exit tid)
|
|
||||||
| _ -> ()
|
|
||||||
in
|
|
||||||
let message () ~level:_ ~params:_ ~data:_ ~span:_ _msg =
|
|
||||||
add (`Msg (Thread.id (Thread.self ())))
|
|
||||||
in
|
|
||||||
let metric () ~level:_ ~params:_ ~data:_ _name _m = () in
|
|
||||||
let add_data_to_span () _sp _data = () in
|
|
||||||
let coll =
|
|
||||||
Trace_core.Collector.(
|
|
||||||
C_some
|
|
||||||
( (),
|
|
||||||
Callbacks.make ~enter_span ~exit_span ~add_data_to_span ~message
|
|
||||||
~metric () ))
|
|
||||||
in
|
|
||||||
coll, fun () -> Queue.fold (fun acc x -> x :: acc) [] log |> List.rev
|
|
||||||
|
|
||||||
let () =
|
|
||||||
print_endline "=== domain concurrency ===";
|
|
||||||
let coll, get = make_recorder () in
|
|
||||||
let@ () = Trace_core.with_setup_collector coll in
|
|
||||||
let n = 4 in
|
|
||||||
(* Each domain returns its own thread id so we can check per-domain counts. *)
|
|
||||||
let domains =
|
|
||||||
Array.init n (fun _i ->
|
|
||||||
Domain.spawn (fun () ->
|
|
||||||
let tid = Thread.id (Thread.self ()) in
|
|
||||||
for j = 1 to iters do
|
|
||||||
Trace_core.with_span ~__FILE__ ~__LINE__ "" @@ fun _ ->
|
|
||||||
Trace_core.message "";
|
|
||||||
if j mod 1000 = 0 then Thread.yield ()
|
|
||||||
done;
|
|
||||||
tid))
|
|
||||||
in
|
|
||||||
let tids = Array.map Domain.join domains in
|
|
||||||
let events = get () in
|
|
||||||
let count pred = List.length (List.filter pred events) in
|
|
||||||
(* For each domain, verify exactly [iters] enters and [iters] exits. *)
|
|
||||||
Array.iteri
|
|
||||||
(fun i tid ->
|
|
||||||
let n_enter =
|
|
||||||
count (function
|
|
||||||
| `Enter t -> t = tid
|
|
||||||
| _ -> false)
|
|
||||||
in
|
|
||||||
let n_exit =
|
|
||||||
count (function
|
|
||||||
| `Exit t -> t = tid
|
|
||||||
| _ -> false)
|
|
||||||
in
|
|
||||||
let n_msg =
|
|
||||||
count (function
|
|
||||||
| `Msg t -> t = tid
|
|
||||||
| _ -> false)
|
|
||||||
in
|
|
||||||
Printf.printf "domain-%d: enter=%d exit=%d msg=%d%s\n" i n_enter n_exit
|
|
||||||
n_msg
|
|
||||||
(if n_enter = iters && n_exit = iters && n_msg = iters then
|
|
||||||
""
|
|
||||||
else
|
|
||||||
" FAIL"))
|
|
||||||
tids
|
|
||||||
16
test/dune
16
test/dune
|
|
@ -1,7 +1,7 @@
|
||||||
(tests
|
(test
|
||||||
(names t1 t_core t_debug)
|
(name t1)
|
||||||
(modules t1 t_core t_debug)
|
|
||||||
(package trace-tef)
|
(package trace-tef)
|
||||||
|
(modules t1)
|
||||||
(libraries trace trace-tef))
|
(libraries trace trace-tef))
|
||||||
|
|
||||||
(test
|
(test
|
||||||
|
|
@ -13,9 +13,7 @@
|
||||||
(libraries trace-tef))
|
(libraries trace-tef))
|
||||||
|
|
||||||
(test
|
(test
|
||||||
(name t_runtime_events)
|
(name t_debug)
|
||||||
(package trace-runtime-events)
|
(modules t_debug)
|
||||||
(modules t_runtime_events)
|
(package trace-tef)
|
||||||
(preprocess
|
(libraries trace trace.debug trace-tef))
|
||||||
(pps ppx_trace))
|
|
||||||
(libraries trace trace-runtime-events runtime_events))
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
module Trace = Trace_core
|
|
||||||
|
|
||||||
let run () =
|
let run () =
|
||||||
Trace.set_process_name "main";
|
Trace.set_process_name "main";
|
||||||
Trace.set_thread_name "t1";
|
Trace.set_thread_name "t1";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
module Trace = Trace_core
|
|
||||||
|
|
||||||
let ( let@ ) = ( @@ )
|
let ( let@ ) = ( @@ )
|
||||||
|
|
||||||
let rec fib x =
|
let rec fib x =
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
=== level filtering ===
|
|
||||||
enter(error-span)
|
|
||||||
enter(info-span)
|
|
||||||
msg(warn-msg)
|
|
||||||
=== manual enter/exit ===
|
|
||||||
enter(manual)
|
|
||||||
exit
|
|
||||||
=== exception safety ===
|
|
||||||
enter(risky)
|
|
||||||
exit
|
|
||||||
=== no collector ===
|
|
||||||
ok
|
|
||||||
=== double setup ===
|
|
||||||
caught: trace: collector already present
|
|
||||||
=== metrics ===
|
|
||||||
metric(my_int,42)
|
|
||||||
metric(my_float,3.14)
|
|
||||||
=== with_setup_collector exception safety ===
|
|
||||||
shutdown called: true
|
|
||||||
138
test/t_core.ml
138
test/t_core.ml
|
|
@ -1,138 +0,0 @@
|
||||||
module Trace = Trace_core
|
|
||||||
|
|
||||||
let ( let@ ) = ( @@ )
|
|
||||||
|
|
||||||
(** mini recording collector *)
|
|
||||||
let make_recorder ?(on_shutdown = fun () -> ()) () :
|
|
||||||
Trace.Collector.t * (unit -> _ list) =
|
|
||||||
let log = Queue.create () in
|
|
||||||
let enter_span () ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_ ~level:_ ~params:_
|
|
||||||
~data:_ ~parent:_ name =
|
|
||||||
Queue.add (`Enter name) log;
|
|
||||||
Trace.Collector.dummy_span
|
|
||||||
in
|
|
||||||
let exit_span () _sp = Queue.add `Exit log in
|
|
||||||
let message () ~level:_ ~params:_ ~data:_ ~span:_ msg =
|
|
||||||
Queue.add (`Msg msg) log
|
|
||||||
in
|
|
||||||
let metric () ~level:_ ~params:_ ~data:_ name m =
|
|
||||||
let v =
|
|
||||||
match m with
|
|
||||||
| Trace.Core_ext.Metric_int n -> string_of_int n
|
|
||||||
| Trace.Core_ext.Metric_float f -> Printf.sprintf "%.2f" f
|
|
||||||
| _ -> "?"
|
|
||||||
in
|
|
||||||
Queue.add (`Metric (name, v)) log
|
|
||||||
in
|
|
||||||
let add_data_to_span () _sp _data = () in
|
|
||||||
let coll =
|
|
||||||
Trace.Collector.(
|
|
||||||
C_some
|
|
||||||
( (),
|
|
||||||
Callbacks.make ~enter_span ~exit_span ~add_data_to_span ~message
|
|
||||||
~metric
|
|
||||||
~shutdown:(fun () -> on_shutdown ())
|
|
||||||
() ))
|
|
||||||
in
|
|
||||||
coll, fun () -> Queue.fold (fun acc x -> x :: acc) [] log |> List.rev
|
|
||||||
|
|
||||||
let dump events =
|
|
||||||
List.iter
|
|
||||||
(function
|
|
||||||
| `Enter s -> Printf.printf "enter(%s)\n" s
|
|
||||||
| `Exit -> print_endline "exit"
|
|
||||||
| `Msg s -> Printf.printf "msg(%s)\n" s
|
|
||||||
| `Metric (n, v) -> Printf.printf "metric(%s,%s)\n" n v)
|
|
||||||
events
|
|
||||||
|
|
||||||
(* current_level acts as a ceiling: events with level <= current_level pass.
|
|
||||||
Level order: Error < Warning < Info < Debug1 < Debug2 < Debug3 < Trace
|
|
||||||
With current_level=Info: Error, Warning, Info pass; Debug1..Trace are filtered. *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== level filtering ===";
|
|
||||||
let coll, get = make_recorder () in
|
|
||||||
Trace.set_current_level Trace.Level.Info;
|
|
||||||
let@ () = Trace.with_setup_collector coll in
|
|
||||||
let@ _ =
|
|
||||||
Trace.with_span ~level:Trace.Level.Error ~__FILE__ ~__LINE__ "error-span"
|
|
||||||
in
|
|
||||||
let@ _ =
|
|
||||||
Trace.with_span ~level:Trace.Level.Info ~__FILE__ ~__LINE__ "info-span"
|
|
||||||
in
|
|
||||||
let@ _ =
|
|
||||||
Trace.with_span ~level:Trace.Level.Debug1 ~__FILE__ ~__LINE__ "debug-span"
|
|
||||||
in
|
|
||||||
Trace.message ~level:Trace.Level.Warning "warn-msg";
|
|
||||||
Trace.message ~level:Trace.Level.Trace "trace-msg";
|
|
||||||
dump (get ());
|
|
||||||
Trace.set_current_level Trace.Level.Trace
|
|
||||||
|
|
||||||
(* manual enter/exit round-trip
|
|
||||||
Verify exit_span is called when using enter_span/exit_span directly. *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== manual enter/exit ===";
|
|
||||||
let coll, get = make_recorder () in
|
|
||||||
let@ () = Trace.with_setup_collector coll in
|
|
||||||
let sp = Trace.enter_span ~__FILE__ ~__LINE__ "manual" in
|
|
||||||
Trace.exit_span sp;
|
|
||||||
dump (get ())
|
|
||||||
|
|
||||||
(* exception safety in with_span
|
|
||||||
The span must be exited even when the body raises. *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== exception safety ===";
|
|
||||||
let coll, get = make_recorder () in
|
|
||||||
let@ () = Trace.with_setup_collector coll in
|
|
||||||
(try Trace.with_span ~__FILE__ ~__LINE__ "risky" @@ fun _ -> raise Exit
|
|
||||||
with Exit -> ());
|
|
||||||
dump (get ())
|
|
||||||
|
|
||||||
(* no-collector behavior
|
|
||||||
All operations are no-ops; messagef's thunk must not be called. *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== no collector ===";
|
|
||||||
assert (not (Trace.enabled ()));
|
|
||||||
let sp = Trace.enter_span ~__FILE__ ~__LINE__ "noop" in
|
|
||||||
assert (sp == Trace.Collector.dummy_span);
|
|
||||||
Trace.exit_span sp;
|
|
||||||
let@ sp = Trace.with_span ~__FILE__ ~__LINE__ "noop2" in
|
|
||||||
assert (sp == Trace.Collector.dummy_span);
|
|
||||||
Trace.message "ignored";
|
|
||||||
Trace.counter_int "ignored" 42;
|
|
||||||
let called = ref false in
|
|
||||||
Trace.messagef (fun k ->
|
|
||||||
called := true;
|
|
||||||
k "ignored");
|
|
||||||
assert (not !called);
|
|
||||||
print_endline "ok"
|
|
||||||
|
|
||||||
(* double setup_collector
|
|
||||||
Installing a second collector while one is active raises Invalid_argument. *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== double setup ===";
|
|
||||||
let coll, _ = make_recorder () in
|
|
||||||
let coll2, _ = make_recorder () in
|
|
||||||
let@ () = Trace.with_setup_collector coll in
|
|
||||||
match Trace.setup_collector coll2 with
|
|
||||||
| exception Invalid_argument msg -> Printf.printf "caught: %s\n" msg
|
|
||||||
| () -> assert false
|
|
||||||
|
|
||||||
(* counter_float and metric *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== metrics ===";
|
|
||||||
let coll, get = make_recorder () in
|
|
||||||
let@ () = Trace.with_setup_collector coll in
|
|
||||||
Trace.counter_int "my_int" 42;
|
|
||||||
Trace.counter_float "my_float" 3.14;
|
|
||||||
dump (get ())
|
|
||||||
|
|
||||||
(* with_setup_collector exception safety
|
|
||||||
shutdown must be called even when the body raises. *)
|
|
||||||
let () =
|
|
||||||
print_endline "=== with_setup_collector exception safety ===";
|
|
||||||
let shutdown_called = ref false in
|
|
||||||
let coll, _ =
|
|
||||||
make_recorder ~on_shutdown:(fun () -> shutdown_called := true) ()
|
|
||||||
in
|
|
||||||
(try Trace.with_setup_collector coll @@ fun () -> raise Exit with Exit -> ());
|
|
||||||
Printf.printf "shutdown called: %b\n" !shutdown_called
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
module Trace = Trace_core
|
|
||||||
|
|
||||||
let ( let@ ) = ( @@ )
|
let ( let@ ) = ( @@ )
|
||||||
|
|
||||||
let main () =
|
let main () =
|
||||||
|
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
(** Test program for the Runtime_events backend.
|
|
||||||
|
|
||||||
This demonstrates and tests the Runtime_events backend by: 1. Emitting trace
|
|
||||||
events 2. Subscribing to the ringbuffer 3. Collecting all events 4.
|
|
||||||
Verifying expected events were emitted *)
|
|
||||||
|
|
||||||
let ( let@ ) = ( @@ )
|
|
||||||
|
|
||||||
(* Event types we'll collect *)
|
|
||||||
type collected_event =
|
|
||||||
| Span_enter of string
|
|
||||||
| Span_exit of string
|
|
||||||
| Message of string
|
|
||||||
| Metric_int of string * int
|
|
||||||
| Metric_float of string * float
|
|
||||||
|
|
||||||
(* Simple recursive function to generate some trace activity *)
|
|
||||||
let rec fib x =
|
|
||||||
let%trace () = "fib" in
|
|
||||||
if x <= 2 then
|
|
||||||
1
|
|
||||||
else
|
|
||||||
fib (x - 1) + fib (x - 2)
|
|
||||||
|
|
||||||
(* Function with explicit span *)
|
|
||||||
let do_work () =
|
|
||||||
Trace_core.with_span ~__FILE__ ~__LINE__ "do_work" @@ fun _sp ->
|
|
||||||
Trace_core.message "Starting work";
|
|
||||||
Trace_core.counter_int "work_units" 100;
|
|
||||||
|
|
||||||
let result = fib 10 in
|
|
||||||
|
|
||||||
Trace_core.messagef (fun k -> k "Computed fib(10) = %d" result);
|
|
||||||
Trace_core.counter_int "work_units" 200;
|
|
||||||
result
|
|
||||||
|
|
||||||
(* Subscribe to runtime events and collect them *)
|
|
||||||
let collect_events () =
|
|
||||||
let events = ref [] in
|
|
||||||
|
|
||||||
(* Create a cursor to read from our own process *)
|
|
||||||
let cursor = Runtime_events.create_cursor None in
|
|
||||||
|
|
||||||
(* Set up callbacks *)
|
|
||||||
let callbacks =
|
|
||||||
Runtime_events.Callbacks.create ()
|
|
||||||
(* Register callbacks for our custom events using type values *)
|
|
||||||
|> Runtime_events.Callbacks.add_user_event
|
|
||||||
Trace_runtime_events.String_type.ty (fun _domain_id _ts tag name ->
|
|
||||||
match Runtime_events.User.tag tag with
|
|
||||||
| Trace_runtime_events.Events.Tag_span_enter ->
|
|
||||||
events := Span_enter name :: !events
|
|
||||||
| Trace_runtime_events.Events.Tag_span_exit ->
|
|
||||||
events := Span_exit name :: !events
|
|
||||||
| Trace_runtime_events.Events.Tag_message ->
|
|
||||||
events := Message name :: !events
|
|
||||||
| _ -> ())
|
|
||||||
|> Runtime_events.Callbacks.add_user_event
|
|
||||||
Trace_runtime_events.String_int.ty
|
|
||||||
(fun _domain_id _ts tag (name, value) ->
|
|
||||||
match Runtime_events.User.tag tag with
|
|
||||||
| Trace_runtime_events.Events.Tag_metric_int ->
|
|
||||||
events := Metric_int (name, value) :: !events
|
|
||||||
| _ -> ())
|
|
||||||
|> Runtime_events.Callbacks.add_user_event
|
|
||||||
Trace_runtime_events.String_float.ty
|
|
||||||
(fun _domain_id _ts tag (name, value) ->
|
|
||||||
match Runtime_events.User.tag tag with
|
|
||||||
| Trace_runtime_events.Events.Tag_metric_float ->
|
|
||||||
events := Metric_float (name, value) :: !events
|
|
||||||
| _ -> ())
|
|
||||||
in
|
|
||||||
|
|
||||||
(* Read all events from the ringbuffer *)
|
|
||||||
let _lost_events = Runtime_events.read_poll cursor callbacks None in
|
|
||||||
|
|
||||||
List.rev !events
|
|
||||||
|
|
||||||
let () =
|
|
||||||
(* Initialize the Runtime_events backend with start_events=false
|
|
||||||
so we can manually control when to start *)
|
|
||||||
Trace_runtime_events.setup ~start_events:false ();
|
|
||||||
|
|
||||||
(* Start runtime events *)
|
|
||||||
Runtime_events.start ();
|
|
||||||
|
|
||||||
(* Set process and thread names *)
|
|
||||||
Trace_core.set_process_name "test";
|
|
||||||
Trace_core.set_thread_name "main";
|
|
||||||
|
|
||||||
(* Do some traced work *)
|
|
||||||
let result = do_work () in
|
|
||||||
Printf.eprintf "result: %d\n" result;
|
|
||||||
|
|
||||||
(* Collect events from the ringbuffer *)
|
|
||||||
let events = collect_events () in
|
|
||||||
|
|
||||||
Printf.eprintf "\ncollected %d events:\n" (List.length events);
|
|
||||||
List.iter
|
|
||||||
(fun ev ->
|
|
||||||
match ev with
|
|
||||||
| Span_enter name -> Printf.eprintf " - span enter: %s\n" name
|
|
||||||
| Span_exit name -> Printf.eprintf " - span exit: %s\n" name
|
|
||||||
| Message msg -> Printf.eprintf " - message: %s\n" msg
|
|
||||||
| Metric_int (name, value) ->
|
|
||||||
Printf.eprintf " - metric int: %s = %d\n" name value
|
|
||||||
| Metric_float (name, value) ->
|
|
||||||
Printf.eprintf " - metric float: %s = %f\n" name value)
|
|
||||||
events;
|
|
||||||
|
|
||||||
(* Verify expected events *)
|
|
||||||
let has_do_work_enter =
|
|
||||||
List.exists
|
|
||||||
(function
|
|
||||||
| Span_enter "do_work" -> true
|
|
||||||
| _ -> false)
|
|
||||||
events
|
|
||||||
in
|
|
||||||
let has_do_work_exit =
|
|
||||||
List.exists
|
|
||||||
(function
|
|
||||||
| Span_exit "do_work" -> true
|
|
||||||
| _ -> false)
|
|
||||||
events
|
|
||||||
in
|
|
||||||
let has_fib_spans =
|
|
||||||
List.filter
|
|
||||||
(function
|
|
||||||
| Span_enter "fib" | Span_exit "fib" -> true
|
|
||||||
| _ -> false)
|
|
||||||
events
|
|
||||||
in
|
|
||||||
let has_starting_work =
|
|
||||||
List.exists
|
|
||||||
(function
|
|
||||||
| Message "Starting work" -> true
|
|
||||||
| _ -> false)
|
|
||||||
events
|
|
||||||
in
|
|
||||||
let has_metrics =
|
|
||||||
List.filter
|
|
||||||
(function
|
|
||||||
| Metric_int ("work_units", _) -> true
|
|
||||||
| _ -> false)
|
|
||||||
events
|
|
||||||
in
|
|
||||||
|
|
||||||
Printf.eprintf "\nVerification:\n";
|
|
||||||
Printf.eprintf " - do_work span enter: %b\n" has_do_work_enter;
|
|
||||||
Printf.eprintf " - do_work span exit: %b\n" has_do_work_exit;
|
|
||||||
Printf.eprintf " - fib spans (enter+exit): %d\n" (List.length has_fib_spans);
|
|
||||||
Printf.eprintf " - 'Starting work' message: %b\n" has_starting_work;
|
|
||||||
Printf.eprintf " - work_units metrics: %d\n" (List.length has_metrics);
|
|
||||||
|
|
||||||
(* Check assertions *)
|
|
||||||
assert has_do_work_enter;
|
|
||||||
assert has_do_work_exit;
|
|
||||||
assert (List.length has_fib_spans = 218);
|
|
||||||
assert has_starting_work;
|
|
||||||
assert (List.length has_metrics = 2);
|
|
||||||
|
|
||||||
Printf.eprintf "\nall good :-)\n";
|
|
||||||
|
|
||||||
Trace_core.shutdown ()
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
(executable
|
|
||||||
(name t_tls)
|
|
||||||
(modules t_tls)
|
|
||||||
(libraries
|
|
||||||
trace
|
|
||||||
; avoid using a recent dune with `enabled-if`, by just using `select` instead.
|
|
||||||
; the dummy case just echoes back the expected file.
|
|
||||||
(select
|
|
||||||
t_tls.ml
|
|
||||||
from
|
|
||||||
(trace.thread-local-storage -> t_tls.real.ml)
|
|
||||||
(-> t_tls.quine.ml))))
|
|
||||||
|
|
||||||
(rule
|
|
||||||
(alias runtest)
|
|
||||||
(action
|
|
||||||
(progn
|
|
||||||
(with-stdout-to
|
|
||||||
t_tls.output
|
|
||||||
(run %{exe:t_tls.exe} %{dep:t_tls.expected}))
|
|
||||||
(diff t_tls.expected t_tls.output))))
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
=== ambient span (TLS) ===
|
|
||||||
before any span: none
|
|
||||||
in outer: outer
|
|
||||||
in inner: inner
|
|
||||||
after inner exits: outer
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
(* When trace.thread-local-storage is unavailable, echo the expected file
|
|
||||||
so the diff always passes. The file is passed as argv[1] by the dune rule. *)
|
|
||||||
let () =
|
|
||||||
let ic = open_in Sys.argv.(1) in
|
|
||||||
(try
|
|
||||||
while true do
|
|
||||||
print_char (input_char ic)
|
|
||||||
done
|
|
||||||
with End_of_file -> ());
|
|
||||||
close_in ic
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
(* Test ambient span tracking via thread-local-storage provider *)
|
|
||||||
|
|
||||||
let ( let@ ) = ( @@ )
|
|
||||||
|
|
||||||
(* Unique span type so we can identify spans by name *)
|
|
||||||
type Trace_core.span += Named of string
|
|
||||||
|
|
||||||
let make_recorder () =
|
|
||||||
let open Trace_core.Collector in
|
|
||||||
let cbs =
|
|
||||||
Callbacks.make
|
|
||||||
~enter_span:(fun
|
|
||||||
()
|
|
||||||
~__FUNCTION__:_
|
|
||||||
~__FILE__:_
|
|
||||||
~__LINE__:_
|
|
||||||
~level:_
|
|
||||||
~params:_
|
|
||||||
~data:_
|
|
||||||
~parent:_
|
|
||||||
name
|
|
||||||
-> Named name)
|
|
||||||
~exit_span:(fun () _sp -> ())
|
|
||||||
~add_data_to_span:(fun () _sp _data -> ())
|
|
||||||
~message:(fun () ~level:_ ~params:_ ~data:_ ~span:_ _msg -> ())
|
|
||||||
~metric:(fun () ~level:_ ~params:_ ~data:_ _name _m -> ())
|
|
||||||
()
|
|
||||||
in
|
|
||||||
C_some ((), cbs)
|
|
||||||
|
|
||||||
let current_name () =
|
|
||||||
match Trace_core.current_span () with
|
|
||||||
| None -> "none"
|
|
||||||
| Some (Named s) -> s
|
|
||||||
| Some _ -> "<other>"
|
|
||||||
|
|
||||||
let () =
|
|
||||||
print_endline "=== ambient span (TLS) ===";
|
|
||||||
Trace_thread_local_storage.setup ();
|
|
||||||
let coll = make_recorder () in
|
|
||||||
let@ () = Trace_core.with_setup_collector coll in
|
|
||||||
|
|
||||||
Printf.printf "before any span: %s\n" (current_name ());
|
|
||||||
|
|
||||||
let@ _outer = Trace_core.with_span ~__FILE__ ~__LINE__ "outer" in
|
|
||||||
Printf.printf "in outer: %s\n" (current_name ());
|
|
||||||
|
|
||||||
(* inner span is scoped to just the one printf *)
|
|
||||||
(let@ _inner = Trace_core.with_span ~__FILE__ ~__LINE__ "inner" in
|
|
||||||
ignore _inner;
|
|
||||||
Printf.printf "in inner: %s\n" (current_name ()));
|
|
||||||
|
|
||||||
(* inner has exited, outer span is restored *)
|
|
||||||
Printf.printf "after inner exits: %s\n" (current_name ())
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# This file is generated by dune, edit dune-project instead
|
# This file is generated by dune, edit dune-project instead
|
||||||
opam-version: "2.0"
|
opam-version: "2.0"
|
||||||
version: "0.12"
|
version: "0.11"
|
||||||
synopsis:
|
synopsis:
|
||||||
"A high-performance backend for trace, emitting a Fuchsia trace into a file"
|
"A high-performance backend for trace, emitting a Fuchsia trace into a file"
|
||||||
maintainer: ["Simon Cruanes"]
|
maintainer: ["Simon Cruanes"]
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
# This file is generated by dune, edit dune-project instead
|
|
||||||
opam-version: "2.0"
|
|
||||||
version: "0.12"
|
|
||||||
synopsis:
|
|
||||||
"A simple collector relying on runtime-events for OCaml 5. Some assembly required."
|
|
||||||
maintainer: ["Simon Cruanes"]
|
|
||||||
authors: ["Simon Cruanes"]
|
|
||||||
license: "MIT"
|
|
||||||
tags: ["trace" "tracing" "trace" "runtime-events"]
|
|
||||||
homepage: "https://github.com/ocaml-tracing/ocaml-trace"
|
|
||||||
bug-reports: "https://github.com/ocaml-tracing/ocaml-trace/issues"
|
|
||||||
depends: [
|
|
||||||
"ocaml" {>= "5.1"}
|
|
||||||
"trace" {= version}
|
|
||||||
"ppx_trace" {= version & with-test}
|
|
||||||
"base-bigarray"
|
|
||||||
"base-unix"
|
|
||||||
"dune" {>= "2.9"}
|
|
||||||
"odoc" {with-doc}
|
|
||||||
]
|
|
||||||
build: [
|
|
||||||
["dune" "subst"] {dev}
|
|
||||||
[
|
|
||||||
"dune"
|
|
||||||
"build"
|
|
||||||
"-p"
|
|
||||||
name
|
|
||||||
"-j"
|
|
||||||
jobs
|
|
||||||
"--promote-install-files=false"
|
|
||||||
"@install"
|
|
||||||
"@runtest" {with-test}
|
|
||||||
"@doc" {with-doc}
|
|
||||||
]
|
|
||||||
["dune" "install" "-p" name "--create-install-files" name]
|
|
||||||
]
|
|
||||||
dev-repo: "git+https://github.com/ocaml-tracing/ocaml-trace.git"
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# This file is generated by dune, edit dune-project instead
|
# This file is generated by dune, edit dune-project instead
|
||||||
opam-version: "2.0"
|
opam-version: "2.0"
|
||||||
version: "0.12"
|
version: "0.11"
|
||||||
synopsis:
|
synopsis:
|
||||||
"A simple backend for trace, emitting Catapult/TEF JSON into a file"
|
"A simple backend for trace, emitting Catapult/TEF JSON into a file"
|
||||||
maintainer: ["Simon Cruanes"]
|
maintainer: ["Simon Cruanes"]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# This file is generated by dune, edit dune-project instead
|
# This file is generated by dune, edit dune-project instead
|
||||||
opam-version: "2.0"
|
opam-version: "2.0"
|
||||||
version: "0.12"
|
version: "0.11"
|
||||||
synopsis:
|
synopsis:
|
||||||
"A lightweight stub for tracing/observability, agnostic in how data is collected"
|
"A lightweight stub for tracing/observability, agnostic in how data is collected"
|
||||||
description: """
|
description: """
|
||||||
|
|
@ -21,7 +21,6 @@ depends: [
|
||||||
]
|
]
|
||||||
depopts: [
|
depopts: [
|
||||||
"unix"
|
"unix"
|
||||||
"thread-local-storage" {>= "0.2"}
|
|
||||||
"mtime" {>= "2.0"}
|
"mtime" {>= "2.0"}
|
||||||
]
|
]
|
||||||
build: [
|
build: [
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue