...

Text file src/internal/trace/tracev2/EXPERIMENTS.md

Documentation: internal/trace/tracev2

     1# Trace experiments
     2
     3Execution traces allow for trialing new events on an experimental basis via
     4trace experiments.
     5This document is a guide that explains how you can define your own trace
     6experiments.
     7
     8Note that if you're just trying to do some debugging or perform some light
     9instrumentation, then a trace experiment is way overkill.
    10Use `runtime/trace.Log` instead.
    11Even if you're just trying to create a proof-of-concept for a low-frequency
    12event, `runtime/trace.Log` will probably be easier overall if you can make
    13it work.
    14
    15Consider a trace experiment if:
    16- The volume of new trace events will be relatively high, and so the events
    17  would benefit from a more compact representation (creating new tables to
    18  deduplicate data, taking advantage of the varint representation, etc.).
    19- It's not safe to call `runtime/trace.Log` (or its runtime equivalent) in
    20  the contexts you want to generate an event (for example, for events about
    21  timers).
    22
    23## Defining a new experiment
    24
    25To define a new experiment, modify `internal/trace/tracev2` to define a
    26new `Experiment` enum value.
    27
    28An experiment consists of two parts: timed events and experimental batches.
    29Timed events are events like any other and follow the same format.
    30They are easier to order and require less work to make use of.
    31Experimental batches are essentially bags of bytes that correspond to
    32an entire trace generation.
    33What they contain and how they're interpreted is totally up to you, but
    34they're most often useful for tables that your other events can refer into.
    35For example, the AllocFree experiment uses them to store type information
    36that allocation events can refer to.
    37
    38### Defining new events
    39
    401. Define your new experiment event types (by convention, experimental events
    41   types start at ID 127, so look for the `const` block defining events
    42   starting there).
    432. Describe your new events in `specs`.
    44   Use the documentation for `Spec` to write your new specs, and check your
    45   work by running the tests in the `internal/trace/tracev2` package.
    46   If you wish for your event argument to be interpreted in a particular
    47   way, follow the naming convention in
    48   `src/internal/trace/tracev2/spec.go`.
    49   For example, if you intend to emit a string argument, make sure the
    50   argument name has the suffix `string`.
    513. Add ordering and validation logic for your new events to
    52   `src/internal/trace/order.go` by listing handlers for those events in
    53   the `orderingDispatch` table.
    54   If your events are always emitted in a regular user goroutine context,
    55   then the handler should be trivial and just validate the scheduling
    56   context to match userGoReqs.
    57   If it's more complicated, see `(*ordering).advanceAllocFree` for a
    58   slightly more complicated example that handles events from a larger
    59   variety of execution environments.
    60   If you need to encode a partial ordering, look toward the scheduler
    61   events (names beginning with `Go`) or just ask someone for help.
    624. Add your new events to the `tracev2Type2Kind` table in
    63   `src/internal/trace/event.go`.
    64
    65## Emitting data
    66
    67### Emitting your new events
    68
    691. Define helper methods on `runtime.traceEventWriter` for emitting your
    70   events.
    712. Instrument the runtime with calls to these helper methods.
    72   Make sure to call `traceAcquire` and `traceRelease` around the operation
    73   your event represents, otherwise it will not be emitted atomically with
    74   that operation completing, resulting in a potentially misleading trace.
    75
    76### Emitting experimental batches
    77
    78To emit experimental batches, use the `runtime.unsafeTraceExpWriter` to
    79write experimental batches associated with your experiment.
    80Heed the warnings and make sure that while you write them, the trace
    81generation cannot advance.
    82Note that each experiment can only have one distinguishable set of
    83batches.
    84
    85## Recovering experimental data
    86
    87### Recovering experimental events from the trace
    88
    89Experimental events will appear in the event stream as an event with the
    90`EventExperimental` `Kind`.
    91Use the `Experimental` method to collect the raw data inserted into the
    92trace.
    93It's essentially up to you to interpret the event from here.
    94I recommend writing a thin wrapper API to present a cleaner interface if you
    95so desire.
    96
    97### Recovering experimental batches
    98
    99Parse out all the experimental batches from `Sync` events as they come.
   100These experimental batches are all for the same generation as all the
   101experimental events up until the next `Sync` event.

View as plain text