nemo_gym.telemetry
nemo_gym.telemetry
NeMo Gym telemetry: optional OpenTelemetry instrumentation via nemo-lens.
Importing this package never requires nemo-lens. Install it with
uv sync --extra telemetry and switch it on with a telemetry: block or
NEMO_LENS_ENABLED=1; with either missing, every instrumentation site in nemo_gym
is a ~0-cost no-op.
Public surface
TelemetryConfig— thetelemetry:config block.GymSpanGroup— Gym span groups and presets.configure_telemetry_env— orchestrator side; hands the settings to spawned server processes through the environment.init_telemetry/get_telemetry/shutdown_telemetry— per-process lifecycle.
Instrumentation primitives (managed_span / span_cm / trace_fn /
is_span_group_enabled / safe_set_span_attributes) come from
nemo_gym.telemetry._fallbacks, which resolves to the real nemo-lens
implementations when it is installed and to no-op stubs when it is not.
See nemo_gym/telemetry/README.md for the design, and
fern/versions/latest/pages/observability/ for user documentation.
Submodules
nemo_gym.telemetry.confignemo_gym.telemetry.connection_poolnemo_gym.telemetry.contribnemo_gym.telemetry.endpointsnemo_gym.telemetry.gym_metricsnemo_gym.telemetry.memorynemo_gym.telemetry.metricsnemo_gym.telemetry.setupnemo_gym.telemetry.span_groupsnemo_gym.telemetry.spans
Package Contents
Classes
Functions
Data
API
Span group names for NeMo Gym instrumentation.
Agent-server /run and /v1/responses spans.
Outbound spans around nemo_gym.server_utils.request — Gym’s single aiohttp
egress point. The egress half of cross-process propagation: injects traceparent
into the outgoing headers.
The whole gym eval / rollout-collection run, driver side. Shares its name with
NeMo-RL’s run-level group, so one spec entry selects both.
Model-server /v1/chat/completions, /v1/responses and /v1/messages spans.
Rollout collection spans (one per task attempt, driver side).
Sandbox provider create/exec/delete spans.
Inbound FastAPI request spans on every Gym server process. The ingress half of
cross-process propagation: adopts an inbound traceparent as the span’s parent.
Resources-server /verify spans.
Resolve a span_groups spec against every group registered in this process.
Entries that name nothing registered are dropped rather than raised: the library
that owns them may not be imported in this process. nemo-lens logs a warning naming
them when the spec is applied in setup_telemetry.
Raises:
RuntimeError: nemo-lens is not installed, so there is nothing to resolve.
Bases: BaseModel
Periodic host and logical-server memory sampling.
Collect host memory and every server process tree.
Seconds between samples.
Bases: BaseModel
OpenTelemetry / nemo-lens configuration for NeMo Gym.
Telemetry is optional twice over: it activates only when enabled is true and
nemo-lens is installed (uv sync --extra telemetry). When either is missing every
instrumentation site in nemo_gym degrades to a ~0-cost no-op and Gym behaves
exactly as it does today.
Master switch. When false, all instrumentation is a ~0-cost no-op.
Exporter backend: otlp | console. console writes one JSON object per
line to stdout, which is what the local validation flow greps.
Use nemo-lens’s aiohttp auto-instrumentation for outbound calls, which produces a
CLIENT span per request in addition to injecting traceparent.
When false, nemo_gym.server_utils.request still injects traceparent manually,
so cross-process traces stay joined — you lose the client-side span, not the trace.
Turn it off if the per-request patching cost matters at very high concurrency.
Bridge Python logging to OTel logs, exported with trace correlation.
Sample each Gym-managed server process tree and emit memory metrics.
Emit metric instruments (the gym.* histograms/gauges plus the FastAPI
instrumentor’s http.server.*).
OTEL_EXPORTER_OTLP_ENDPOINT for the otlp exporter, e.g.
https://api.honeycomb.io. Optional: the standard env var still works and always
wins (setdefault), so any OTLP-compatible backend or collector that expects the
raw env var keeps working unchanged. Setting it here just means a run’s destination is
committed with the rest of the config instead of exported by hand every time.
OTEL_EXPORTER_OTLP_HEADERS, e.g. x-honeycomb-team=.... Prefer
${oc.env:MY_API_KEY} interpolation for the secret portion so the raw credential
does not live in a committed YAML file.
OTEL_EXPORTER_OTLP_PROTOCOL: grpc (the OTel SDK default) or
http/protobuf.
Correlates every process of one gym env start / gym env test invocation.
Generated in the orchestrator and inherited by the servers when unset.
service.name reported to the backend.
Passed through the standard OTEL_SERVICE_NAME env var, not through
instrument_fastapi(service_name=...) — that parameter is accepted and ignored by
nemo-lens at the pinned commit (contrib/fastapi.py).
Each server process appends its own Gym server name, so a run yields
nemo-gym/example_single_tool_call, nemo-gym/policy_model, and so on rather
than three indistinguishable nemo-gym services. Set service_name_per_server
to false to opt out.
Suffix service_name with each server’s Gym config name.
On by default because Gym runs several processes that would otherwise share one
service.name, which makes a backend’s service map useless. The unsuffixed name
stays available as the nemo.gym.service_group resource attribute.
Span-group spec: a preset (default | per_rollout | all) or a
comma-separated list of group names (e.g. "default,sandbox"). See
GymSpanGroup. An unknown name is logged as a
warning and ignored rather than rejected.
Emit trace spans.
Translate the telemetry: block into env vars for spawned server processes.
Call once in the orchestrator, before spawning any server. os.environ is what
Popen snapshots into each child, so this is how a YAML setting reaches a server
process that shares nothing else with its parent.
Uses setdefault throughout: a raw NEMO_GYM_OTEL_* / NEMO_LENS_* /
OTEL_SERVICE_NAME / OTEL_EXPORTER_OTLP_* set by the user always wins over YAML.
Returns the run id shared by every process in this run, or None when telemetry is
disabled.
Return this process’s telemetry handle, or None if uninitialised/disabled.
Initialise this process’s telemetry. Call once per process; idempotent.
Reads the NEMO_GYM_OTEL_* environment that configure_telemetry_env put in
place, so a server process needs no config file access to agree with its siblings.
Parameters:
This server’s Gym config name (e.g. example_single_tool_call).
Used to disambiguate service.name across the fleet.
resources_servers | responses_api_agents |
responses_api_models, or orchestrator for the CLI.
Extra process-lifetime attributes to merge.
Returns: Optional[TelemetryHandle]
class:TelemetryHandle, or None when nemo-lens is absent or telemetry is
Always returns False.
True when telemetry is switched on in this process’s environment.
Cheap enough to call before doing setup work, and importantly it does not import nemo-lens — a process with telemetry off never pays for the lens import at all.
Return the effective metrics switch after Gym/Lens env precedence.
No-op context manager — yields None.
Resolve memory profiling after raw environment variables take precedence.
No-op.
Flush and shut down this process’s telemetry providers.
Idempotent — TelemetryHandle.shutdown guards against a second call, and Gym
reaches this from more than one terminal path. A no-op when Gym reused providers that
another library set up. Never raises.
No-op context manager — yields None.
Build a TelemetryConfig from Gym’s merged global config dict.
Reads the optional top-level telemetry: block. A run that never mentions
telemetry gets the all-defaults config, which is disabled.
No-op decorator — returns the function unchanged.