Monad Data Routing Reference
Data routing enables conditional delivery of records to different outputs based on record content. Every edge in your pipeline is a routing rule.
Core Concept
-
Each edge evaluates independently
-
Records can match multiple edges (fan-out)
-
No circular routing (DAG structure)
Edge Structure
Edges connect nodes with optional conditions:
{
"from": "transform-normalize",
"to": "output-sentinel-analytics",
"name": "Critical Events",
"conditions": {
"operator": "or",
"conditions": [
{"type": "equals", "key": "severity", "value": "critical"},
{"type": "equals", "key": "severity", "value": "high"}
]
}
}
Logical Operators
Operators combine multiple conditions.
| Operator | Function | Min Conditions |
|---|---|---|
|
Route ALL records (pass-through) |
0 |
|
Block ALL records |
0 |
|
ALL conditions must be true |
1+ |
|
At least ONE condition true |
2+ |
|
NONE of the conditions true |
1+ |
|
EXACTLY ONE condition true |
2+ |
Operator Examples
Pass-through (all records):
{
"operator": "always",
"conditions": []
}
Multi-criteria AND:
{
"operator": "and",
"conditions": [
{"type": "equals", "key": "source", "value": "ise"},
{"type": "equals", "key": "result", "value": "fail"}
]
}
Multi-criteria OR:
{
"operator": "or",
"conditions": [
{"type": "equals", "key": "severity", "value": "critical"},
{"type": "equals", "key": "severity", "value": "high"},
{"type": "contains", "key": "message", "value": "intrusion"}
]
}
Exclusion (NOR):
{
"operator": "nor",
"conditions": [
{"type": "equals", "key": "event_type", "value": "heartbeat"},
{"type": "equals", "key": "event_type", "value": "keepalive"}
]
}
Condition Types
Nine condition types for flexible routing.
Value Matching
equals - Exact value match
{"type": "equals", "key": "status", "value": "denied"}
equals_any - Match any value in list
{"type": "equals_any", "key": "severity", "values": ["critical", "high", "medium"]}
String Operations
contains - Substring match
{"type": "contains", "key": "message", "value": "authentication failed"}
starts_with - Prefix match
{"type": "starts_with", "key": "user", "value": "admin_"}
ends_with - Suffix match
{"type": "ends_with", "key": "filename", "value": ".exe"}
matches_regex - Regular expression match
{"type": "matches_regex", "key": "ip", "pattern": "^10\\.50\\.1\\.\\d+$"}
Numeric Comparison
greater_than - Numeric greater than
{"type": "greater_than", "key": "failed_attempts", "value": 5}
less_than - Numeric less than
{"type": "less_than", "key": "response_time_ms", "value": 100}
Sampling
sample - Percentage-based or key-based sampling
{"type": "sample", "percentage": 10}
{"type": "sample", "key": "user_id", "percentage": 5}
Routing Patterns
Pattern 1: Critical vs Bulk Split
Route security events to expensive analytics tier, bulk to cheap storage.
Edge 1: Critical → Sentinel Analytics
{
"from": "transform",
"to": "output-sentinel-analytics",
"name": "Critical Security Events",
"conditions": {
"operator": "or",
"conditions": [
{"type": "equals", "key": "result", "value": "FAIL"},
{"type": "equals", "key": "event_type", "value": "intrusion"},
{"type": "contains", "key": "action", "value": "deny"},
{"type": "greater_than", "key": "severity_score", "value": 7}
]
}
}
Edge 2: Bulk → Sentinel Basic
{
"from": "transform",
"to": "output-sentinel-basic",
"name": "Bulk Archive",
"conditions": {
"operator": "always",
"conditions": []
}
}
| Both edges evaluate independently. Critical events go to BOTH outputs (analytics for alerting, basic for archive). |
Pattern 2: Source-Based Routing
Route different log sources to different processing paths.
{
"from": "input-syslog",
"to": "transform-ise",
"name": "ISE Logs",
"conditions": {
"operator": "or",
"conditions": [
{"type": "contains", "key": "message", "value": "CISE_"},
{"type": "equals", "key": "facility", "value": "local6"}
]
}
}
Pattern 3: Noise Exclusion
Use nor to exclude known noise patterns.
{
"from": "transform",
"to": "output-sentinel",
"name": "Exclude Noise",
"conditions": {
"operator": "nor",
"conditions": [
{"type": "equals", "key": "event_type", "value": "heartbeat"},
{"type": "equals", "key": "event_type", "value": "accounting_interim"},
{"type": "contains", "key": "message", "value": "health check"}
]
}
}
Pattern 4: Sampling for High-Volume Sources
Sample 10% of successful authentications, 100% of failures.
Edge 1: All failures
{
"conditions": {
"operator": "and",
"conditions": [
{"type": "equals", "key": "result", "value": "FAIL"}
]
}
}
Edge 2: Sampled successes
{
"conditions": {
"operator": "and",
"conditions": [
{"type": "equals", "key": "result", "value": "PASS"},
{"type": "sample", "percentage": 10}
]
}
}
ISE-Specific Routing Examples
Route by ISE Message Type
| ISE Prefix | Meaning | Route To |
|---|---|---|
|
Auth failures |
Analytics (critical) |
|
Auth success |
Basic (bulk) |
|
Command accounting |
Analytics (audit) |
|
Posture results |
Analytics (compliance) |
Condition for failures:
{"type": "contains", "key": "message", "value": "CISE_Failed_Attempts"}
Best Practices
-
Name edges descriptively - Future you will thank past you
-
Test with sample data - Before enabling production pipelines
-
Document routing logic - Why this edge exists
-
Consider fan-out - Records can match multiple edges
-
Use
norfor exclusion - Cleaner than complexandconditions