Introduction to Netprobe Router
Introduction Copied
The Netprobe Router is a standalone application purpose-built for high-throughput forwarding of streaming telemetry data. It supports both the ITRS internal streaming protocol and OpenTelemetry Protocol (OTLP). It passes data through in its original protobuf wire format, applying only lightweight routing rules to determine which destinations receive which data. Telemetry can include metrics, logs, and traces depending on what the senders publish.
Use the Netprobe Router when you want to:
- Forward telemetry received through the ITRS internal ingestion service or OTLP to one or more downstream destinations with minimal latency.
- Apply routing rules, such as filtering, duplicating, or selectively splitting telemetry flows, without modifying the telemetry payload (no normalization, enrichment, or transformation).
- Simplify network layout by concentrating outbound connectivity in one place.
- Ensure reliable delivery to ITRS Analytics or other downstream destinations by using store-and-forward: persist batches to disk when a reporter is unavailable and replay them when connectivity returns.
Routing components Copied
The Netprobe Router processes telemetry by using three routing components:
RoutingCollector— Receives inbound streaming telemetry on a single gRPC port (ITRS ingestion and OTLP). It is the only collector that feeds the routing pipeline; one router process needs only one instance.RoutingWorkflow— Evaluates routes for each incoming batch. It forwards all data or applies conditions based on fields such as data type, name, dimensions, properties, severity, and value.RoutingReporter— Forwards telemetry to a downstream destination (one plugin instance per target, outbound gRPC to hostname and port). Optionally enables store-and-forward to buffer batches on disk when the destination is unavailable and replay them when connectivity returns.
Note
This guide refers to the three routing components by name:RoutingCollector(receives data),RoutingReporter(sends data onward), andRoutingWorkflow(applies routing rules). In your YAML configuration, these appear undercollectorsandreportersusingclassName(for example,className: RoutingCollectorandclassName: RoutingReporter). The routing pipeline itself is configured under the top-level keyroutingWorkflow(camelCase).
How the Netprobe Router works Copied
In practical terms, the router sits between a sender and one or more recipients.
The routing process is:
- A sender, such as a Gateway, Netprobe, or other Collection Agent component, opens a single connection to the router.
RoutingCollectorreceives the telemetry on a single gRPC endpoint.RoutingWorkflowevaluates the configured routes for each incoming batch.- Every matching
RoutingReporterforwards the telemetry to its configured destination.
The Netprobe Router supports two delivery modes:
- Best-effort — Attempts delivery once. If the destination is unavailable, the data is dropped.
- Store-and-forward — Persists telemetry to disk and retries delivery until it succeeds.
Important
Store-and-forward delivery mode helps prevent data loss during downstream outages but requires sufficient disk capacity. If the configured store reaches capacity, new data is dropped.
Geneos use cases Copied
Geneos environments commonly publish telemetry to ITRS Analytics by using gRPC over HTTP/2. The Netprobe Router provides a dedicated routing layer between Geneos components and ITRS Analytics.
Route multiple Gateways and Netprobes through one connection Copied
Use the Netprobe Router as a single managed egress point for multiple Gateways and Netprobes. Instead of opening separate outbound connections from many monitored systems to ITRS Analytics, those components connect to a single router, which maintains the downstream connection.
Use this approach when:
- You want to simplify firewall rules.
- Outbound connectivity to ITRS Analytics must be tightly controlled.
- The ITRS Analytics endpoint is external, and you want to centralize access through a small number of managed hosts.
- You want to manage TLS certificates, credentials, and endpoint changes in one place instead of on every sender.
Route telemetry to multiple receivers Copied
The Netprobe Router can forward the same Geneos telemetry stream to multiple receivers.
Use this capability to:
- Send the same telemetry to multiple ITRS Analytics environments.
You can also route different data types to different receivers. For example, you can send metrics to one destination and log events to another.
Store and forward Copied
Configure the Netprobe Router to persist telemetry batches to disk before forwarding them. This provides at-least-once delivery semantics for each configured recipient.
Use this capability when:
- Temporary downstream outages must not cause data loss.
- Network connectivity to ITRS Analytics is unreliable or intermittent.
- Each recipient requires independent retry behavior.
- You want the router to survive restarts and continue replaying undelivered batches.
Important
Store-and-forward delivery mode helps prevent data loss during downstream outages but requires sufficient disk capacity. If the configured store reaches capacity, new data is dropped.
Run the local examples Copied
The package includes Unix example harnesses under examples/unix. Each subdirectory is self-contained: router-config.yaml (or router1-config.yaml and router2-config.yaml for chained routers), router.sh (or router1.sh and router2.sh), logback.xml, sender and receiver scripts, and a README.txt that describes that harness. The following descriptions correspond to the files included in the package.
All Unix examples use the same sender, which simulates a simple Geneos telemetry stream:
- One
gaugemetric every second, namedsome.gauge - One
log_eventevery second, namedsome.log - Both data points use the
simple-examplenamespace - Both data points include the dimension
service.name=simple-example-sender - The log event has
infoseverity and an incrementing message body
Before running any example:
- Edit
examples/unix/env.shand set theJAVAvariable for your environment. - Open one terminal per process you want to run.
- Start each script from its own example directory.
One-to-one Copied
Location: examples/unix/one-to-one
This example routes all synthetic telemetry to a single test receiver by using best-effort delivery. If the receiver is unavailable, data is dropped until it becomes available again. For more information, see README.txt in the directory.
Use this example to verify the basic data path:
- Run
router.sh. - Run
receiver.sh. - Run
sender.sh.
Expected behavior:
- The
receiverprints both the synthetic gauge stream and the synthetic log stream (one pass-through route). - Router
selfMetricsand workflow output go tostdoutthrough the logging reporter. - Best-effort delivery — if you stop the receiver, routed data is dropped until it is available again.
Self-monitoring configuration Copied
This example enables selfMetrics, which reports operational metrics about the router itself. These metrics are sent through the standard workflow to stdout and are separate from the RoutingWorkflow, which forwards inbound telemetry. That keeps the harness easy to read when you run it in a terminal.
monitoring:
healthProbe:
enabled: false
selfMetrics:
enabled: true
dimensions:
hostname: ${env:HOSTNAME}
app: ${env:APP}
workflow:
storeDirectory: .
metrics:
reporter: stdout
logs:
reporter: stdout
events:
reporter: stdout
attributes:
reporter: stdout
The following is an entry in the top-level reporters list, alongside plugin reporters such as RoutingReporter:
- type: logging
name: stdout
Together, these pieces do the following:
monitoring.healthProbedisables the optional HTTP health endpoint so the example stays minimal.monitoring.selfMetricsenables router self-metrics and addshostnameandapplabels from the environment variables. Those dimensions identify the router instance if you later pointselfMetricsat Geneos. For more information, see Self-monitoring configuration and the One-to-many self-monitoring example.workflowselects where each standard workflow channel is sent. Every channel (metrics,logs,events,attributes) uses the reporter namedstdout, andstoreDirectorysets the on-disk root for any workflow persistence the agent needs.- Top-level
reporters(type: logging,name: stdout) define the logging reporter that the workflow references. Log lines for router-local metrics, logs, events, and attributes are printed to the process standard output instead of being sent over TCP or another sink.
This path is not the routed application traffic but is the router’s own telemetry and diagnostics. The streaming path from senders to downstream recipients is RoutingWorkflow together with the RoutingCollector and RoutingReporter plugins. For more information, see Routing Collector configuration and Routing Reporter configuration.
Routing configuration Copied
The following configuration defines how the router receives, routes, and forwards streaming telemetry. These subsections follow the logical pipeline order:
collectorsentry (RoutingCollector)routingWorkflowblock (RoutingWorkflow)reporters(includingRoutingReporter)
Note
Theone-to-oneexample configuration file might list these YAML blocks in a different order. The Collection Agent still loads the full configuration before it starts.
collectors — receive inbound streaming telemetry:
collectors:
- type: plugin
name: routing-grpc
className: RoutingCollector
port: 4317
RoutingWorkflow — defines how each batch is dispatched to named RoutingReporter destinations:
routingWorkflow:
routes:
- reporters: [receiver]
The following is an entry in the top-level reporters list. It defines the downstream routing destination that routes refer to by name (receiver), alongside any other reporters such as the logging stdout reporter used for self-monitoring:
- type: plugin
name: receiver
className: RoutingReporter
hostname: localhost
port: 4318
usePlainText: true
useCompression: true
This configuration does the following:
RoutingCollectorlistens on port 4317 for gRPC (ITRS ingestion and OTLP on the same port). This port is the only ingress into the routing pipeline for this example. For more information, see Routing Collector configuration.RoutingWorkflowdefines how batches from theRoutingCollectorare dispatched. A single route withreporters: [receiver]and noanyorallconditions forwards every incoming batch to the reporter namedreceiver. For more information, see Routing workflow configuration and Routes.- Top-level
reporters(RoutingReporternamedreceiver) opens an outbound gRPC client to localhost:4318 (the test receiver).usePlainText: truedisables TLS for the local harness;useCompression: trueenables compression on a typical production-style stream. For more information, see Routing Reporter configuration.
Chained routers Copied
Location: examples/unix/chained-routers
This example runs two router processes in series: sender > router 1 (first hop) > router 2 (second hop) > receiver. Each hop uses the same pattern as One-to-one, with best-effort delivery. Each router uses its own workflow.storeDirectory (router1-workflow-store, router2-workflow-store) so both processes can run from this folder without clashing. For more information, see README.txt in the directory.
The following table lists each hop and port (plain-text gRPC, compressed like One-to-one):
| Hop | Role | Port |
|---|---|---|
| sender > router 1 | RoutingCollector on router 1 |
4317 |
| router 1 > router 2 | RoutingReporter > RoutingCollector on router 2 |
4320 |
| router 2 > receiver | RoutingReporter > test receiver |
4318 |
Self-monitoring in this example matches One-to-one: monitoring, workflow, logging stdout, and one RoutingCollector YAML block per router. The router1.sh and router2.sh scripts set APP to netprobe-router-chain-1 and netprobe-router-chain-2 so selfMetrics labels distinguish the two processes.
Use this example to verify a multi-hop routing path. Start downstream processes first, then work back toward the sender:
- Run
receiver.sh. - Run
router2.sh(router 2 must accept traffic from router 1 before you rely on end-to-end delivery). - Run
router1.sh. - Run
sender.sh.
Expected behavior:
- The
receiverprints both the synthetic gauge stream and the synthetic log stream after two router hops. - Router
selfMetricsand standard workflow output for each process go tostdoutin its own terminal. - Best-effort delivery on each hop — if router 2 or the receiver is down, router 1 may drop batches per its reporter’s circuit breaker. If router 2 is up but the receiver is down, router 2 drops until the receiver is available again.
Router 1 configuration Copied
Ingress matches the other examples; egress targets the second router’s collector:
routingWorkflow:
routes:
- reporters: [router-2]
reporters:
- type: plugin
name: router-2
className: RoutingReporter
hostname: localhost
port: 4320
usePlainText: true
useCompression: true
collectors:
- type: plugin
name: routing-grpc
className: RoutingCollector
port: 4317
Router 2 configuration Copied
The collector listens on 4320. The pass-through route forwards everything to the test receiver on 4318 (similar to One-to-one routing):
routingWorkflow:
routes:
- reporters: [receiver]
reporters:
- type: plugin
name: receiver
className: RoutingReporter
hostname: localhost
port: 4318
usePlainText: true
useCompression: true
collectors:
- type: plugin
name: routing-grpc
className: RoutingCollector
port: 4320
One-to-many Copied
Location: examples/unix/one-to-many
This example routes synthetic telemetry to two test receivers (gauges to receiver-1, log events to receiver-2) with best-effort delivery. For more information, see README.txt in the directory.
Self-monitoring and ingress in this example match One-to-one: monitoring, workflow, logging stdout, and one RoutingCollector on port 4317. The Conditional route configuration and Multiple routing reporter configuration sections describe the changes (conditional routes and multiple RoutingReporter plugins).
Use this example to verify conditional routing:
- Run
router.sh. - Run
receiver-1.sh. - Run
receiver-2.sh. - Run
sender.sh.
Expected behavior:
- receiver-1 prints the synthetic metric stream only.
- receiver-2 prints the synthetic log stream only.
- The sender continues to emit both data types through the same inbound router connection.
Conditional route configuration Copied
There are two pass-through routes instead of one. Each route names a different downstream reporter and uses scope: first with a type condition so each batch is classified from its first data point (the harness sends one logical type per batch). For more information, see Routes and Routing conditions.
routingWorkflow:
routes:
- reporters: [receiver-1]
scope: first
any:
- field: type
operator: eq
value: gauge
- reporters: [receiver-2]
scope: first
any:
- field: type
operator: eq
value: log_event
In this configuration, the first route sends gauge batches to receiver-1, and the second route sends log-event batches to receiver-2. Routes are evaluated independently (multi-route evaluation). Both routes can match different batches from the same sender connection over time.
scope: first means only the first data point in the batch is tested. If it matches, the whole batch follows that route. This is appropriate in this example because each batch is homogeneous.
Multiple routing reporter configuration Copied
The top-level reporters list defines two RoutingReporter plugins. Each destination has its own hostname, port, and plain-text/compression settings:
- type: plugin
name: receiver-1
className: RoutingReporter
hostname: localhost
port: 4318
usePlainText: true
useCompression: true
- type: plugin
name: receiver-2
className: RoutingReporter
hostname: localhost
port: 4319
usePlainText: true
useCompression: true
receiver-1 and receiver-2 are the names referenced by the reporters field on each route in routingWorkflow.routes. They listen on ports 4318 and 4319 so two test receivers can run side by side.
For full RoutingReporter configuration, see Routing Reporter configuration.
One-to-many store-and-forward Copied
Location: examples/unix/one-to-many-store-and-forward
This example routes traffic the same way as One-to-many, but each RoutingReporter enables store-and-forward. Stop a receiver and restart it to see replay. Use cleanup.sh to reset on-disk state between runs. For more information, see README.txt in the directory.
Use this example to verify resilient delivery:
- Run
router.sh. - Run
receiver-1.sh. - Run
receiver-2.sh. - Run
sender.sh. - Stop one receiver while the sender keeps running.
- Restart the stopped receiver.
Expected behavior:
- If receiver-1 stops, the synthetic metric traffic is buffered for replay.
- If receiver-2 stops, the synthetic log traffic is buffered for replay.
- When a stopped receiver comes back, the router replays the undelivered batches for that route.
Reporters with store-and-forward configuration Copied
The top-level reporters list matches One-to-many, except that each RoutingReporter includes a storeAndForward block. This example sets only enabled: true while all other store settings use their defaults, including the store root directory.
- type: plugin
name: receiver-1
className: RoutingReporter
hostname: localhost
port: 4318
usePlainText: true
useCompression: true
storeAndForward:
enabled: true
- type: plugin
name: receiver-2
className: RoutingReporter
hostname: localhost
port: 4319
usePlainText: true
useCompression: true
storeAndForward:
enabled: true
storeAndForward.enabled: true turns on disk-backed queuing and retries for that destination only. The gauge route still targets receiver-1 and the log route still targets receiver-2, so metric and log backlogs stay separate per reporter.
Note
Each reporter delivers independently. One stopped receiver does not block live delivery to the other. Each reporter has its own store and retry loop.
On disk, each RoutingReporter store lives under storeAndForward.directory (default: process working directory). For more information, see Store-and-forward delivery.
One-to-many self-monitoring Copied
Location: examples/unix/one-to-many-self-monitoring
In this example, the router accepts streaming telemetry on the RoutingCollector port (4317) and forwards it to two test receivers (receiver-1 on 4318, receiver-2 on 4319) by using two unconditional routes in RoutingWorkflow (all data goes to both receivers). Self-monitoring is enabled, and the standard workflow sends self-metrics through the TCP reporter netprobe-reporter to localhost:9137 for Gateway and Netprobe. For more information, see README.txt and gateway.setup.xml in the directory.
Compared to One-to-many, streaming ingress, RoutingWorkflow, and RoutingReporter destinations are unchanged. What changes is the standard workflow (from stdout to tcp), a new tcp reporter, and gateway.setup.xml so Gateway can map hostname and app labels onto entities and samplers. monitoring.selfMetrics and router.sh still supply those dimensions (APP=netprobe-router-multi, HOSTNAME from the host). For more information, see Self-monitoring configuration.
Note
The checked-inroutingWorkflowconfiguration in this example defines two unconditional routes, so each batch is delivered to both receiver-1 and receiver-2 (multi-route evaluation). Copy the conditional routes from One-to-many if you want agaugeversuslog_eventsplit instead.
Setup on one machine (router, Netprobe, Gateway) Copied
As described in README.txt, run Gateway (with the checked-in gateway.setup.xml), then Netprobe, then router.sh, both receivers, and sender.sh on one host so localhost and 9137 line up.
Use this example to verify routing and observability together:
- Copy gateway.setup.xml into the Gateway program directory, then run
./gateway2.linux_64 -demoto start the Gateway. - Run
./netprobe.linux_64to start the Netprobe on the default port (7036). The Netprobe listens for Collection Agent on9137, as configured in gateway.setup.xml. - Run
router.sh. - Run
receiver-1.shandreceiver-2.sh. - Run
sender.sh. - Open Active Console (or your Geneos UI) against the Gateway and confirm Dynamic Entities for the router’s
selfMetrics.
Expected behavior:
- Routed telemetry appears at both receivers (two unconditional routes in
RoutingWorkflow). If you chose thegaugeversuslog_eventsplit, receiver-1 prints the synthetic metric stream only and receiver-2 prints the synthetic log stream only. - Self-metrics appear in Gateway (Dynamic Entities) with
hostnameandappfrom the router environment.
Standard workflow configuration Copied
All four workflow channels use the TCP reporter named netprobe-reporter instead of stdout:
workflow:
storeDirectory: .
metrics:
reporter: netprobe-reporter
logs:
reporter: netprobe-reporter
events:
reporter: netprobe-reporter
attributes:
reporter: netprobe-reporter
reporter: netprobe-reporter sets each channel’s processed output through the TCP reporter named netprobe-reporter. For more information, see Workflow configuration.
storeDirectory is the working-directory root for any workflow persistence the agent requires (same role as in the other examples).
TCP reporter configuration Copied
The following entry is added to the top-level reporters list, alongside the same logging stdout and RoutingReporter definitions as One-to-many:
- type: tcp
name: netprobe-reporter
hostname: localhost
port: 9137
The tcp reporter named netprobe-reporter defines the TCP sink the workflow uses when each channel sets reporter: netprobe-reporter. Traffic goes to localhost:9137, which must match the Netprobe Collection Agent reporter and reporterPort in gateway.setup.xml. For more information, see Gateway reporter.
Gateway setup Copied
The following Geneos configuration (gateway.setup.xml) pairs with the router’s tcp reporter and the hostname and app dimensions:
<?xml version="1.0" encoding="ISO-8859-1"?>
<gateway compatibility="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.itrsgroup.com/GA7.9.0-260414/gateway.xsd">
<probes>
<probe name="localhost">
<hostname>localhost</hostname>
<dynamicEntities>
<mappingType ref="Router Mapping"/>
<collectionAgentParameters ref="CA"/>
</dynamicEntities>
</probe>
</probes>
<dynamicEntities>
<simpleMappings>
<mapping name="Router Mapping">
<custom>
<geneosItems>
<geneosItem>
<label>hostname</label>
<entity>
<required>true</required>
<useInDisplayName>true</useInDisplayName>
</entity>
</geneosItem>
<geneosItem>
<label>app</label>
<sampler/>
</geneosItem>
</geneosItems>
</custom>
</mapping>
</simpleMappings>
<mappingTypes>
<mappingType name="Router Mapping">
<mappings>
<mapping ref="Router Mapping"/>
</mappings>
</mappingType>
</mappingTypes>
<collectionAgentParameters>
<collectionAgentParameters name="CA">
<unmanaged/>
<reporterPort>9137</reporterPort>
</collectionAgentParameters>
</collectionAgentParameters>
</dynamicEntities>
<operatingEnvironment>
<gatewayName>Demo Gateway</gatewayName>
</operatingEnvironment>
</gateway>
The reporterPort value of 9137 in collectionAgentParameters must match the router TCP reporter port.
Router Mapping maps hostname and app from monitoring.selfMetrics.dimensions to the entity and sampler. For more information, see README.txt in the directory.
For TLS and authentication, see Security. For production YAML settings, see Configuration. To diagnose common problems, see Troubleshooting.
See also Copied
- Introduction to Collection Agent (workflows, reporters, monitoring)
- Collection Agent configuration reference