Skip to content

docs(cli): document operational process logging config#419

Open
ericevans-nv wants to merge 5 commits into
NVIDIA:mainfrom
ericevans-nv:docs/cli-operational-logging
Open

docs(cli): document operational process logging config#419
ericevans-nv wants to merge 5 commits into
NVIDIA:mainfrom
ericevans-nv:docs/cli-operational-logging

Conversation

@ericevans-nv

@ericevans-nv ericevans-nv commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Overview

Documents the operational logging configuration and source-selection behavior introduced by #413. This docs-only PR should merge after or with #413 so the documented options match released CLI and library behavior.

  • I confirm this contribution is my own work, or I have the right to submit it under this project's license.
  • I searched existing issues and open pull requests, and this does not duplicate existing work.

Details

  • Document always-on stderr logging, built-in defaults, and the configuration-editing commands that intentionally skip logging initialization.
  • Explain the single-source precedence across CLI options, environment variables, discovered config.toml, and defaults.
  • Document direct CLI and environment settings, absolute TOML configuration paths, and the shared Rust LoggingRuntime entry points.
  • Update the [logging] and [[logging.sinks]] example for asynchronous file delivery and the fixed 8,192-entry queue safety limit.

Where should the reviewer start?

  • docs/nemo-relay-cli/basic-usage.mdx

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

Summary by CodeRabbit

  • Documentation
    • Added an “Operational Logging” subsection to Basic Usage, covering logging initialization and configuration.
    • Clarified that stderr logging is always enabled.
    • Documented the precedence order for selecting logging settings: CLI --log-*, then NEMO_RELAY* environment variables, then [logging] in the resolved config.toml, then built-in defaults.
    • Added guidance on using direct CLI/env settings vs an absolute TOML file via --log-config-path / NEMO_RELAY_LOG_CONFIG_PATH, including an explicit “do not combine” rule.
    • Expanded [logging] schema details (e.g., level, stderr format, optional flush interval) and sink configuration examples for async file logging.

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
@ericevans-nv ericevans-nv requested review from a team and lvojtku as code owners July 14, 2026 16:20
@github-actions github-actions Bot added size:S PR is small Documentation documentation-related labels Jul 14, 2026
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Basic Usage documents Relay operational logging initialization, configuration precedence, stderr output, TOML settings, asynchronous file sinks, and Rust runtime lifetime requirements.

Changes

Operational logging

Layer / File(s) Summary
Document logging configuration
docs/nemo-relay-cli/basic-usage.mdx
Documents logging initialization behavior, CLI/environment/TOML precedence, direct and file-based configuration, [logging] and [[logging.sinks]] settings, asynchronous file delivery, and LoggingRuntime shutdown requirements.

Estimated code review effort: 1 (Trivial) | ~2 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Conventional Commits syntax is correct and the title accurately summarizes the docs-only logging configuration changes.
Description check ✅ Passed The description follows the template with Overview, Details, reviewer start, checklist items, and related issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/nemo-relay-cli/basic-usage.mdx`:
- Around line 153-183: Replace the logging configuration section in the basic
usage documentation with the actual observability configuration path supported
by the CLI. Remove references to --log-* options, NEMO_RELAY_LOG* variables, the
[logging] TOML table, and their precedence or mixing rules; document the real
configuration entry points and usage instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 798ef69d-66c9-4e56-8f4b-2db20ac26017

📥 Commits

Reviewing files that changed from the base of the PR and between ccc0204 and fc992b7.

📒 Files selected for processing (1)
  • docs/nemo-relay-cli/basic-usage.mdx
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (7)
**/*.mdx

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

MDX top-of-file SPDX comments must use {/* ... */} delimiters instead of HTML comment delimiters (Must-Fix)

In MDX files, top-of-file comments must use JSX comment delimiters ({/* to open and */} to close); do not use HTML comments for MDX SPDX headers

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Update README.md, fern/, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.

**/*.{md,mdx}: Prefer the documented public API, not internal shortcuts
Keep package names, repo references, and build commands current
Keep release-process and release-notes guidance in repo-maintainer docs such as RELEASING.md, not as user-facing docs pages or CHANGELOG.md
Keep stable user-facing wrappers at scripts/ root in docs and examples; only point at namespaced helper paths when documenting internal maintenance work
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, and grpc-v1 protocol details on separate pages

If links in documentation change, run just docs-linkcheck.

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
**/*.{md,markdown,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Markdown/MDX documentation files using the HTML comment block form.

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
{docs,examples}/**/*

📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)

Update docs and examples.

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
docs/**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If documentation examples or commands under docs/ change, run the targeted docs checks appropriate to the change.

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency across language bindings.
Flag stale examples, missing SPDX headers where required, and instructions that no longer match CI or pre-commit behavior.

Files:

  • docs/nemo-relay-cli/basic-usage.mdx
🔇 Additional comments (1)
docs/nemo-relay-cli/basic-usage.mdx (1)

185-208: 🎯 Functional Correctness

Check the logging schema/API surfaceflush_interval_millis, queue_capacity, the 8192-entry cap, relative-path resolution, and LoggingRuntime::configure* should all map to supported public interfaces; if any of them are internal or unstable, switch this doc to the public entry point and update the defaults accordingly.

Comment on lines +153 to +183
Relay selects one CLI logging source in this order:

1. `--log-*` command-line options
2. `NEMO_RELAY_LOG*` environment variables
3. `[logging]` in the resolved Relay `config.toml`
4. Built-in defaults

Sources are not merged. Configure the level and stderr format directly:

```bash
nemo-relay --log-level debug --log-stderr-format jsonl
```

Alternatively, select an absolute TOML file containing a `[logging]` section:

```bash
nemo-relay --log-config-path /absolute/path/to/logging.toml
```

Environment variables provide the same two choices:

```bash
export NEMO_RELAY_LOG=debug
export NEMO_RELAY_LOG_STDERR_FORMAT=jsonl

# Or select an absolute TOML file instead:
export NEMO_RELAY_LOG_CONFIG_PATH=/absolute/path/to/logging.toml
```

Do not combine `--log-config-path` with direct logging options, or
`NEMO_RELAY_LOG_CONFIG_PATH` with the other logging environment variables.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 \
  'log-config-path|NEMO_RELAY_LOG_CONFIG_PATH|log-level|NEMO_RELAY_LOG|stderr-format|config.toml|logging' .

Repository: NVIDIA/NeMo-Relay

Length of output: 50376


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate likely logging/config files and map their structure.
git ls-files | rg '(^crates/.*(log|logging|config).*\.(rs|ts|js|mdx)$|^docs/nemo-relay-cli/basic-usage\.mdx$|Cargo\.toml$)' | sed -n '1,200p'

printf '\n--- outline candidates ---\n'
for f in \
  crates/cli/src/main.rs \
  crates/cli/src/commands.rs \
  crates/cli/src/logging.rs \
  crates/cli/src/config.rs \
  crates/cli/src/args.rs \
  crates/cli/src/options.rs \
  crates/relay/src/logging.rs \
  crates/relay/src/config.rs
do
  if [ -f "$f" ]; then
    echo "### $f"
    ast-grep outline "$f" --view expanded || true
    echo
  fi
done

Repository: NVIDIA/NeMo-Relay

Length of output: 1189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for the concrete logging option names and resolution logic with limited output.
rg -n -C 3 \
  'log-config-path|log-stderr-format|log-level|NEMO_RELAY_LOG_CONFIG_PATH|NEMO_RELAY_LOG_STDERR_FORMAT|NEMO_RELAY_LOG|logging' \
  crates docs \
  --glob '!**/*.mdx' \
  --glob '!**/*.md' \
  | sed -n '1,260p'

Repository: NVIDIA/NeMo-Relay

Length of output: 1329


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect CLI argument definitions and logging config resolution in the relay CLI.
for f in \
  crates/cli/src/main.rs \
  crates/cli/src/commands/*.rs \
  crates/cli/src/*.rs \
  crates/cli/tests/coverage/commands/*.rs \
  crates/cli/tests/coverage/agents/*.rs
do
  [ -f "$f" ] && true
done

rg -n -C 4 \
  'struct .*Args|log_config_path|log_stderr_format|log_level|NEMO_RELAY_LOG_CONFIG_PATH|NEMO_RELAY_LOG_STDERR_FORMAT|NEMO_RELAY_LOG|Logging|logging' \
  crates/cli/src crates/cli/tests/coverage \
  | sed -n '1,260p'

Repository: NVIDIA/NeMo-Relay

Length of output: 2352


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the CLI logging flags, env vars, and config loader with focused output.
rg -n -C 4 \
  'log_config_path|log_stderr_format|log_level|NEMO_RELAY_LOG_CONFIG_PATH|NEMO_RELAY_LOG_STDERR_FORMAT|NEMO_RELAY_LOG|stderr_format|flush_interval_millis|queue_capacity|logging' \
  crates/cli/src crates/cli/tests \
  | sed -n '1,260p'

Repository: NVIDIA/NeMo-Relay

Length of output: 155


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the main CLI entrypoint and the serve command wiring.
for f in crates/cli/src/main.rs crates/cli/src/commands/serve.rs crates/cli/src/configuration/mod.rs crates/cli/src/configuration/types.rs; do
  if [ -f "$f" ]; then
    echo "### $f"
    cat -n "$f" | sed -n '1,260p'
    echo
  fi
done

Repository: NVIDIA/NeMo-Relay

Length of output: 20419


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate every logging-related symbol in Rust sources and config docs.
rg -n -C 2 \
  'stderr_format|log_config|log_level|log_stderr|NEMO_RELAY_LOG|logging\]|flush_interval_millis|queue_capacity|human|jsonl' \
  crates docs \
  --glob '!**/*.mdx' \
  --glob '!**/*.md' \
  | sed -n '1,260p'

Repository: NVIDIA/NeMo-Relay

Length of output: 19483


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the shared config loader and override application points.
for f in crates/cli/src/configuration/mod.rs crates/cli/src/configuration/types.rs; do
  echo "### $f"
  ast-grep outline "$f" --view expanded || true
  echo
done

printf '\n--- focused reads ---\n'
sed -n '260,520p' crates/cli/src/configuration/mod.rs

Repository: NVIDIA/NeMo-Relay

Length of output: 20050


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find tests or docs that exercise the logging settings and precedence.
rg -n -C 3 \
  'log|stderr|jsonl|human|config-path|logging' \
  crates/cli/tests crates/cli/src docs/nemo-relay-cli/basic-usage.mdx \
  | sed -n '1,260p'

Repository: NVIDIA/NeMo-Relay

Length of output: 21372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the exact functions that assemble config and apply overrides.
python3 - <<'PY'
from pathlib import Path
path = Path("crates/cli/src/configuration/mod.rs")
lines = path.read_text().splitlines()
targets = ["fn load_shared_config", "fn load_shared_config_scoped", "fn apply_server_overrides"]
for t in targets:
    for i, line in enumerate(lines):
        if t in line:
            start = max(0, i-20)
            end = min(len(lines), i+140)
            print(f"\n### {t} @ line {i+1}\n")
            for n in range(start, end):
                print(f"{n+1:4d}: {lines[n]}")
            break
PY

Repository: NVIDIA/NeMo-Relay

Length of output: 21404


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for any direct references to the logging config filename and env names.
rg -n -C 4 \
  'logging\.toml|config\.toml|NEMO_RELAY_LOG_CONFIG_PATH|NEMO_RELAY_LOG_STDERR_FORMAT|NEMO_RELAY_LOG_LEVEL|NEMO_RELAY_LOG=' \
  . \
  | sed -n '1,240p'

Repository: NVIDIA/NeMo-Relay

Length of output: 19070


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the shared config loader and override application logic in full.
python3 - <<'PY'
from pathlib import Path
path = Path("crates/cli/src/configuration/mod.rs")
lines = path.read_text().splitlines()
for name in ["fn load_shared_config(", "fn load_shared_config_scoped(", "fn apply_server_overrides("]:
    for i, line in enumerate(lines):
        if name in line:
            start = max(0, i-30)
            end = min(len(lines), i+220)
            print(f"\n### {name} @ line {i+1}\n")
            for n in range(start, end):
                print(f"{n+1:4d}: {lines[n]}")
            break
PY

Repository: NVIDIA/NeMo-Relay

Length of output: 33465


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search the repository for any runtime logging format/config code.
rg -n -C 3 \
  'jsonl|human-readable|stderr format|stderr_format|flush interval|queue capacity|tracing_subscriber|env_filter|fmt::layer|with_writer|logging source' \
  crates \
  | sed -n '1,260p'

Repository: NVIDIA/NeMo-Relay

Length of output: 22058


Update the logging docs to match the real config surface. --log-*, NEMO_RELAY_LOG*, and a [logging] table don’t exist in the CLI, so this precedence/mixing guidance is stale and should be replaced with the actual observability configuration path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/nemo-relay-cli/basic-usage.mdx` around lines 153 - 183, Replace the
logging configuration section in the basic usage documentation with the actual
observability configuration path supported by the CLI. Remove references to
--log-* options, NEMO_RELAY_LOG* variables, the [logging] TOML table, and their
precedence or mixing rules; document the real configuration entry points and
usage instead.

Source: Path instructions

@willkill07 willkill07 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need a part outside of the CLI for the environment-based configuration of logging

rapids-bot Bot pushed a commit that referenced this pull request Jul 16, 2026
#### Overview

Add configurable, process-wide operational logging backed by the `log` facade and `spdlog-rs`. Operational commands initialize logging during top-level dispatch, before command execution. `nemo-relay config` and `nemo-relay plugins edit` intentionally skip initialization so invalid logging configuration cannot prevent users from repairing it.

This PR establishes the logging configuration and runtime. Broader production operational event call sites will be added separately.

- [x] I confirm this contribution is my own work, or I have the right to submit it under this project's license.
- [x] I searched existing issues and open pull requests, and this does not duplicate existing work.

#### Details

- Add core-owned `LoggingConfig` and `LoggingRuntime` APIs shared by CLI and library integrations.
- Support built-in defaults, normal `config.toml` discovery, environment configuration, explicit absolute TOML paths, and direct CLI settings. CLI sources take precedence over environment configuration, which takes precedence over discovered file configuration and defaults.
- Add an always-on stderr sink for initialized operational commands and optional asynchronous JSONL or human-readable file sinks.
- Bound asynchronous file queues, reject duplicate resolved sink paths, and drain pending file records during shutdown.
- Attach one root Relay ID to operational records for process-level correlation.
- Keep logging output on stderr or configured files; operational logging does not write to stdout.
- Keep logging configuration under `[logging]` in `config.toml`. A separate interactive logging editor is outside this PR.
- Documentation for the configuration surface is tracked in #419.
- Add focused core and CLI coverage for parsing, validation, formatting, sink behavior, configuration precedence, initialization policy, and shutdown flushing.
- Regenerate `ATTRIBUTIONS-Rust.md` for the new Rust dependencies.

#### Where should the reviewer start?

- `crates/core/src/logging/` for configuration types, runtime ownership, formatting, sinks, and shutdown behavior
- `crates/cli/src/commands/logging.rs` and `crates/cli/src/commands/mod.rs` for configuration-source selection and early command initialization
- `crates/cli/src/configuration/logging.rs` for normal Relay TOML integration
- `crates/core/tests/coverage/logging_tests.rs` and `crates/cli/tests/coverage/shared/config_tests.rs` for runtime and configuration guarantees
- `crates/cli/tests/coverage/commands/main_tests.rs` for CLI precedence and command policy

#### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

- Closes: RELAY-451


## Summary by CodeRabbit

* **New Features**
  * Added configurable operational logging with human-readable or JSONL output.
  * Added stderr and asynchronous file sinks with per-sink level/format, queue limits, and periodic flushing.
  * Introduced logging configuration via CLI options, environment variables, and TOML (including scoped application).
  * Logging now initializes automatically for applicable CLI commands, while configuration/editor commands can bypass it.
* **Bug Fixes**
  * Strengthened validation for configuration values and file sink destination handling (including duplicates and invalid paths).
* **Tests**
  * Added extensive logging coverage for config loading, formatter output, sink runtime behavior, shutdown behavior, and CLI precedence/policy.
* **Chores**
  * Regenerated dependency attribution and license metadata.

Authors:
  - Eric Evans II (https://github.com/ericevans-nv)
  - Alex Fournier (https://github.com/afourniernv)

Approvers:
  - Alex Fournier (https://github.com/afourniernv)
  - Will Killian (https://github.com/willkill07)
  - https://github.com/Salonijain27

URL: #413
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation documentation-related size:S PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants