Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Logging and Observability

ndn-rs uses the tracing crate for structured, target-routed logging. Every event carries a target: string drawn from a 26-entry taxonomy, which lets operators select exactly the subsystems they care about without wading through unrelated output.

Quick start

# Show only pipeline and PIT events at trace level.
RUST_LOG=fwd.pipeline=trace,fwd.pit=debug ndn-fwd -c router.toml

# Show all face-system events at debug, everything else at info.
RUST_LOG=info,face.system=debug ndn-fwd -c router.toml

The RUST_LOG syntax is the standard EnvFilter directive format: target=level[,target=level,...].

Log-target taxonomy

Print the full taxonomy at any time:

$ ndn-fwd --modules
fwd.pipeline
fwd.pit
fwd.cs
fwd.fib
fwd.strategy
face.tcp
face.udp
face.ws
face.lp
face.eth
face.system
mgmt.rib
mgmt.face
mgmt.fib
mgmt.cs
mgmt.strategy
mgmt.log
mgmt.security
mgmt.status
routing.dvr
routing.nlsr
sync.svs
sync.psync
security
engine
discovery

The same list is available at runtime via the management API:

$ ndn-tools interest /localhost/nfd/log/modules

Target reference

TargetSubsystem
fwd.pipelinePer-packet pipeline stages (decode → CS → PIT → strategy)
fwd.pitPIT insert / expire / satisfy events
fwd.csContent Store hit / miss / eviction
fwd.fibFIB nexthop lookup, add, remove
fwd.strategyStrategy decisions (best-route, multicast, …)
face.tcpTCP unicast face send / receive
face.udpUDP unicast and multicast face send / receive
face.wsWebSocket face send / receive
face.lpNDNLPv2 framing, fragmentation, reassembly
face.ethRaw Ethernet face send / receive
face.systemFace lifecycle (bind, connect, BLE, serial, hotplug)
mgmt.ribRIB register / unregister commands
mgmt.faceFace create / destroy commands
mgmt.fibFIB add-nexthop / remove-nexthop commands
mgmt.csCS config / erase commands
mgmt.strategyStrategy-choice set / unset commands
mgmt.logLog set-filter / get-filter commands
mgmt.securitySecurity identity, key, schema, CA commands
mgmt.statusStatus dataset and shutdown commands
routing.dvrDistance-vector routing protocol events
routing.nlsrNLSR link-state routing protocol events
sync.svsStateVectorSync events
sync.psyncPSync events
securitySignature verification and trust-anchor events
engineEngine lifecycle, config loading, fatal errors
discoveryNeighbor discovery and service discovery events

Changing the filter at runtime

The filter can be reloaded without restarting the forwarder:

ndn-tools command /localhost/nfd/log/set-filter \
  Uri fwd.pipeline=trace,mgmt.face=debug

Read the current filter:

ndn-tools interest /localhost/nfd/log/get-filter

Structured fields

Events include machine-readable fields alongside the human message, making them easy to parse with tools like jq when the formatter is set to JSON:

RUST_LOG=fwd.pipeline=trace RUST_LOG_FORMAT=json ndn-fwd -c router.toml \
  | jq 'select(.target == "fwd.pipeline")'

Typical pipeline event fields: name (NDN Name), face (FaceId), nonce, len (bytes).

Log file

Configure a persistent log file in router.toml:

[logging]
level = "info"
file  = "/var/log/ndn-fwd/ndn-fwd.log"

File writes are non-blocking — log events never stall the forwarding pipeline.