nemoguardrails.telemetry

View as Markdown

Module Contents

Classes

NameDescription
DeploymentTypeEnumHow the NeMo product was invoked.
EventTypeEnum-
GuardrailsUsageEventUsage event for NeMo Guardrails.
NemoSourceEnumThe NeMo product that created the event.
RailsEngineEnum-
TelemetryEventAbstract base for telemetry events.

Functions

NameDescription
_build_eventWrap a TelemetryEvent in the inner event dict for the NVIDIA envelope.
_build_nvidia_payloadBuild the outer NVIDIA telemetry envelope that wraps one or more events.
_collect_usage_dataCollect anonymous usage data into a GuardrailsUsageEvent.
_detect_builtin_featuresDetect which built-in NeMo Guardrails library features are active.
_flow_file_name-
_get_audit_fileReturn the local audit JSONL path, honoring test overrides.
_get_config_dirReturn the telemetry config directory, honoring test overrides.
_get_do_not_track_fileReturn the do-not-track marker path, honoring test overrides.
_get_heartbeat_interval_sReturn the heartbeat interval, falling back safely on bad env values.
_get_iso_timestampFormat a Unix timestamp as an ISO 8601 UTC string with millisecond precision.
_get_usage_stats_server_urlReturn the telemetry server URL, honoring runtime env overrides.
_get_version-
_heartbeat_loopRun the heartbeat loop forever in a daemon thread.
_is_custom_flow-
_is_usage_stats_enabledCheck whether usage reporting is enabled.
_is_v2_library_flow-
_normalize_builtin_feature_idReturn the documented feature id for a RailsConfigData field.
_reset_for_forkClear module state in a forked child so it starts a fresh session.
_rotate_audit_fileRotate the local audit file when it exceeds the size cap.
_safe_home_dirReturn the user’s home directory without raising at import time.
_send_one_eventWrite a single event to the audit file and POST it.
_send_reportPOST a single telemetry event to the configured server.
_start_daemon_threadStart a daemon thread and report whether startup succeeded.
_write_audit_fileAppend a payload to the local audit file as a JSON line.
report_usageEmit one anonymous usage event for the given config.
set_deployment_typeSet the deployment type that subsequent report_usage calls will use.

Data

_AUDIT_FILE

_AUDIT_FILE_MAX_BYTES

_COLANG_V2_LIBRARY_DIR

_CONFIG_BUILTIN_FEATURE_ALIASES

_CONFIG_DIR

_DO_NOT_TRACK_FILE

_HEARTBEAT_INTERVAL_S

_KNOWN_BUILTIN_FLOWS

_NVIDIA_CLIENT_ID

_NVIDIA_EVENT_PROTOCOL

_NVIDIA_EVENT_SYS_VER

_USAGE_STATS_SERVER

_deployment_type_override

_heartbeat_started

_lock

_session_uuid

log

API

class nemoguardrails.telemetry.DeploymentTypeEnum

Bases: enum.Enum

How the NeMo product was invoked.

Mirrors the shared nemo-telemetry definition. library covers direct LLMRails / Guardrails use in user code, api is the FastAPI server, cli is the interactive chat command. sdk and nmp are inherited from the shared enum and are valid values guardrails does not produce itself.

API
= 'api'
CLI
= 'cli'
LIBRARY
= 'library'
NMP
= 'nmp'
SDK
= 'sdk'
UNDEFINED
= 'undefined'
class nemoguardrails.telemetry.EventTypeEnum

Bases: enum.Enum

HEARTBEAT
= 'heartbeat'
STARTUP
= 'startup'
class nemoguardrails.telemetry.GuardrailsUsageEvent()

Bases: TelemetryEvent

Usage event for NeMo Guardrails.

Emitted at each LLMRails or IORails instantiation and as periodic heartbeats from a single daemon thread per process. The Guardrails wrapper emits through whichever runtime engine it constructs. All events from one process share a session ID. Contains no user content, model names, or request-level data.

_event_name
str = 'guardrails_usage_event'
builtin_features
List[str]
colang_version
str
deployment_type
DeploymentTypeEnum
event
EventTypeEnum
has_knowledge_base
bool
llm_providers
List[str]
model_config
nemo_source
NemoSourceEnum
nemoguardrails_version
str
num_custom_flows
int
num_rails_configured
int
os_name
str
platform
str
python_version
str
rail_types_in_use
List[str]
rails_engine
RailsEngineEnum
session_id
str
streaming_configured
bool
timestamp
float
tracing_enabled
bool
class nemoguardrails.telemetry.NemoSourceEnum

Bases: enum.Enum

The NeMo product that created the event.

Mirrors the shared nemo-telemetry definition so the guardrails event plugs into the same definitions/types block other NeMo products (DataDesigner, Safe Synthesizer, Agent Toolkit, etc.) already share.

AGENT_TOOLKIT
= 'agent_toolkit'
ANONYMIZER
= 'anonymizer'
AUDITOR
= 'auditor'
DATADESIGNER
= 'datadesigner'
EVALUATOR
= 'evaluator'
GUARDRAILS
= 'guardrails'
INFERENCE
= 'inference'
SAFE_SYNTHESIZER
= 'safe-synthesizer'
UNDEFINED
= 'undefined'
class nemoguardrails.telemetry.RailsEngineEnum

Bases: enum.Enum

IORAILS
= 'IORails'
LLMRAILS
= 'LLMRails'
UNDEFINED
= 'undefined'
class nemoguardrails.telemetry.TelemetryEvent()

Bases: BaseModel

Abstract base for telemetry events.

Subclasses must define _event_name as a ClassVar. The optional _schema_version ClassVar is used by the payload builder to set eventSchemaVer in the NVIDIA telemetry envelope.

Raises:

  • TypeError: If a subclass fails to define _event_name.
_event_name
str
_schema_version
str = '1.7'
nemoguardrails.telemetry.TelemetryEvent.__init_subclass__(
kwargs: typing.Any = {}
) -> None
nemoguardrails.telemetry._build_event(
event: nemoguardrails.telemetry.TelemetryEvent,
ts: typing.Optional[float] = None
) -> typing.Dict[str, typing.Any]

Wrap a TelemetryEvent in the inner event dict for the NVIDIA envelope.

Always injects nemoSource="guardrails" into the parameters so the backend can route the event correctly.

Parameters:

event
TelemetryEvent

The Pydantic event instance to serialize.

ts
Optional[float]Defaults to None

Optional Unix timestamp for the ts field; uses current time if None.

Returns: Dict[str, Any]

A dict with ts, name, and parameters keys, ready to

nemoguardrails.telemetry._build_nvidia_payload(
events: typing.List[nemoguardrails.telemetry.TelemetryEvent],
client_version: str,
session_id: str,
timestamps: typing.Optional[typing.List[typing.Optional[float]]] = None
) -> typing.Dict[str, typing.Any]

Build the outer NVIDIA telemetry envelope that wraps one or more events.

All envelope fields other than clientVer, sessionId, eventSchemaVer, sentTs, cpuArchitecture, and events are hardcoded to "undefined" or "None" per the NVIDIA telemetry protocol spec. eventSchemaVer is read from the first event’s _schema_version ClassVar.

Parameters:

events
List[TelemetryEvent]

Non-empty list of telemetry events to include.

client_version
str

Version string of the calling product, set as clientVer (typically the package version).

session_id
str

Session identifier set as sessionId in the envelope.

timestamps
Optional[List[Optional[float]]]Defaults to None

Optional per-event Unix timestamps. If None, each event is timestamped with the current time.

Returns: Dict[str, Any]

The complete envelope as a dict, ready to be JSON-serialized

Raises:

  • ValueError: If events is empty.
nemoguardrails.telemetry._collect_usage_data(
config: typing.Optional[nemoguardrails.rails.llm.config.RailsConfig],
deployment_type: str
) -> nemoguardrails.telemetry.GuardrailsUsageEvent

Collect anonymous usage data into a GuardrailsUsageEvent.

Always populates system fields (version, platform, Python version). When config is provided, additionally populates config-derived fields: LLM provider names, rail types in use, built-in features, custom flow count, and feature flags. Never reads model names, prompts, or user content.

Parameters:

config
Optional[RailsConfig]

The RailsConfig to inspect, or None for a system-only event (e.g. from the server startup context).

deployment_type
str

How guardrails was deployed, e.g. "library", "api", or "cli". Coerced to DeploymentTypeEnum.UNDEFINED if falsy.

Returns: GuardrailsUsageEvent

A fully populated GuardrailsUsageEvent.

nemoguardrails.telemetry._detect_builtin_features(
config: nemoguardrails.rails.llm.config.RailsConfig
) -> typing.List[str]

Detect which built-in NeMo Guardrails library features are active.

Uses two signals: (1) fields on RailsConfigData that differ from their defaults (explicit config), and (2) exact-match flow names against a known set of built-in library flows. Only our own feature names are ever reported, never user-defined flow names.

Parameters:

config
RailsConfig

The RailsConfig instance to inspect.

Returns: List[str]

Sorted list of active built-in feature names (e.g.

nemoguardrails.telemetry._flow_file_name(
flow: typing.Any
) -> typing.Optional[str]
nemoguardrails.telemetry._get_audit_file() -> pathlib.Path

Return the local audit JSONL path, honoring test overrides.

nemoguardrails.telemetry._get_config_dir() -> pathlib.Path

Return the telemetry config directory, honoring test overrides.

nemoguardrails.telemetry._get_do_not_track_file() -> pathlib.Path

Return the do-not-track marker path, honoring test overrides.

nemoguardrails.telemetry._get_heartbeat_interval_s() -> float

Return the heartbeat interval, falling back safely on bad env values.

nemoguardrails.telemetry._get_iso_timestamp(
ts: typing.Optional[float] = None
) -> str

Format a Unix timestamp as an ISO 8601 UTC string with millisecond precision.

Parameters:

ts
Optional[float]Defaults to None

Unix timestamp (seconds since epoch). If None, uses the current UTC time.

Returns: str

ISO 8601 formatted string ending with "Z", e.g.

nemoguardrails.telemetry._get_usage_stats_server_url() -> str

Return the telemetry server URL, honoring runtime env overrides.

nemoguardrails.telemetry._get_version(
package_name: str
) -> str
nemoguardrails.telemetry._heartbeat_loop(
startup_event: nemoguardrails.telemetry.GuardrailsUsageEvent,
session_id: str,
client_version: str
) -> None

Run the heartbeat loop forever in a daemon thread.

Started exactly once per process (gated by _heartbeat_started). Sleeps at least _HEARTBEAT_INTERVAL_S seconds, then emits a heartbeat event tied to the process’s session ID. The heartbeat reuses a copy of the first startup event’s metadata and changes only event, timestamp, and sessionId. The thread is a daemon so it dies with the main process; no explicit shutdown is required.

Parameters:

startup_event
GuardrailsUsageEvent

The first startup event emitted by this process.

session_id
str

The process-stable session ID, mirrored into the heartbeat event’s session_id field and the envelope.

client_version
str

Value to set as clientVer in the envelope.

nemoguardrails.telemetry._is_custom_flow(
flow: typing.Any
) -> bool
nemoguardrails.telemetry._is_usage_stats_enabled() -> bool

Check whether usage reporting is enabled.

Opt-out signals, any of which disables reporting:

  • NEMO_GUARDRAILS_NO_USAGE_STATS=1 / true env var (product-specific).
  • DO_NOT_TRACK=1 / true env var (industry-standard).
  • ~/.config/nemoguardrails/do_not_track file present.
  • CI env var truthy (set by GitHub Actions, GitLab CI, CircleCI, Travis, Buildkite, etc.). Suppresses telemetry from automated test runs that are not real deployments. Honoring CI is the same convention used by Homebrew, npm, conda, and others.
  • PYTEST_CURRENT_TEST env var present, or pytest already loaded in the process. Catches the case of a developer running tests locally without CI=true, including collection/import phases where PYTEST_CURRENT_TEST is not set, and suppresses any telemetry that would otherwise leak from a downstream user’s test suite that happens to import nemoguardrails.

The intent is that adoption metrics reflect real deployments only, not synthetic test/CI traffic.

Returns: bool

True if reporting should proceed, False if any opt-out is active.

nemoguardrails.telemetry._is_v2_library_flow(
flow: typing.Any
) -> bool
nemoguardrails.telemetry._normalize_builtin_feature_id(
field_name: str
) -> str

Return the documented feature id for a RailsConfigData field.

nemoguardrails.telemetry._reset_for_fork() -> None

Clear module state in a forked child so it starts a fresh session.

Registered via os.register_at_fork(after_in_child=...) at module import time on POSIX platforms. Without this, workers spawned by gunicorn --preload (or any other fork-based runtime) would inherit the parent’s session ID and its _heartbeat_started flag, but lose the actual heartbeat thread (POSIX fork() only duplicates the calling thread). The result would be silent: every worker would report under the parent’s session and never emit heartbeats. After this hook runs, the child’s first report_usage call generates a fresh session UUID and starts its own heartbeat. The deployment-type override is intentionally preserved so a forked API or CLI worker keeps the attribution claimed by its parent.

nemoguardrails.telemetry._rotate_audit_file(
audit_file: typing.Optional[pathlib.Path] = None
) -> None

Rotate the local audit file when it exceeds the size cap.

The current usage_stats.json is renamed to usage_stats.json.1, overwriting any previous backup. This bounds on-disk usage at approximately 2 * _AUDIT_FILE_MAX_BYTES. Errors are silently logged at DEBUG level.

nemoguardrails.telemetry._safe_home_dir() -> pathlib.Path

Return the user’s home directory without raising at import time.

nemoguardrails.telemetry._send_one_event(
event: nemoguardrails.telemetry.GuardrailsUsageEvent,
server_url: str,
client_version: str,
session_id: str
) -> None

Write a single event to the audit file and POST it.

Used as the target of a one-shot daemon thread spawned by report_usage. Fire-and-forget: errors are swallowed at DEBUG level inside _write_audit_file and _send_report.

Parameters:

event
GuardrailsUsageEvent

The telemetry event to record and transmit.

server_url
str

Full HTTPS URL of the telemetry endpoint.

client_version
str

Value to set as clientVer in the envelope.

session_id
str

Value to set as sessionId in the envelope.

nemoguardrails.telemetry._send_report(
event: nemoguardrails.telemetry.TelemetryEvent,
server_url: str,
client_version: str,
session_id: str
) -> None

POST a single telemetry event to the configured server.

Fire-and-forget: a single attempt with a 5-second timeout, no retries, all exceptions silently logged at DEBUG level. Runs in a daemon thread so it never blocks the main process.

Parameters:

event
TelemetryEvent

The telemetry event to send.

server_url
str

Full HTTPS URL of the telemetry endpoint.

client_version
str

Value to set as clientVer in the envelope.

session_id
str

Value to set as sessionId in the envelope.

nemoguardrails.telemetry._start_daemon_thread(
target: typing.Any,
args: tuple[typing.Any, ...],
failure_message: str
) -> bool

Start a daemon thread and report whether startup succeeded.

nemoguardrails.telemetry._write_audit_file(
data: typing.Dict[str, typing.Any]
) -> None

Append a payload to the local audit file as a JSON line.

Creates the config directory if it does not exist. Rotates the audit file when it exceeds _AUDIT_FILE_MAX_BYTES. All errors (permission denied, disk full, etc.) are silently logged at DEBUG level so telemetry never disrupts the main process.

Parameters:

data
Dict[str, Any]

Serialized event payload (already converted to a dict via model_dump(by_alias=True)).

nemoguardrails.telemetry.report_usage(
config: typing.Optional[nemoguardrails.rails.llm.config.RailsConfig] = None,
deployment_type: str = 'library',
rails_engine: str = ''
) -> None

Emit one anonymous usage event for the given config.

Each call produces a single event tied to the process’s session ID (lazily generated on first call, reused thereafter). The heartbeat daemon thread is started exactly once per process. All work happens off the calling thread so this function returns immediately.

The effective deployment type is resolved as: the value previously passed to set_deployment_type if any, else the function argument. This lets the server lifespan or CLI command claim the deployment context once, and downstream LLMRails.__init__ / Guardrails.__init__ calls inherit it without coordination.

Respects the triple opt-out (env vars and file).

Parameters:

config
Optional[RailsConfig]Defaults to None

RailsConfig to introspect. When None, only system-level fields are populated.

deployment_type
strDefaults to 'library'

How guardrails was deployed (e.g. "library", "api", "cli"). Overridden by set_deployment_type.

rails_engine
strDefaults to ''

Which engine class is in use (e.g. "LLMRails", "IORails"). Ignored if empty.

nemoguardrails.telemetry.set_deployment_type(
deployment_type: str
) -> None

Set the deployment type that subsequent report_usage calls will use.

Called by the FastAPI server lifespan ("api") and the nemoguardrails chat CLI command ("cli") before LLMRails is constructed. Takes precedence over the deployment_type argument passed by LLMRails.__init__ and Guardrails.__init__, so the same library-internal call sites emit the correct value depending on how the process was invoked.

Invalid values are silently ignored (logged at DEBUG level), so a bad caller never crashes the host process.

Parameters:

deployment_type
str

One of the DeploymentTypeEnum string values (e.g. "api", "cli", "library").

nemoguardrails.telemetry._AUDIT_FILE: Optional[Path] = None
nemoguardrails.telemetry._AUDIT_FILE_MAX_BYTES = 10 * 1024 * 1024
nemoguardrails.telemetry._COLANG_V2_LIBRARY_DIR = Path(__file__).resolve().parent / 'colang' / 'v2_x' / 'library'
nemoguardrails.telemetry._CONFIG_BUILTIN_FEATURE_ALIASES = {'fact_checking': 'factchecking', 'patronus': 'patronusai', 'regex_detection': '...
nemoguardrails.telemetry._CONFIG_DIR: Optional[Path] = None
nemoguardrails.telemetry._DO_NOT_TRACK_FILE: Optional[Path] = None
nemoguardrails.telemetry._HEARTBEAT_INTERVAL_S = _get_heartbeat_interval_s()
nemoguardrails.telemetry._KNOWN_BUILTIN_FLOWS = {'activefence moderation on input': 'activefence', 'activefence moderation on in...
nemoguardrails.telemetry._NVIDIA_CLIENT_ID = '184482118588404'
nemoguardrails.telemetry._NVIDIA_EVENT_PROTOCOL = '1.6'
nemoguardrails.telemetry._NVIDIA_EVENT_SYS_VER = 'nemo-telemetry/1.0'
nemoguardrails.telemetry._USAGE_STATS_SERVER = 'https://events.telemetry.data.nvidia.com/v1.1/events/json'
nemoguardrails.telemetry._deployment_type_override: Optional[DeploymentTypeEnum] = None
nemoguardrails.telemetry._heartbeat_started = False
nemoguardrails.telemetry._lock = threading.Lock()
nemoguardrails.telemetry._session_uuid: Optional[str] = None
nemoguardrails.telemetry.log = logging.getLogger(__name__)