> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veadk.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# In-memory exporter

`InMemoryExporter` keeps span data in process memory instead of reporting it to an external platform. It organizes spans by `session_id`, which is useful for local debugging, testing, and dumping a session's trace data to a JSON file for offline analysis.

## When to use

* Local development and debugging of agent execution flows;
* Verifying spans in unit or integration tests;
* Offline environments without external platform connectivity, where you need to retain and analyze trace data locally.

## Automatic management

`InMemoryExporter` is created and managed automatically by `OpentelemetryTracer` and records completed, sampled spans. It therefore **cannot** be added explicitly to the `exporters` list of `OpentelemetryTracer`, or initialization fails.

```python lines theme={null}
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer

# The in-memory exporter is attached automatically even with no external exporters
tracer = OpentelemetryTracer(exporters=[])
```

## Usage

After a session run finishes, call the tracer's `dump` method to export that session's spans to a local JSON file:

```python title="app.py" lines theme={null}
import asyncio
from pathlib import Path

from veadk import Agent, Runner
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer

tracer = OpentelemetryTracer()
agent = Agent(name="trace_demo", tracers=[tracer])
runner = Runner(agent=agent, app_name="trace_demo", user_id="demo-user")
response = asyncio.run(
    runner.run("Explain the purpose of an agent in one sentence", session_id="demo-session")
)
print(response)
Path("traces").mkdir(exist_ok=True)
path = tracer.dump(user_id="demo-user", session_id="demo-session", path="traces")
print(path)
```

## Parameters

### Constructor parameters

`InMemoryExporter` usually does not need to be constructed by hand; its constructor parameters are:

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `name` | `str` | `inmemory_exporter` | Exporter instance identifier. |

### `dump` method parameters

`OpentelemetryTracer.dump` relies on spans retained by the in-memory exporter, with the following parameters:

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `user_id` | `str` | `unknown_user_id` | User identifier, used to organize and name the dump file. |
| `session_id` | `str` | `unknown_session_id` | Session identifier, used to filter spans of that session. |
| `path` | `str` | Agent directory | Output directory; it must already exist because `dump` does not create it. |

The dump file is named like `{name}_{user_id}_{session_id}_{trace_id}.json`, and its content is a list of spans, each containing the name, `span_id`, `trace_id`, start/end times, attributes, and parent span.

<Note>
  Memory usage grows with the number of spans, so long-running processes should watch memory growth. Session-level filtering relies on a correctly configured `session_id`; `dump` first force-exports all pending spans, then filters by `session_id` before writing the file.
</Note>

## Checking the export

Complete [model configuration](/productions/veadk/preview/en/components/agent/model), save the example as `app.py`, and run `python app.py`. The printed file path should exist, and its JSON list should contain spans from this model call

In-memory data is lost when the process exits. Session filtering relies on session identifiers recorded by model-call spans. The file can be empty if no relevant model span was recorded, sampling omitted the data, or the session ID differs. `user_id` names the output file; it does not filter spans or enforce access control
