> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server.

# nemo_gym.telemetry.spans

A CLIENT-kind span, which nemo-lens cannot currently produce.

`nemo.lens.helpers.managed_span` calls `tracer.start_span(name)` with no `kind`
argument and exposes no way to pass one, so every span it creates is `SpanKind.INTERNAL`.
For spans *inside* a service that is right. For Gym's outbound calls it is not: an
INTERNAL span on a cross-service hop means a backend cannot tell that the agent server
called the model server, so Jaeger/Tempo/Honeycomb service maps lose the edge and
client-vs-server latency attribution stops working.

Gym is pinned to nemo-lens `b85578fc`, so rather than change lens this module creates
that one span directly against the OTel API. Adding a `kind` parameter to
`managed_span` is the proper fix and is raised as a decision in the PR body; when it
lands, delete this module and pass `kind=` instead.

Everything else is deliberately identical to `managed_span`: context attach/detach,
exception recording, and an unconditional `end()` in `finally`.

**Callers must gate on the span group themselves.** Nothing here checks it, so that a
disabled site does not pay for entering a context manager at all
(`kb/knowledge/conventions/hot-path-overhead.md`).

## Module Contents

### Functions

| Name                                                   | Description                                                              |
| ------------------------------------------------------ | ------------------------------------------------------------------------ |
| [`client_span`](#nemo_gym-telemetry-spans-client_span) | Start a `SpanKind.CLIENT` span, attach it as current, and always end it. |

### API

```python
nemo_gym.telemetry.spans.client_span(
    name: str,
    tracer: typing.Any = None,
    attributes: typing.Any = {}
)
```

Start a `SpanKind.CLIENT` span, attach it as current, and always end it.

**Parameters:**

**`name`** `str`

Span name.

---

**`tracer`** `Any` — default: None

OTel tracer; defaults to the globally registered one.

---

**`**attributes`** `Any` — default: \{}

Set on the span via `safe_set_span_attributes`, so non-scalar
values are dropped and sensitive keys are redacted rather than exported.

---