Module Runtime_events

Runtime events - ring buffer-based runtime tracing

This module enables users to enable and subscribe to tracing events from the Garbage Collector and other parts of the OCaml runtime. This can be useful for diagnostic or performance monitoring purposes. This module can be used to subscribe to events for the current process or external processes asynchronously.

When enabled (either via setting the OCAML_RUNTIME_EVENTS_START environment variable or calling Runtime_events.start) a file with the pid of the process and extension .events will be created. By default this is in the current directory but can be over-ridden by the OCAML_RUNTIME_EVENTS_DIR environment variable. Each domain maintains its own ring buffer in a section of the larger file into which it emits events.

There is additionally a set of C APIs in runtime_events.h that can enable zero-impact monitoring of the current process or bindings for other languages.

The runtime events system's behaviour can be controlled by the following environment variables:

type runtime_counter =
  1. | EV_C_FORCE_MINOR_ALLOC_SMALL
  2. | EV_C_FORCE_MINOR_MAKE_VECT
  3. | EV_C_FORCE_MINOR_SET_MINOR_HEAP_SIZE
  4. | EV_C_FORCE_MINOR_MEMPROF
  5. | EV_C_MINOR_PROMOTED
  6. | EV_C_MINOR_ALLOCATED
  7. | EV_C_REQUEST_MAJOR_ALLOC_SHR
  8. | EV_C_REQUEST_MAJOR_ADJUST_GC_SPEED
  9. | EV_C_REQUEST_MINOR_REALLOC_REF_TABLE
  10. | EV_C_REQUEST_MINOR_REALLOC_EPHE_REF_TABLE
  11. | EV_C_REQUEST_MINOR_REALLOC_CUSTOM_TABLE
  12. | EV_C_MAJOR_HEAP_POOL_WORDS
    (*

    Total words in a Domain's major heap pools. This is the sum of unallocated and live words in each pool.

    • since 5.1
    *)
  13. | EV_C_MAJOR_HEAP_POOL_LIVE_WORDS
    (*

    Current live words in a Domain's major heap pools.

    • since 5.1
    *)
  14. | EV_C_MAJOR_HEAP_LARGE_WORDS
    (*

    Total words of a Domain's major heap large allocations. A large allocation is an allocation larger than the largest sized pool.

    • since 5.1
    *)
  15. | EV_C_MAJOR_HEAP_POOL_FRAG_WORDS
    (*

    Words in a Domain's major heap pools lost to fragmentation. This is due to there not being a pool with the exact size of an allocation and a larger sized pool needing to be used.

    • since 5.1
    *)
  16. | EV_C_MAJOR_HEAP_POOL_LIVE_BLOCKS
    (*

    Live blocks of a Domain's major heap pools.

    • since 5.1
    *)
  17. | EV_C_MAJOR_HEAP_LARGE_BLOCKS
    (*

    Live blocks of a Domain's major heap large allocations.

    • since 5.1
    *)

The type for counter events emitted by the runtime

type runtime_phase =
  1. | EV_EXPLICIT_GC_SET
  2. | EV_EXPLICIT_GC_STAT
  3. | EV_EXPLICIT_GC_MINOR
  4. | EV_EXPLICIT_GC_MAJOR
  5. | EV_EXPLICIT_GC_FULL_MAJOR
  6. | EV_EXPLICIT_GC_COMPACT
  7. | EV_MAJOR
  8. | EV_MAJOR_SWEEP
  9. | EV_MAJOR_MARK_ROOTS
  10. | EV_MAJOR_MARK
  11. | EV_MINOR
  12. | EV_MINOR_LOCAL_ROOTS
  13. | EV_MINOR_FINALIZED
  14. | EV_EXPLICIT_GC_MAJOR_SLICE
  15. | EV_FINALISE_UPDATE_FIRST
  16. | EV_FINALISE_UPDATE_LAST
  17. | EV_INTERRUPT_REMOTE
  18. | EV_MAJOR_EPHE_MARK
  19. | EV_MAJOR_EPHE_SWEEP
  20. | EV_MAJOR_FINISH_MARKING
  21. | EV_MAJOR_GC_CYCLE_DOMAINS
  22. | EV_MAJOR_GC_PHASE_CHANGE
  23. | EV_MAJOR_GC_STW
  24. | EV_MAJOR_MARK_OPPORTUNISTIC
  25. | EV_MAJOR_SLICE
  26. | EV_MAJOR_FINISH_CYCLE
  27. | EV_MINOR_CLEAR
  28. | EV_MINOR_FINALIZERS_OLDIFY
  29. | EV_MINOR_GLOBAL_ROOTS
  30. | EV_MINOR_LEAVE_BARRIER
  31. | EV_STW_API_BARRIER
  32. | EV_STW_HANDLER
  33. | EV_STW_LEADER
  34. | EV_MAJOR_FINISH_SWEEPING
  35. | EV_MINOR_FINALIZERS_ADMIN
  36. | EV_MINOR_REMEMBERED_SET
  37. | EV_MINOR_REMEMBERED_SET_PROMOTE
  38. | EV_MINOR_LOCAL_ROOTS_PROMOTE
  39. | EV_DOMAIN_CONDITION_WAIT
  40. | EV_DOMAIN_RESIZE_HEAP_RESERVATION

The type for span events emitted by the runtime

type lifecycle =
  1. | EV_RING_START
  2. | EV_RING_STOP
  3. | EV_RING_PAUSE
  4. | EV_RING_RESUME
  5. | EV_FORK_PARENT
  6. | EV_FORK_CHILD
  7. | EV_DOMAIN_SPAWN
  8. | EV_DOMAIN_TERMINATE

Lifecycle events for the ring itself

val lifecycle_name : lifecycle -> string

Return a string representation of a given lifecycle event type

val runtime_phase_name : runtime_phase -> string

Return a string representation of a given runtime phase event type

val runtime_counter_name : runtime_counter -> string

Return a string representation of a given runtime counter type

type cursor

Type of the cursor used when consuming

module Timestamp : sig ... end
module Type : sig ... end
module User : sig ... end

User events is a way for libraries to provide runtime events that can be consumed by other tools. These events can carry known data types or custom values. The current maximum number of user events is 8192.

module Callbacks : sig ... end
val start : unit -> unit

start () will start the collection of events in the runtime if not already started.

Events can be consumed by creating a cursor with create_cursor and providing a set of callbacks to be called for each type of event.

val pause : unit -> unit

pause () will pause the collection of events in the runtime. Traces are collected if the program has called Runtime_events.start () or the OCAML_RUNTIME_EVENTS_START environment variable has been set.

val resume : unit -> unit

resume () will resume the collection of events in the runtime. Traces are collected if the program has called Runtime_events.start () or the OCAML_RUNTIME_EVENTS_START environment variable has been set.

val create_cursor : (string * int) option -> cursor

create_cursor path_pid creates a cursor to read from an runtime_events. Cursors can be created for runtime_events in and out of process. A runtime_events ring-buffer may have multiple cursors reading from it at any point in time and a program may have multiple cursors open concurrently (for example if multiple consumers want different sets of events). If path_pid is None then a cursor is created for the current process. Otherwise the pair contains a string path to the directory that contains the pid.events file and int pid for the runtime_events of an external process to monitor.

val free_cursor : cursor -> unit

Free a previously created runtime_events cursor

val read_poll : cursor -> Callbacks.t -> int option -> int

read_poll cursor callbacks max_option calls the corresponding functions on callbacks for up to max_option events read off cursor's runtime_events and returns the number of events read.