CLI
The main CLI command is nats-sink. It is intended for operators and
developers who want to run a sink process from a terminal, container, or
service manager without writing Python code. The CLI reads the same JSON
configuration model that the Python API uses.
The project also ships a companion metrics command named nats-sink-metrics.
That command does not run a sink. It reads a local JSON metrics snapshot and
prints status in formats that are easy for humans, shell scripts, and simple
monitoring jobs to consume.
The project also ships an observability policy command named
nats-sink-observe. That command manages what may be shared with external
observability platforms. It can generate a disabled Prometheus policy from the
core config, list metric names and subject hints, validate policy, and render
policy-filtered Prometheus textfile output or run the optional native
Prometheus HTTP endpoint. It can also export approved metrics to an
OpenTelemetry Collector through OTLP/HTTP JSON, including the Elastic
Observability and Grafana Alloy profiles, approved aggregate metric events
through Splunk HEC, approved custom metrics to OCI Monitoring, Amazon
CloudWatch, and Azure Monitor, approved best-effort datagrams to
StatsD-compatible aggregators or a Datadog Agent, and RFC 5424-style messages
to syslog pipelines.
For readers new to this project, the CLI does not implement a separate
delivery engine. It validates configuration, creates the selected sink, builds
JetStreamSinkRunner, and then the core runner performs commit-then-ACK
processing.
For operational teams, this means the same command can be used during local tests, lab validation, and controlled service deployments. The behavior should be reviewed through configuration and logs rather than through ad hoc scripts that might accidentally weaken ACK ordering or secret handling.
nats-sink run config.json
nats-sink validate config.json
nats-sink show-effective-config config.json
nats-sink export-catalogue-manifest config.json --dataset-name orders-events
nats-sink test-sink config.json
nats-sink inspect-ordered config.json --max-messages 5 --format jsonl
nats-sink stream-plan config.json
nats-sink query-lineage config.json --field mission_id --value MISSION-ALPHA --dry-run
nats-sink replay-spool spool-config.json target-config.json --dry-run
nats-sink-metrics show .local/nats-sinks/metrics.json
nats-sink-observe init-prometheus-policy config.json observability.prometheus.json
nats-sink-observe prometheus-http .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe otlp-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe elastic-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe grafana-alloy-config observability.prometheus.json
nats-sink-observe grafana-alloy-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe splunk-hec-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe oci-monitoring-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe statsd-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe datadog-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe cloudwatch-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe azure-monitor-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe syslog-export .local/nats-sinks/metrics.json observability.prometheus.json --dry-run
nats-sink-observe nats-monitoring-poll observability.prometheus.json --dry-run
Commands
nats-sink validate
Validates JSON syntax, Pydantic configuration models, and sink-specific configuration. This is the safest first command to run because it does not need to connect to NATS or the configured destination.
nats-sink validate examples/file-basic/config.json
When the configuration contains a top-level sinks registry, validate also
checks every named sink and reports which route names reference which target
names. The report is intentionally safe to paste into tickets or release
evidence because it includes target names and sink types, not passwords,
connection credentials, or payloads.
nats-sink validate examples/named-multi-sink/config.json
Example output:
Configuration is valid.
Active sink: file
ACK policy: commit-then-acknowledge
Named sinks: file_audit (file), oracle_secret (oracle), oracle_unclass (oracle)
Route target references:
- nato_secret_sensor_audit: oracle_secret (required), file_audit (optional, minimum_wait_ms=250, timeout_ms=1000)
- nato_unclass_sensor_audit: oracle_unclass (required)
nats-sink export-catalogue-manifest
Exports a redacted data-product or catalogue manifest from a validated configuration. The command does not connect to NATS or any sink destination and does not export payloads.
nats-sink export-catalogue-manifest config.json \
--dataset-name orders-events \
--output .local/catalogue/orders-events.json
Existing output files are not replaced unless --overwrite is set. See
Catalogue Manifest Export for the manifest shape and
governance boundary.
nats-sink show-effective-config
Displays the validated configuration as redacted JSON. Use this when you want to confirm defaults and environment-backed field names without printing resolved secrets.
This is especially useful in reviewed environments because it lets operators confirm NATS subjects, sink type, message metadata defaults, encryption policy, and DLQ settings without exposing passwords, tokens, Oracle wallet passwords, or encryption keys.
nats-sink show-effective-config examples/file-basic/config.json
nats-sink test-sink
Starts the configured sink and runs a health check when the sink supports it. This command opens destination connections, so use it only in environments where that is expected.
nats-sink test-sink examples/file-basic/config.json
Named sink health checks use the same sink-specific validation and startup path as the active sink:
nats-sink test-sink examples/named-multi-sink/config.json --sink-name file_audit
nats-sink test-sink examples/named-multi-sink/config.json --all-named-sinks
--sink-name is useful when the configuration contains Oracle targets and file
targets but an operator only wants to check the local file audit path. Use
--all-named-sinks only when opening every configured destination is expected.
nats-sink inspect-ordered
Inspects JetStream messages through a NATS ordered consumer when the installed NATS Python client exposes ordered-consumer support. This is an inspection tool, not a sink worker: it does not build a sink, does not write to Oracle Database, Oracle MySQL, file, spool, fan-out, or plugin destinations, and does not ACK production durable work.
Use it for bounded local troubleshooting when an operator needs to inspect a small in-order view of a subject without advancing the configured durable sink consumer:
nats-sink inspect-ordered examples/file-basic/config.json --max-messages 5
Example text output:
Ordered inspection result
inspection_only=true
messages_seen=1
payload_bytes_seen=24
stopped_reason=timeout
record stream_sequence=7 consumer_sequence=1 subject='orders.created' priority=null classification=null labels='' payload_bytes=24 payload_redacted=true
Payloads are redacted by default. For local troubleshooting files, write sanitized JSONL under an approved output root:
nats-sink inspect-ordered examples/file-basic/config.json \
--max-messages 5 \
--max-payload-bytes 1048576 \
--max-headers 32 \
--max-header-value-bytes 256 \
--output-root .local/nats-sinks/inspection \
--output orders.jsonl
Example JSONL record:
{"inspection_only":true,"subject":"orders.created","stream":"ORDERS","consumer":"_ordered","stream_sequence":7,"consumer_sequence":1,"timestamp":null,"received_at":"2026-05-26T10:00:00Z","priority":null,"classification":null,"labels":[],"headers":{"Authorization":"<redacted>","X-Trace":"visible"},"payload":{"redacted":true,"bytes":24,"sha256":"..."}}
Use --format jsonl when shell tooling should consume the records from
standard output. Use --include-payload only in controlled local environments
where the payload is approved for display; binary payloads are encoded as
Base64, and text payloads are emitted as UTF-8. The command enforces hard
limits for message count, payload bytes, pending messages, pending bytes,
timeouts, header count, header value length, and JSONL output paths before or
during inspection. If ordered-consumer support is not available in the active
client, the command exits with a configuration error rather than falling back
to durable pull or ordinary push delivery. The compatibility check uses the
public JetStreamContext.subscribe API and reports only a short sanitized
reason, such as a missing ordered_consumer option or an unreadable client
signature.
See Ordered Consumer Evaluation for the design decision and replay boundaries.
nats-sink stream-plan
Generates an offline JetStream stream-management plan from the runtime JSON
configuration. This command is deliberately separate from nats-sink run: it
does not connect to NATS, does not create streams, does not update consumers,
does not resolve credentials, and does not need NATS administrator
permissions.
Use it when an operator wants to review stream retention, discard policy, storage type, replica count, duplicate-window settings, and runtime versus administration permission boundaries before applying changes with the NATS CLI, Terraform, Ansible, or another approved platform process.
nats-sink stream-plan examples/file-basic/config.json \
--retention limits \
--discard old \
--storage file \
--replicas 3 \
--duplicate-window-seconds 600
Use JSON output for scripts and review artifacts:
nats-sink stream-plan examples/file-basic/config.json --format json
Example JSON excerpt:
{
"stream": "ORDERS",
"subjects": ["orders.*"],
"durable_consumer": "file-orders-sink",
"recommended_stream_settings": {
"retention": "limits",
"discard": "old",
"storage": "file",
"replicas": 3,
"duplicate_window_seconds": 600
},
"runtime_permissions": [
"$JS.API.CONSUMER.MSG.NEXT.ORDERS.file-orders-sink",
"$JS.API.CONSUMER.INFO.ORDERS.file-orders-sink",
"$JS.ACK.ORDERS.file-orders-sink.>",
"_INBOX.>"
]
}
See JetStream Stream Management Planning for the full operator guide and permission discussion.
nats-sink query-lineage
Queries already persisted Oracle rows by a small set of allow-listed lineage fields. This command is read-only: it does not connect to NATS, does not ACK messages, does not write to Oracle, and does not alter sink state.
Start with dry-run mode to validate the configured table, field, limit, and SQL shape without opening an Oracle connection:
nats-sink query-lineage examples/oracle-jetstream/config.json \
--field mission_id \
--value MISSION-ALPHA \
--limit 10 \
--format json \
--dry-run
The dry-run output prints bind names but not the lookup value:
{
"field": "mission_id",
"table": "NATS_SINK_EVENTS",
"limit": 10,
"payload_included": false,
"binds": ["lineage_value"],
"sql": "select ... where json_value(MISSION_METADATA_JSON, '$.mission_id') = :lineage_value ... fetch first 10 rows only"
}
Supported fields are correlation_id, causation_id, mission_id,
tasking_id, track_id, message_id, and subject. Payload output is
omitted by default. See Lineage Query Helpers for
the security model, Oracle examples, and output reference.
nats-sink replay-spool
Replays committed records from an encrypted edge spool into a final destination
sink. The first argument must be a normal configuration file whose
sink.type is spool. The second argument must be a normal configuration file
for the target sink, such as file or oracle.
nats-sink replay-spool /etc/nats-sinks/spool.json /etc/nats-sinks/oracle.json --dry-run
Example dry-run output:
Dry run complete; 128 committed spool record(s) eligible.
Replay a bounded number of records:
nats-sink replay-spool /etc/nats-sinks/spool.json /etc/nats-sinks/oracle.json --max-records 100
Example replay output:
Replay complete: scanned=100 replayed=100 deleted=100 failed=0
Replay does not ACK JetStream messages. The original ACK already happened when
the spool record was committed by nats-sink run. During replay, files are
deleted only after the target sink returns success and the spool config keeps
delete_after_replay enabled. See Edge Spool Sink for the
full delivery and security model.
nats-sink run
Starts the JetStream runner. This command opens NATS and destination connections and begins processing messages.
nats-sink run examples/file-basic/config.json --log-level INFO
Use --dry-run to validate and construct runtime objects without opening NATS or sink connections.
When metrics.enabled is true and metrics.snapshot_file is set in
configuration, run also writes a local metrics snapshot for
nats-sink-metrics:
{
"metrics": {
"enabled": true,
"namespace": "nats_sinks",
"snapshot_file": ".local/nats-sinks/metrics.json",
"event_freshness_enabled": true,
"event_stale_after_seconds": 300,
"event_future_skew_tolerance_seconds": 5
}
}
nats-sink-metrics show
Shows the status of counters, gauges, and timing observations from a local JSON snapshot. The default output is a table:
nats-sink-metrics show .local/nats-sinks/metrics.json
Example output:
KIND METRIC VALUE DESCRIPTION
counter messages_fetched_total 256 Raw JetStream messages fetched by the pull consumer.
counter messages_written_total 256 Messages reported durable by the destination sink.
counter messages_acked_total 256 Messages acknowledged to JetStream after durable success or DLQ success.
observation sink_batch_write_seconds.count 4 Elapsed seconds spent inside sink.write_batch for successful batches.
Script-friendly formats are available:
nats-sink-metrics show .local/nats-sinks/metrics.json --format shell
nats-sink-metrics show .local/nats-sinks/metrics.json --format json
nats-sink-metrics show .local/nats-sinks/metrics.json --format jsonl
nats-sink-metrics show .local/nats-sinks/metrics.json --format prometheus
nats-sink-metrics show .local/nats-sinks/metrics.json --format names
Filter and sort output:
nats-sink-metrics show .local/nats-sinks/metrics.json --kind counter
nats-sink-metrics show .local/nats-sinks/metrics.json --metric "*error*" --metric "*failed*"
nats-sink-metrics show .local/nats-sinks/metrics.json --sort value --reverse
Fail when the snapshot has gone stale:
nats-sink-metrics show .local/nats-sinks/metrics.json --stale-after-seconds 60
nats-sink-metrics get
Prints one value, which is useful in shell scripts:
failed=$(nats-sink-metrics get .local/nats-sinks/metrics.json messages_failed_total --default 0)
if [ "$failed" -gt 0 ]; then
echo "nats-sinks has failed messages"
exit 2
fi
get exits with code 4 when a metric is missing and no --default value is
provided.
nats-sink-metrics describe
Lists the metrics emitted by the framework:
nats-sink-metrics describe
nats-sink-metrics describe --format names
nats-sink-metrics describe --format json
The full metrics reference, Python hooks, staleness behavior, exit codes, and Prometheus text output examples are documented in Metrics.
nats-sink-observe init-prometheus-policy
Generates a disabled observability policy from a runtime configuration. The generated policy includes metric-sharing defaults, the configured namespace, and subject hints discovered from the config. It does not enable Prometheus sharing.
nats-sink-observe init-prometheus-policy \
/etc/nats-sinks/config.json \
/etc/nats-sinks/observability.prometheus.json \
--output-file /var/lib/node_exporter/textfile_collector/nats_sinks.prom
nats-sink-observe validate-policy
Validates a policy file before a service or operator relies on it:
nats-sink-observe validate-policy /etc/nats-sinks/observability.prometheus.json
Example output:
Observability policy is valid.
schema=nats_sinks.observability.policy.v1
enabled=false
namespace=nats_sinks
prometheus_enabled=false
otlp_enabled=false
elastic_enabled=false
grafana_alloy_enabled=false
splunk_hec_enabled=false
statsd_enabled=false
cloudwatch_enabled=false
syslog_enabled=false
nats_server_monitoring_enabled=false
nats_server_monitoring_prometheus_enabled=false
allowed_metrics=0
allowed_metric_patterns=0
denied_metrics=0
denied_metric_patterns=0
subjects=1
nats-sink-observe list-metrics
Lists metric names that can be used in an observability allow list:
nats-sink-observe list-metrics --format names
nats-sink-observe list-metrics --format json
nats-sink-observe list-subjects
Lists subject hints copied from the runtime configuration:
nats-sink-observe list-subjects \
/etc/nats-sinks/observability.prometheus.json \
--format shell
Example output:
NATS_SINKS_SUBJECT_1_ORDERS=orders.*
Current metrics are not subject-labeled. This command helps operators review policy and prepares the extension point for future subject-aware connectors.
nats-sink-observe prometheus-textfile
Renders Prometheus textfile output after applying the observability policy:
nats-sink-observe prometheus-textfile \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--output /var/lib/node_exporter/textfile_collector/nats_sinks.prom
Use --dry-run to print to stdout:
nats-sink-observe prometheus-textfile \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
The command writes only a comment when the policy is disabled. See Observability for the sharing model and its Prometheus Integration sub-page for service deployment guidance.
nats-sink-observe prometheus-http
Runs the optional native Prometheus HTTP endpoint or renders one response for
review. The endpoint is disabled unless both the top-level policy and
prometheus.http_endpoint.enabled are true:
nats-sink-observe prometheus-http \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
# HELP nats_sinks_messages_fetched_total Raw JetStream messages fetched by the pull consumer.
# TYPE nats_sinks_messages_fetched_total counter
nats_sinks_messages_fetched_total 256
Run the endpoint as a foreground process:
nats-sink-observe prometheus-http \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json
Example startup output:
Serving Prometheus metrics on 127.0.0.1:9108/metrics
Use this command as a separate service, not inside the sink worker, unless an embedding application deliberately accepts that coupling. The endpoint never ACKs messages and never connects to NATS or a destination sink.
nats-sink-observe otlp-export
Exports policy-approved metrics to an OpenTelemetry Collector through
OTLP/HTTP JSON. The command is disabled unless both the top-level
observability policy and otlp.enabled are true. It reads only the local
metrics snapshot and policy file; it does not connect to NATS, Oracle, file
sink directories, DLQ subjects, or future destination backends.
Dry-run mode prints the OTLP JSON request body without opening a network connection:
nats-sink-observe otlp-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
{"resourceMetrics":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"nats-sinks"}},{"key":"nats_sinks.namespace","value":{"stringValue":"nats_sinks"}}]},"scopeMetrics":[{"metrics":[{"description":"Raw JetStream messages fetched by the pull consumer.","name":"nats_sinks_messages_fetched_total","sum":{"aggregationTemporality":2,"dataPoints":[{"asDouble":256.0,"timeUnixNano":"1790000000000000000"}],"isMonotonic":true},"unit":"1"}],"scope":{"name":"nats-sinks.observability.otlp"}}]}]}
Live export uses the endpoint, timeout, retry, request-size, and optional header environment-variable settings from the policy:
nats-sink-observe otlp-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json
Example success output:
OTLP export: attempted=true delivered=true attempts=1 status=200 message=OTLP export delivered
Example bounded failure output:
OTLP export: attempted=true delivered=false attempts=3 status=none message=OTLP export failed with URLError
The output is intentionally sanitized. It does not print the collector URL, header values, payload bodies, subjects, table names, file paths, labels, classification values, or other sensitive deployment detail. Full connector guidance is documented in OpenTelemetry OTLP Integration.
nats-sink-observe elastic-export
Exports policy-approved metrics through the Elastic Observability OTLP profile.
The command is disabled unless both the top-level observability policy and
elastic.enabled are true. It uses the same local snapshot, allow and deny
lists, stale-snapshot checks, timeout bounds, retry bounds, and redaction
posture as the other observability connectors.
Dry-run mode prints the Elastic-profiled OTLP JSON body without opening a network connection:
nats-sink-observe elastic-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
{"resourceMetrics":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"nats-sinks"}},{"key":"nats_sinks.namespace","value":{"stringValue":"nats_sinks"}},{"key":"data_stream.dataset","value":{"stringValue":"nats_sinks.metrics"}},{"key":"data_stream.namespace","value":{"stringValue":"default"}},{"key":"nats_sinks.observability.profile","value":{"stringValue":"elastic"}}]},"scopeMetrics":[{"metrics":[{"description":"Raw JetStream messages fetched by the pull consumer.","name":"nats_sinks_messages_fetched_total","sum":{"aggregationTemporality":2,"dataPoints":[{"asDouble":256.0,"timeUnixNano":"1790000000000000000"}],"isMonotonic":true},"unit":"1"}],"scope":{"name":"nats-sinks.observability.elastic"}}]}]}
Example success output:
Elastic Observability export: attempted=true delivered=true attempts=1 status=200 message=Elastic Observability export delivered
The command is an observability connector profile, not a delivery feature. It does not ACK messages and does not write directly to Elasticsearch. Full connector guidance is documented in Elastic Observability Profile.
nats-sink-observe grafana-alloy-config
Renders a minimal Grafana Alloy River configuration snippet from the observability policy. The snippet configures an Alloy OTLP receiver, batch processor, and OTLP HTTP exporter using environment-variable references for upstream Grafana settings.
nats-sink-observe grafana-alloy-config \
/etc/nats-sinks/observability.prometheus.json
Example output:
otelcol.receiver.otlp "nats_sinks" {
http {
endpoint = "127.0.0.1:4318"
}
output {
metrics = [otelcol.processor.batch.nats_sinks_batch.input]
}
}
The rendered config is a starter snippet for operator review. It does not start Alloy and does not validate a whole Alloy deployment.
nats-sink-observe grafana-alloy-export
Exports policy-approved metrics to a Grafana Alloy OTLP receiver. The command
is disabled unless both the top-level observability policy and
grafana_alloy.enabled are true. It uses the same local snapshot, allow and
deny lists, stale-snapshot checks, timeout bounds, retry bounds, request-size
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints the Grafana Alloy-profiled OTLP JSON body without opening a network connection:
nats-sink-observe grafana-alloy-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
{"resourceMetrics":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"nats-sinks"}},{"key":"nats_sinks.namespace","value":{"stringValue":"nats_sinks"}},{"key":"nats_sinks.observability.profile","value":{"stringValue":"grafana_alloy"}},{"key":"telemetry.collector","value":{"stringValue":"grafana_alloy"}}]},"scopeMetrics":[{"metrics":[{"description":"Raw JetStream messages fetched by the pull consumer.","name":"nats_sinks_messages_fetched_total","sum":{"aggregationTemporality":2,"dataPoints":[{"asDouble":256.0,"timeUnixNano":"1790000000000000000"}],"isMonotonic":true},"unit":"1"}],"scope":{"name":"nats-sinks.observability.grafana_alloy"}}]}]}
Example success output:
Grafana Alloy export: attempted=true delivered=true attempts=1 status=200 message=Grafana Alloy export delivered
The command is an observability connector profile, not a delivery feature. It does not ACK messages, manage Alloy, or hold downstream Grafana credentials. Full connector guidance is documented in Grafana Alloy Profile.
nats-sink-observe splunk-hec-export
Exports policy-approved aggregate metrics to Splunk HTTP Event Collector. The
command is disabled unless both the top-level observability policy and
splunk_hec.enabled are true. It uses the same local snapshot, allow and deny
lists, stale-snapshot checks, timeout bounds, retry bounds, request-size
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints the Splunk HEC JSON event body without opening a network connection or requiring the HEC token to be present:
nats-sink-observe splunk-hec-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
{"event":"metric","fields":{"metric_name:nats_sinks_messages_fetched_total":256,"nats_sinks_namespace":"nats_sinks","nats_sinks_observability_profile":"splunk_hec"},"host":"nats-sinks","source":"nats-sinks","sourcetype":"nats_sinks:metrics","time":1790000000.0}
Example success output:
Splunk HEC export: attempted=true delivered=true attempts=1 status=200 message=Splunk HEC export delivered
The command is an observability connector, not a delivery feature. It does not ACK messages, write payloads to Splunk, or expose the HEC endpoint or token in result summaries. Full connector guidance is documented in Splunk HEC Integration.
nats-sink-observe oci-monitoring-export
Exports policy-approved aggregate metrics to OCI Monitoring as custom metrics.
The command is disabled unless both the top-level observability policy and
oci_monitoring.enabled are true. It uses the same local snapshot, allow and
deny lists, stale-snapshot checks, timeout bounds, retry bounds, request-size
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints a sanitized OCI PostMetricData request body without
importing the OCI SDK or opening a network connection:
nats-sink-observe oci-monitoring-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
[{"batch_atomicity":"ATOMIC","metric_data":[{"compartment_id":"<redacted>","datapoints":[{"count":1,"timestamp":"2026-05-27T12:00:00.000Z","value":256.0}],"dimensions":{"deployment":"edge"},"name":"mission_ops_messages_fetched_total","namespace":"nats_sinks_metrics"}]}]
Example success output:
OCI Monitoring export: attempted=true delivered=true attempts=1 requests=1 metrics=1 message=OCI Monitoring export delivered
The command is an observability connector, not a delivery feature. It does not ACK messages, write payloads to OCI Monitoring, expose compartment OCIDs in dry-run output, or manage OCI IAM policies. Full connector guidance is documented in OCI Monitoring Integration.
nats-sink-observe statsd-export
Exports policy-approved metrics to a StatsD-compatible UDP listener or Unix
datagram socket. The command is disabled unless both the top-level
observability policy and statsd.enabled are true. It uses the same local
snapshot, allow and deny lists, stale-snapshot checks, timeout bounds, retry
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints StatsD lines without opening a socket:
nats-sink-observe statsd-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
nats_sinks.messages_fetched_total:256|g
nats_sinks.messages_acked_total:256|g
Example success output:
StatsD export: attempted=true delivered=true attempts=1 datagrams=2 message=StatsD export delivered
The command is an observability connector, not a delivery feature. StatsD transport is best-effort, so successful local sending must not be treated as durable telemetry custody. Full connector guidance is documented in StatsD Integration.
nats-sink-observe datadog-export
Exports policy-approved metrics as DogStatsD datagrams to a local or explicitly
approved Datadog Agent listener. The command is disabled unless both the
top-level observability policy and datadog.enabled are true. It uses the same
local snapshot, allow and deny lists, stale-snapshot checks, timeout bounds,
retry bounds, datagram-size bounds, and redaction posture as the other
observability connectors.
Dry-run mode prints DogStatsD lines without opening a socket:
nats-sink-observe datadog-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
nats_sinks.messages_fetched_total:256|g|#environment:test,service:nats-sinks
nats_sinks.messages_acked_total:256|g|#environment:test,service:nats-sinks
Example success output:
Datadog export: attempted=true delivered=true attempts=1 datagrams=2 message=Datadog export delivered
The command is an observability connector, not a delivery feature. DogStatsD transport is best-effort, Datadog tags are opt-in and bounded, and successful local sending must not be treated as durable telemetry custody. Full connector guidance is documented in Datadog Integration.
nats-sink-observe cloudwatch-export
Exports policy-approved metrics to Amazon CloudWatch custom metrics through
PutMetricData. The command is disabled unless both the top-level
observability policy and cloudwatch.enabled are true. It uses the same local
snapshot, allow and deny lists, stale-snapshot checks, timeout bounds, retry
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints the CloudWatch request list without importing boto3, loading AWS credentials, or calling AWS:
nats-sink-observe cloudwatch-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
[
{
"MetricData": [
{
"MetricName": "nats_sinks_messages_fetched_total",
"StorageResolution": 60,
"Unit": "None",
"Value": 256.0
}
],
"Namespace": "nats-sinks/metrics"
}
]
Example success output:
Amazon CloudWatch export: attempted=true delivered=true attempts=1 requests=1 metrics=1 message=Amazon CloudWatch export delivered
The command is an observability connector, not a delivery feature. Successful
local export means the AWS SDK accepted the PutMetricData call; it does not
prove alert evaluation, dashboard rendering, or downstream retention. Full
connector guidance is documented in
Amazon CloudWatch Integration.
nats-sink-observe azure-monitor-export
Exports policy-approved metrics to Azure Monitor custom metrics through the
regional Azure Monitor REST endpoint for one reviewed Azure resource. The
command is disabled unless both the top-level observability policy and
azure_monitor.enabled are true. It uses the same local snapshot, allow and
deny lists, stale-snapshot checks, timeout bounds, retry bounds, request-size
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints the Azure Monitor request bodies without loading a bearer token or calling Azure:
nats-sink-observe azure-monitor-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
[
{
"data": {
"baseData": {
"dimNames": [
"deployment"
],
"metric": "nats_sinks_messages_fetched_total",
"namespace": "nats-sinks/metrics",
"series": [
{
"count": 1,
"dimValues": [
"edge"
],
"max": 256.0,
"min": 256.0,
"sum": 256.0
}
]
}
},
"time": "2026-05-28T12:00:00.000Z"
}
]
Example success output:
Azure Monitor export: attempted=true delivered=true attempts=1 requests=1 metrics=1 status=200 message=Azure Monitor export delivered
The command is an observability connector, not a delivery feature. Successful local export means Azure Monitor accepted the HTTP request; it does not prove alert evaluation, dashboard rendering, or downstream retention. Full connector guidance is documented in Azure Monitor Integration.
nats-sink-observe syslog-export
Exports policy-approved metrics as RFC 5424-style syslog messages over UDP or
a Unix datagram socket. The command is disabled unless both the top-level
observability policy and syslog.enabled are true. It uses the same local
snapshot, allow and deny lists, stale-snapshot checks, timeout bounds, retry
bounds, and redaction posture as the other observability connectors.
Dry-run mode prints syslog messages without opening a socket:
nats-sink-observe syslog-export \
/var/lib/nats-sink/metrics.json \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
<134>1 2026-09-21T14:13:20.000Z - nats-sinks - metrics [nats_sinks metric="messages_fetched_total" kind="counter" value="256" namespace="nats_sinks" profile="syslog"] -
<134>1 2026-09-21T14:13:20.000Z - nats-sinks - metrics [nats_sinks metric="messages_acked_total" kind="counter" value="256" namespace="nats_sinks" profile="syslog"] -
Example success output:
Syslog export: attempted=true delivered=true attempts=1 messages=2 message=Syslog export delivered
The command is an observability connector, not a delivery feature. Syslog transport is best-effort, messages are bounded and sanitized, and successful local sending must not be treated as durable telemetry custody. Full connector guidance is documented in Syslog Bridge.
nats-sink-observe nats-monitoring-poll
Polls policy-approved NATS server monitoring endpoints and writes a sanitized
local snapshot. This command is disabled unless the top-level observability
policy and nats_server_monitoring.enabled are true.
nats-sink-observe nats-monitoring-poll \
/etc/nats-sinks/observability.prometheus.json \
--output /var/lib/nats-sink/nats-monitoring.json
Use --dry-run to review the snapshot without writing a file:
nats-sink-observe nats-monitoring-poll \
/etc/nats-sinks/observability.prometheus.json \
--dry-run
Example dry-run output:
{
"schema": "nats_sinks.observability.nats_monitoring.snapshot.v1",
"generated_at_epoch_seconds": 1797820000.0,
"endpoints": [
{
"endpoint": "/jsz",
"status_code": 200,
"fields": {
"jetstream.stats.messages": 42,
"jetstream.stats.consumer_count": 3
}
}
]
}
The snapshot does not include the configured monitoring base URL. It includes only endpoint paths and the scalar fields selected by policy.
nats-sink-observe nats-monitoring-prometheus
Renders selected numeric NATS monitoring values as Prometheus text. This command
is disabled unless nats_server_monitoring.prometheus_enabled is true.
nats-sink-observe nats-monitoring-prometheus \
/var/lib/nats-sink/nats-monitoring.json \
/etc/nats-sinks/observability.prometheus.json \
--output /var/lib/node_exporter/textfile_collector/nats_sinks_nats_monitoring.prom
Example output:
# HELP nats_sinks_nats_monitoring_jsz_jetstream_stats_messages NATS server monitoring value for /jsz field jetstream.stats.messages
# TYPE nats_sinks_nats_monitoring_jsz_jetstream_stats_messages gauge
nats_sinks_nats_monitoring_jsz_jetstream_stats_messages 42
String values such as server identifiers are not rendered to Prometheus. They remain in the local snapshot only when explicitly allowed by policy.
CLI Flow
sequenceDiagram
participant U as User
participant C as CLI
participant CFG as JSON Config
participant S as Sink Registry
participant R as Runner
U->>C: nats-sink run config.json
C->>CFG: Load and validate
C->>S: Create selected sink
C->>R: Build runner
R->>R: Connect, consume, write, ACK last
The CLI returns non-zero for validation and runtime failures. It never prints resolved passwords.
nats-sink-metrics returns 0 on success, 2 for invalid snapshot or display
input, 3 for stale snapshots when staleness is enforced, and 4 when get
cannot find a metric without a default value.
nats-sink-observe returns 0 on success, 2 for invalid configuration,
policy, snapshot, textfile output errors, disabled native endpoint startup, or
profile render errors, and 3 when an enabled Prometheus HTTP dry-run returns
an error response, a stale snapshot is rejected, or an enabled OTLP, Elastic,
Grafana Alloy, Splunk HEC, OCI Monitoring, StatsD, Datadog, Amazon CloudWatch,
Azure Monitor, or syslog export exhausts bounded delivery attempts.