-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathminidebug_runtime.mli
354 lines (316 loc) · 14.9 KB
/
minidebug_runtime.mli
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
(** The functors creating a [Debug_runtime] module that
{{:http://lukstafi.github.io/ppx_minidebug/ppx_minidebug/Minidebug_runtime/index.html}
[ppx_minidebug]} requires. *)
type time_tagged = Not_tagged | Clock | Elapsed
type elapsed_times = Not_reported | Seconds | Milliseconds | Microseconds | Nanoseconds
type location_format =
| No_location
| File_only
| Beg_line
| Beg_pos
| Range_line
| Range_pos
type toc_entry_criteria =
| Minimal_depth of int
| Minimal_size of int
| Minimal_span of Mtime.span
| And of toc_entry_criteria list
| Or of toc_entry_criteria list
module type Shared_config = sig
val refresh_ch : unit -> bool
val debug_ch : unit -> out_channel
val debug_ch_name : unit -> string
val snapshot_ch : unit -> unit
val reset_to_snapshot : unit -> unit
val table_of_contents_ch : out_channel option
val time_tagged : time_tagged
val elapsed_times : elapsed_times
val location_format : location_format
val print_entry_ids : bool
val verbose_entry_ids : bool
val global_prefix : string
val split_files_after : int option
val toc_entry : toc_entry_criteria
val description : string
val init_log_level : int
end
val shared_config :
?time_tagged:time_tagged ->
?elapsed_times:elapsed_times ->
?location_format:location_format ->
?print_entry_ids:bool ->
?verbose_entry_ids:bool ->
?global_prefix:string ->
?split_files_after:int ->
?with_table_of_contents:bool ->
?toc_entry:toc_entry_criteria ->
?for_append:bool ->
?log_level:int ->
string ->
(module Shared_config)
(** Sets up a file with the given path, or if [split_files_after] is given, creates a
directory to store the files. By default the logging will not be time tagged and will
be appending to the file / creating more files. If [time_tagged] is [Clock], entries
will be tagged with a date and clock time; if it is [Elapsed], they will be tagged
with the time span elapsed since the start of the process (using
[Mtime_clock.elapsed]). If [split_files_after] is given and [for_append] is false,
clears the directory. If the opened file exceeds [split_files_after] characters,
[Shared_config.refresh_ch ()] returns true; if in that case
[Shared_config.debug_ch ()] is called, it will create and return a new file.
If [elapsed_times] is different from [Not_reported], the elapsed time spans are
printed for log subtrees, in the corresponding units with precision up to 1%. The
times include printing out logs, therefore might not be reliable for profiling. In the
runtime creation functions, [elapsed_times] defaults to [Not_reported].
If [print_entry_ids] is true, the [entry_id] identifiers are printed on log headers
with the syntax [{#ID}]; by default they are omitted. If [verbose_entry_ids] is true,
the [entry_id] identifiers are also printed on logged values.
If [global_prefix] is given, the log header messages (and the log closing messages for
the flushing backend) are prefixed with it.
If [table_of_contents_ch] is given or [with_table_of_contents=true], outputs selected
log headers to this channel. The provided file name is used as a prefix for links to
anchors of the log headers. Note that debug runtime builders that take a channel
instead of a file name, will use [global_prefix] instead for the anchor links. The
setting [toc_entry] controls the selection of headers to include in a ToC (it defaults
to [And []], which means including all entries).
[log_level], by default 9, specifies {!Shared_config.init_log_level}. This is the
initial log level. In particular, the header "BEGIN DEBUG SESSION" is only printed if
(initial) [log_level > 0]. *)
(** When using the
{{:http://lukstafi.github.io/ppx_minidebug/ppx_minidebug/Minidebug_runtime/index.html}
[ppx_minidebug]} syntax extension, provide a module called [Debug_runtime] with this
signature in scope of the instrumented code. *)
module type Debug_runtime = sig
val close_log : fname:string -> start_lnum:int -> entry_id:int -> unit
val open_log :
fname:string ->
start_lnum:int ->
start_colnum:int ->
end_lnum:int ->
end_colnum:int ->
message:string ->
entry_id:int ->
log_level:int ->
[ `Diagn | `Debug | `Track ] ->
unit
val open_log_no_source :
message:string ->
entry_id:int ->
log_level:int ->
[ `Diagn | `Debug | `Track ] ->
unit
val log_value_sexp :
?descr:string ->
entry_id:int ->
log_level:int ->
is_result:bool ->
Sexplib0.Sexp.t ->
unit
val log_value_pp :
?descr:string ->
entry_id:int ->
log_level:int ->
pp:(Format.formatter -> 'a -> unit) ->
is_result:bool ->
'a ->
unit
val log_value_show :
?descr:string -> entry_id:int -> log_level:int -> is_result:bool -> string -> unit
val log_value_printbox : entry_id:int -> log_level:int -> PrintBox.t -> unit
val exceeds_max_nesting : unit -> bool
val exceeds_max_children : unit -> bool
val get_entry_id : unit -> int
val max_nesting_depth : int option ref
val max_num_children : int option ref
val global_prefix : string
val snapshot : unit -> unit
(** For [PrintBox] runtimes, outputs the current logging stack to the logging channel.
If the logging channel supports that, an output following a snapshot will rewind the
channel to the state prior to the snapshot. Does nothing for the [Flushing]
runtimes. *)
val description : string
(** A description that should be sufficient to locate where the logs end up. If not
configured explicitly, it will be some combination of: the global prefix, the file
name or "stdout". *)
val no_debug_if : bool -> unit
(** For [PrintBox] runtimes, when passed true within the scope of a log subtree,
disables the logging of this subtree and its subtrees. Does not do anything when
passed false ([no_debug_if false] does {e not} re-enable the log). Does nothing for
the [Flushing] runtimes. *)
val log_level : int ref
(** The runtime log level.
The log levels are used both at compile time, and for the PrintBox runtime. Not
logging at compile time means the corresponding logging code is not generated; not
logging at runtime means the logging state is not updated. *)
end
(** The output is flushed line-at-a-time, so no output should be lost if the traced
program crashes. The logged traces are still indented, but if the values to print are
multi-line, their formatting might be messy. The indentation is also smaller (half of
PrintBox). *)
module Flushing : functor (_ : Shared_config) -> Debug_runtime
val default_html_config : PrintBox_html.Config.t
val default_md_config : PrintBox_md.Config.t
module type PrintBox_runtime = sig
include Debug_runtime
type config = {
mutable hyperlink : [ `Prefix of string | `No_hyperlinks ];
(** If [hyperlink] is [`Prefix prefix], code pointers are rendered as hyperlinks.
When [prefix] is either empty, starts with a dot, or starts with ["http:"] or
["https:"], the link address has the form [sprintf "%s#L%d" fname start_lnum],
allowing browsing in HTML directly. Otherwise, it has the form
[sprintf "%s:%d:%d" fname start_lnum (start_colnum + 1)], intended for
editor-specific prefixes such as ["vscode://file/"].
Note that rendering a link on a node will make the node non-foldable,
therefore it is best to combine [`Prefix prefix] with
[values_first_mode=true]. *)
mutable toc_specific_hyperlink : string option;
(** If provided, overrides [hyperlink] as the prefix used for generating URIs
pointing to anchors in logs. *)
mutable backend :
[ `Text | `Html of PrintBox_html.Config.t | `Markdown of PrintBox_md.Config.t ];
(** If the content is [`Text], logs are generated as monospaced text; for other
settings as html or markdown. *)
mutable boxify_sexp_from_size : int;
(** If positive, [Sexp.t]-based logs with this many or more atoms are converted to
print-boxes before logging. Disabled by default (i.e. negative). *)
mutable highlight_terms : Re.re option;
(** Uses a highlight style for logs on paths ending with a log matching the
regular expression. *)
mutable exclude_on_path : Re.re option;
(** Does not propagate the highlight status from child logs through log headers
matching the given regular expression. *)
mutable prune_upto : int;
(** At depths lower than [prune_upto] (or equal if counting from 1) only ouptputs
highlighted boxes. This makes it simpler to trim excessive logging while still
providing some context. Defaults to [0] -- no pruning. *)
mutable truncate_children : int;
(** If > 0, only the given number of the most recent children is kept at each
node. Defaults to [0] -- keep all (no pruning). *)
mutable values_first_mode : bool;
(** If set to true, does not put the source code location of a computation as a
header of its subtree. Rather, puts the result of the computation as the
header of a computation subtree, if rendered as a single line -- or just the
name, and puts the result near the top. If false, puts the result at the end
of the computation subtree, i.e. preserves the order of the computation. *)
mutable max_inline_sexp_size : int;
(** Maximal size (in atoms) up to which a sexp value can be inlined during
"boxification". *)
mutable max_inline_sexp_length : int;
(** Maximal length (in characters/bytes) up to which a sexp value can be inlined
during "boxification". *)
mutable snapshot_every_sec : float option;
(** If given, output a snapshot of the pending logs when at least the given time
(in seconds) has passed since the previous output. This is only checked at
calls to log values. *)
mutable sexp_unescape_strings : bool;
(** If true, when a value is a sexp atom or is decomposed into a sexp atom by
boxification, it is not printed as a sexp, but the string of the atom is
printed directly. Defaults to [true]. *)
mutable with_toc_listing : bool;
(** If true, outputs non-collapsed trees of ToC entries in the Table of Contents
files. *)
mutable toc_flame_graph : bool;
(** If true, outputs a minimalistic rendering of a flame graph in the Table of
Contents files, with boxes positioned to reflect both the ToC entries
hierarchy and elapsed times for the opening and closing of entries. Not
supported in the [`Text] backend. *)
mutable flame_graph_separation : int;
(** How many pixels a single box, for a log header, is expected to take in a flame
graph. Defaults to [40]. Note: ideally the height of a flame tree should be
calculated automatically, then this setting would disappear. *)
}
val config : config
end
(** The logged traces will be pretty-printed as trees using the `printbox` package. This
logger supports conditionally disabling a particular nesting of the logs, regardless
of where in the nesting level [no_debug_if] is called. *)
module PrintBox : functor (_ : Shared_config) -> PrintBox_runtime
val debug_file :
?time_tagged:time_tagged ->
?elapsed_times:elapsed_times ->
?location_format:location_format ->
?print_entry_ids:bool ->
?verbose_entry_ids:bool ->
?global_prefix:string ->
?split_files_after:int ->
?with_toc_listing:bool ->
?toc_entry:toc_entry_criteria ->
?toc_flame_graph:bool ->
?flame_graph_separation:int ->
?highlight_terms:Re.t ->
?exclude_on_path:Re.t ->
?prune_upto:int ->
?truncate_children:int ->
?for_append:bool ->
?boxify_sexp_from_size:int ->
?max_inline_sexp_length:int ->
?backend:[ `Text | `Html of PrintBox_html.Config.t | `Markdown of PrintBox_md.Config.t ] ->
?hyperlink:string ->
?toc_specific_hyperlink:string ->
?values_first_mode:bool ->
?log_level:int ->
?snapshot_every_sec:float ->
string ->
(module PrintBox_runtime)
(** Creates a PrintBox-based debug runtime configured to output html or markdown to a file
with the given name suffixed with [".log"], [".html"] or [".md"] depending on the
backend. By default the logging will not be time tagged and the file will be created
or erased by this function. The default [boxify_sexp_from_size] value is 50.
Setting [~with_toc_listing:true] or [~toc_flame_graph:true] or both will create an
additional log file, the given name suffixed with ["-toc"] and the corresponding file
name extension. This file will collect selected entries, hyperlinking to anchors in
the main logging file(s).
By default [backend] is [`Markdown PrintBox.default_md_config]. See
{!type:PrintBox.config} for details about PrintBox-specific parameters. See
{!shared_config} for the details about shared parameters. *)
val debug :
?debug_ch:out_channel ->
?time_tagged:time_tagged ->
?elapsed_times:elapsed_times ->
?location_format:location_format ->
?print_entry_ids:bool ->
?verbose_entry_ids:bool ->
?description:string ->
?global_prefix:string ->
?table_of_contents_ch:out_channel ->
?toc_entry:toc_entry_criteria ->
?highlight_terms:Re.t ->
?exclude_on_path:Re.t ->
?prune_upto:int ->
?truncate_children:int ->
?toc_specific_hyperlink:string ->
?values_first_mode:bool ->
?log_level:int ->
?snapshot_every_sec:float ->
unit ->
(module PrintBox_runtime)
(** Creates a PrintBox-based debug runtime for the [`Text] backend. By default it will log
to [stdout] and will not be time tagged.
See {!type:PrintBox.config} for details about PrintBox-specific parameters. See
{!shared_config} for the details about shared parameters. *)
val debug_flushing :
?debug_ch:out_channel ->
?table_of_contents_ch:out_channel ->
?filename:string ->
?time_tagged:time_tagged ->
?elapsed_times:elapsed_times ->
?location_format:location_format ->
?print_entry_ids:bool ->
?verbose_entry_ids:bool ->
?description:string ->
?global_prefix:string ->
?split_files_after:int ->
?with_table_of_contents:bool ->
?toc_entry:toc_entry_criteria ->
?for_append:bool ->
?log_level:int ->
unit ->
(module Debug_runtime)
(** Creates a flushing-based debug runtime. By default it will log to [stdout] and will
not be time tagged. At most one of [debug_ch], [filename] can be provided. Adds the
suffix [".log"] to the file name if [filename] is given.
See {!shared_config} for the details about shared parameters. *)
val forget_printbox : (module PrintBox_runtime) -> (module Debug_runtime)
(** Upcasts the runtime. *)
val sexp_of_lazy_t : ('a -> Sexplib0.Sexp.t) -> 'a lazy_t -> Sexplib0.Sexp.t
(** Unlike [Lazy.sexp_of_t] available in the [Base] library, does not force the lazy
value, only converts it if it's already computed and non-exception. *)