Skip to main content
Routing controls where your data goes. Each batch from a source is matched against rules you define, and the matched rule determines which sinks receive it. You can send the same data to multiple sinks (fan-out) and attach transforms to specific routes.

Quick start

The simplest setup sends everything to one sink:
[routing]
default = ["clickhouse"]
All data from all sources goes to the ClickHouse sink. No rules needed.

Adding rules

Rules match data by source and send it to specific sinks. Rules are evaluated top to bottom — the first match wins.
[routing]
default = ["clickhouse"]

[[routing.rules]]
match = { source_type = "syslog" }
sinks = ["clickhouse", "logs"]

[[routing.rules]]
match = { source = "tcp_debug" }
sinks = ["stdout"]
In this example:
  • Syslog data (both TCP and UDP) goes to ClickHouse and the disk sink — fan-out to two destinations
  • The debug source goes to stdout only
  • Everything else (TCP from SDKs, HTTP) falls through to the default: ClickHouse

Match conditions

Each rule has a match object with one or both of these fields:
FieldMatches
sourceExact source name — "tcp", "tcp_debug", "syslog_tcp", "syslog_udp", "http"
source_typeSource type — "tcp" matches all TCP sources, "syslog" matches both syslog TCP and UDP
If you specify both fields, both must match (AND logic).
# Match only the primary TCP source
[[routing.rules]]
match = { source = "tcp" }
sinks = ["clickhouse"]

# Match all syslog sources (tcp + udp)
[[routing.rules]]
match = { source_type = "syslog" }
sinks = ["clickhouse", "logs"]

Evaluation order

  1. Rules are checked in the order they appear in the config file
  2. The first matching rule wins — no further rules are evaluated
  3. If no rule matches, data goes to the default sinks
  4. If no rule matches and default is empty, the data is dropped
Put specific rules (matching exact source names) before broad rules (matching source types) to avoid early matches swallowing everything.

Fan-out

A single rule can send data to multiple sinks:
[[routing.rules]]
match = { source_type = "syslog" }
sinks = ["clickhouse", "disk_logs", "forwarder"]
Tell delivers to all three sinks without copying the data. If one sink is slow or down, the others still receive their copy — fan-out is independent per sink.

Adding transforms

Attach transforms to a routing rule to process data before it reaches sinks. Transforms run in order.
[[routing.rules]]
match = { source_type = "syslog" }
sinks = ["clickhouse", "logs"]

[[routing.rules.transformers]]
type = "pattern_matcher"

[[routing.rules.transformers]]
type = "redact"
strategy = "hash"
hash_key = "your-secret"
patterns = ["email", "ipv4"]
This extracts log patterns first, then redacts PII, then writes to both sinks. See Transforms for available transform types and their configuration.

Common patterns

Analytics + archival: Send SDK data to ClickHouse for queries and Parquet for long-term storage.
[[routing.rules]]
match = { source = "tcp" }
sinks = ["clickhouse", "archive"]
Separate log handling: Route syslog through pattern extraction to ClickHouse, while SDK events skip transforms.
[routing]
default = ["clickhouse"]

[[routing.rules]]
match = { source_type = "syslog" }
sinks = ["clickhouse"]

[[routing.rules.transformers]]
type = "pattern_matcher"
Edge forwarding: Forward all data to a central Tell server.
[routing]
default = ["upstream"]