# `PtcRunner.TraceLog.Collector`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/trace_log/collector.ex#L1)

GenServer that collects trace events and writes them to a JSONL file.

The Collector holds an open file handle and writes events as they arrive.
It manages a monotonic `seq` counter for deterministic event ordering and
deduplicates `agent.config` events by `agent_id`.

Events are written in v2 format with `schema_version: 2`.

# `t`

```elixir
@type t() :: %PtcRunner.TraceLog.Collector{
  emitted_agent_ids: MapSet.t(String.t()),
  file: File.io_device() | nil,
  header: term(),
  meta: map(),
  parent_ref: reference() | nil,
  path: String.t(),
  seq: non_neg_integer(),
  start_time: integer(),
  trace_id: String.t(),
  write_errors: non_neg_integer()
}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `max_event_bytes`

```elixir
@spec max_event_bytes() :: pos_integer()
```

Returns the event byte cap applied before enqueueing and writing events.

# `max_mailbox_len`

```elixir
@spec max_mailbox_len() :: non_neg_integer()
```

Returns the collector mailbox length at which new events are shed.

# `path`

```elixir
@spec path(GenServer.server()) :: String.t()
```

Returns the file path for this collector's trace output.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts a new Collector process.

## Options

  * `:path` - File path for the JSONL output. Defaults to a timestamped file in the
    directory configured by `Application.get_env(:ptc_runner, :trace_dir)`, or CWD if unset.
  * `:trace_id` - Unique identifier for this trace. Defaults to a random hex string.
  * `:trace_kind` - Discriminator for the type of trace (e.g., `"benchmark"`, `"analysis"`, `"planning"`).
  * `:producer` - Identifier for the component that created this trace (e.g., `"demo.benchmark"`).
  * `:trace_label` - Human-readable label for this trace (e.g., test case name).
  * `:model` - LLM model used for this trace.
  * `:query` - The input query or question for this trace.
  * `:meta` - Producer-specific metadata to include under `data`. Defaults to `%{}`.

## Examples

    {:ok, collector} = Collector.start_link(
      path: "/tmp/trace.jsonl",
      trace_kind: "benchmark",
      producer: "demo.benchmark",
      query: "How many products?"
    )

# `stop`

```elixir
@spec stop(GenServer.server()) :: {:ok, String.t(), non_neg_integer()}
```

Stops the Collector and closes the file.

Returns the path to the trace file and the number of write errors.

## Examples

    {:ok, path, errors} = Collector.stop(collector)

# `trace_id`

```elixir
@spec trace_id(GenServer.server()) :: String.t()
```

Returns the trace_id for this collector.

# `write_event`

```elixir
@spec write_event(GenServer.server(), map()) :: :ok
```

Writes an event map to the trace file.

The event is assigned a monotonic `seq` number server-side, then encoded
to JSON and written. If the event carries an `agent_id` with an
`agent_config` in its data, the collector will emit an `agent.config`
event first (deduplicated by agent_id).

This is an asynchronous operation that never blocks the caller.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
