Table of Contents

Class TraceRecordHeader

Namespace
Typhon.Profiler
Assembly
Typhon.Profiler.dll

Wire-format layout constants and encode/decode helpers for the common header (12 B, present on every record) and the span header extension (25 B, present on every span record, optionally followed by a 16 B trace context).

public static class TraceRecordHeader
Inheritance
TraceRecordHeader
Inherited Members

Remarks

Common header layout (12 B):

offset 0..1    u16  Size             // total record size in bytes, including these 2 bytes. 0 = empty ring slot. 0xFFFF = wrap sentinel.
offset 2       u8   Kind             // TraceEventKind discriminant
offset 3       u8   ThreadSlot       // slot index 0..255 (from ThreadSlotRegistry)
offset 4..11   i64  StartTimestamp   // Stopwatch.GetTimestamp() at begin (span) or emit (instant)

Span header extension (25 B), appended after the common header for IsSpan(TraceEventKind) kinds:

offset 12..19  i64  DurationTicks    // Stopwatch.GetTimestamp() delta at end; 0 allowed for open/crashed spans
offset 20..27  u64  SpanId           // this span's unique ID (0 disallowed for real spans)
offset 28..35  u64  ParentSpanId     // enclosing Typhon span's SpanId, or 0 for top-level
offset 36      u8   SpanFlags        // bit 0 = has trace context (next 16 B are TraceIdHi + TraceIdLo)

Optional trace context (16 B): only present when SpanFlagsHasTraceContext bit is set in SpanFlags:

offset 37..44  u64  TraceIdHi        // upper 8 B of Activity.TraceId
offset 45..52  u64  TraceIdLo        // lower 8 B of Activity.TraceId

All multi-byte integers are little-endian — BinaryPrimitives with explicit LittleEndian variants. No host-endian reads/writes anywhere in the wire format so .typhon-trace files are portable across ARM/x64.

Fields

CommonHeaderSize

Common header size — 12 bytes.

public const int CommonHeaderSize = 12

Field Value

int

EmptySlot

Reserved "empty slot" marker in the Size field — consumer treats this position as not-yet-committed.

public const ushort EmptySlot = 0

Field Value

ushort

MaxSpanHeaderSize

Span record header with trace context (common + span extension + trace context) = 53 B.

public const int MaxSpanHeaderSize = 53

Field Value

int

MinSpanHeaderSize

Span record header with no trace context (common + span extension) = 37 B.

public const int MinSpanHeaderSize = 37

Field Value

int

SourceLocationIdSize

Optional source-location-id size — 2 bytes (u16 LE), appended after the (optional) trace context when the flag is set.

public const int SourceLocationIdSize = 2

Field Value

int

SpanFlagsHasSourceLocation

SpanFlags bit 1 — set when the record carries a 2-byte source-location id (the compile-time SourceLocationGenerator site index) immediately after the optional trace context. See claude/design/Profiler/10-profiler-source-attribution.md.

public const byte SpanFlagsHasSourceLocation = 2

Field Value

byte

SpanFlagsHasTraceContext

SpanFlags bit 0 — set when the record includes a 16-byte trace context after the span header extension.

public const byte SpanFlagsHasTraceContext = 1

Field Value

byte

SpanHeaderExtensionSize

Span header extension size — 25 bytes, appended after the common header for span records.

public const int SpanHeaderExtensionSize = 25

Field Value

int

TraceContextSize

Optional trace context size — 16 bytes, appended after the span header extension if the flags bit is set.

public const int TraceContextSize = 16

Field Value

int

WrapSentinel

Reserved "wrap to start" sentinel in the Size field — consumer resets its read pointer to the buffer start when it sees this.

public const ushort WrapSentinel = 65535

Field Value

ushort

Methods

ReadCommonHeader(ReadOnlySpan<byte>, out ushort, out TraceEventKind, out byte, out long)

Parse the 12-byte common header at the start of source.

public static void ReadCommonHeader(ReadOnlySpan<byte> source, out ushort size, out TraceEventKind kind, out byte threadSlot, out long startTimestamp)

Parameters

source ReadOnlySpan<byte>
size ushort
kind TraceEventKind
threadSlot byte
startTimestamp long

ReadSourceLocationId(ReadOnlySpan<byte>)

Parse the optional 2-byte source-location id at source. Caller has already read SpanFlagsHasSourceLocation from SpanFlags and is positioning source just past the optional trace context.

public static ushort ReadSourceLocationId(ReadOnlySpan<byte> source)

Parameters

source ReadOnlySpan<byte>

Returns

ushort

ReadSpanHeaderExtension(ReadOnlySpan<byte>, out long, out ulong, out ulong, out byte)

Parse the 25-byte span header extension at source.

public static void ReadSpanHeaderExtension(ReadOnlySpan<byte> source, out long durationTicks, out ulong spanId, out ulong parentSpanId, out byte spanFlags)

Parameters

source ReadOnlySpan<byte>
durationTicks long
spanId ulong
parentSpanId ulong
spanFlags byte

ReadTraceContext(ReadOnlySpan<byte>, out ulong, out ulong)

Parse the optional 16-byte trace context at source.

public static void ReadTraceContext(ReadOnlySpan<byte> source, out ulong traceIdHi, out ulong traceIdLo)

Parameters

source ReadOnlySpan<byte>
traceIdHi ulong
traceIdLo ulong

SourceLocationIdOffset(bool)

Byte offset of the optional source-location id within a span record: 37 with no trace context, 53 with. Caller passes this to WriteSourceLocationId(Span<byte>, ushort) / ReadSourceLocationId(ReadOnlySpan<byte>) after slicing the destination/source span at the offset.

public static int SourceLocationIdOffset(bool hasTraceContext)

Parameters

hasTraceContext bool

Returns

int

SpanHeaderSize(bool)

Total header size for a span record: 37 B if hasTraceContext is false, 53 B if true.

public static int SpanHeaderSize(bool hasTraceContext)

Parameters

hasTraceContext bool

Returns

int

SpanHeaderSize(bool, bool)

Total header size for a span record including the optional source-location id. Adds 2 bytes when hasSourceLocation is true.

public static int SpanHeaderSize(bool hasTraceContext, bool hasSourceLocation)

Parameters

hasTraceContext bool
hasSourceLocation bool

Returns

int

WriteCommonHeader(Span<byte>, ushort, TraceEventKind, byte, long)

Write the 12-byte common header at the start of destination.

public static void WriteCommonHeader(Span<byte> destination, ushort size, TraceEventKind kind, byte threadSlot, long startTimestamp)

Parameters

destination Span<byte>
size ushort
kind TraceEventKind
threadSlot byte
startTimestamp long

WriteSourceLocationId(Span<byte>, ushort)

Write the optional 2-byte source-location id at destination. Caller passes the span starting at the offset just past the optional trace context (37 with no trace context, 53 with). Set SpanFlagsHasSourceLocation in SpanFlags when calling this.

public static void WriteSourceLocationId(Span<byte> destination, ushort sourceLocationId)

Parameters

destination Span<byte>
sourceLocationId ushort

WriteSpanHeaderExtension(Span<byte>, long, ulong, ulong, byte)

Write the 25-byte span header extension at destination (caller passes the span starting at offset 12 of the record).

public static void WriteSpanHeaderExtension(Span<byte> destination, long durationTicks, ulong spanId, ulong parentSpanId, byte spanFlags)

Parameters

destination Span<byte>
durationTicks long
spanId ulong
parentSpanId ulong
spanFlags byte

WriteTraceContext(Span<byte>, ulong, ulong)

Write the optional 16-byte trace context at destination (caller passes the span starting at offset 37 of the record).

public static void WriteTraceContext(Span<byte> destination, ulong traceIdHi, ulong traceIdLo)

Parameters

destination Span<byte>
traceIdHi ulong
traceIdLo ulong