package trace

  1. Overview
  2. Docs

Source file trace_core.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
include Types
module A = Atomic_
module Collector = Collector
module Meta_map = Meta_map
module Level = Level

type collector = (module Collector.S)

(* ## globals ## *)

(** Global collector. *)
let collector : collector option A.t = A.make None

(* default level for spans without a level *)
let default_level_ = A.make Level.Trace
let current_level_ = A.make Level.Trace

(* ## implementation ## *)

let[@inline] ctx_of_span (sp : explicit_span) : explicit_span_ctx =
  { span = sp.span; trace_id = sp.trace_id }

let data_empty_build_ () = []

let[@inline] enabled () =
  match A.get collector with
  | None -> false
  | Some _ -> true

let[@inline] get_default_level () = A.get default_level_
let[@inline] set_default_level l = A.set default_level_ l
let[@inline] set_current_level l = A.set current_level_ l
let[@inline] get_current_level () = A.get current_level_

let[@inline] check_level ?(level = A.get default_level_) () : bool =
  Level.leq level (A.get current_level_)

let with_span_collector_ (module C : Collector.S) ?__FUNCTION__ ~__FILE__
    ~__LINE__ ?(data = data_empty_build_) name f =
  let data = data () in
  C.with_span ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name f

let[@inline] with_span ?level ?__FUNCTION__ ~__FILE__ ~__LINE__ ?data name f =
  match A.get collector with
  | Some collector when check_level ?level () ->
    with_span_collector_ collector ?__FUNCTION__ ~__FILE__ ~__LINE__ ?data name
      f
  | _ ->
    (* fast path: no collector, no span *)
    f Collector.dummy_span

let[@inline] enter_span ?level ?__FUNCTION__ ~__FILE__ ~__LINE__
    ?(data = data_empty_build_) name : span =
  match A.get collector with
  | Some (module C) when check_level ?level () ->
    let data = data () in
    C.enter_span ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name
  | _ -> Collector.dummy_span

let[@inline] exit_span sp : unit =
  match A.get collector with
  | None -> ()
  | Some (module C) -> C.exit_span sp

let enter_manual_span_collector_ (module C : Collector.S) ~parent ~flavor
    ?__FUNCTION__ ~__FILE__ ~__LINE__ ?(data = data_empty_build_) name :
    explicit_span =
  let data = data () in
  C.enter_manual_span ~parent ~flavor ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data
    name

let[@inline] enter_manual_span ~parent ?flavor ?level ?__FUNCTION__ ~__FILE__
    ~__LINE__ ?data name : explicit_span =
  match A.get collector with
  | Some coll when check_level ?level () ->
    enter_manual_span_collector_ coll ~parent ~flavor ?__FUNCTION__ ~__FILE__
      ~__LINE__ ?data name
  | _ -> Collector.dummy_explicit_span

let[@inline] enter_manual_toplevel_span ?flavor ?level ?__FUNCTION__ ~__FILE__
    ~__LINE__ ?data name : explicit_span =
  enter_manual_span ~parent:None ?flavor ?level ?__FUNCTION__ ~__FILE__
    ~__LINE__ ?data name

let[@inline] enter_manual_sub_span ~parent ?flavor ?level ?__FUNCTION__
    ~__FILE__ ~__LINE__ ?data name : explicit_span =
  enter_manual_span
    ~parent:(Some (ctx_of_span parent))
    ?flavor ?level ?__FUNCTION__ ~__FILE__ ~__LINE__ ?data name

let[@inline] exit_manual_span espan : unit =
  if espan != Collector.dummy_explicit_span then (
    match A.get collector with
    | None -> ()
    | Some (module C) -> C.exit_manual_span espan
  )

let[@inline] add_data_to_span sp data : unit =
  if sp != Collector.dummy_span && data <> [] then (
    match A.get collector with
    | None -> ()
    | Some (module C) -> C.add_data_to_span sp data
  )

let[@inline] add_data_to_manual_span esp data : unit =
  if esp != Collector.dummy_explicit_span && data <> [] then (
    match A.get collector with
    | None -> ()
    | Some (module C) -> C.add_data_to_manual_span esp data
  )

let message_collector_ (module C : Collector.S) ?span
    ?(data = data_empty_build_) msg : unit =
  let data = data () in
  C.message ?span ~data msg

let[@inline] message ?level ?span ?data msg : unit =
  match A.get collector with
  | Some coll when check_level ?level () ->
    message_collector_ coll ?span ?data msg
  | _ -> ()

let messagef ?level ?span ?data k =
  match A.get collector with
  | Some (module C) when check_level ?level () ->
    k (fun fmt ->
        Format.kasprintf
          (fun str ->
            let data =
              match data with
              | None -> []
              | Some f -> f ()
            in
            C.message ?span ~data str)
          fmt)
  | _ -> ()

let counter_int ?level ?(data = data_empty_build_) name n : unit =
  match A.get collector with
  | Some (module C) when check_level ?level () ->
    let data = data () in
    C.counter_int ~data name n
  | _ -> ()

let counter_float ?level ?(data = data_empty_build_) name f : unit =
  match A.get collector with
  | Some (module C) when check_level ?level () ->
    let data = data () in
    C.counter_float ~data name f
  | _ -> ()

let set_thread_name name : unit =
  match A.get collector with
  | None -> ()
  | Some (module C) -> C.name_thread name

let set_process_name name : unit =
  match A.get collector with
  | None -> ()
  | Some (module C) -> C.name_process name

let setup_collector c : unit =
  while
    let cur = A.get collector in
    match cur with
    | Some _ -> invalid_arg "trace: collector already present"
    | None -> not (A.compare_and_set collector cur (Some c))
  do
    ()
  done

let shutdown () =
  match A.exchange collector None with
  | None -> ()
  | Some (module C) -> C.shutdown ()

type extension_event = Types.extension_event = ..

let[@inline] extension_event ev =
  match A.get collector with
  | None -> ()
  | Some (module C) -> C.extension_event ev

module Internal_ = struct
  module Atomic_ = Atomic_
end
OCaml

Innovation. Community. Security.