Skip to content

Overview

Stream Relations in Qaze help you visualize and understand the message flows between your NATS JetStream streams. The relations graph shows how streams are connected through mirroring, sourcing, and republish configurations.

Types of Stream Relations

1. Mirror Relations

  • Shows: Streams that mirror other streams
  • Detection: Direct configuration match
  • Always detected: Yes, if mirror configuration exists

2. Source Relations

  • Shows: Streams that source from other streams
  • Detection: Direct configuration match (stream.Sources[].Name)
  • Always detected: Yes, if source configuration exists

3. Republish Relations

  • Shows: Streams that republish messages to other streams
  • Detection: Conservative pattern matching (detailed below)
  • Always detected: Only when subjects explicitly match patterns

Republish Relations: How Detection Works

Qaze uses a conservative approach for republish relation detection. This means relations are only shown when stream subjects explicitly handle the republish patterns, rather than just implicitly including them through broader wildcards.

The Detection Algorithm

For a republish relation to be detected between Stream A and Stream B:

  1. Stream A must have a republish configuration with:

    • Source pattern (e.g., "events.user.*")
    • Destination template (e.g., "audit.$1")
  2. Stream A's subjects must explicitly match the republish pattern:

    • At least one of Stream A's subjects must directly match the republish source pattern
    • Broad wildcards that only implicitly include the pattern are not sufficient
  3. The transformed destination must match Stream B's subjects:

    • The republish template transforms the matched subject
    • The result must match at least one of Stream B's subjects

Examples: Relations That WILL Be Detected

✅ Example 1: Exact Subject Match

yaml
Stream A (Events):
  subjects: ['user.login.event']
  republish:
    source: 'user.login.event'
    dest: 'audit.user.login'

Stream B (Audit):
  subjects: ['audit.user.login']

Result: ✅ Relation detected - exact match guarantees message flow

✅ Example 2: Wildcard Pattern Match

yaml
Stream A (Orders):
  subjects: ['order.123.created', 'order.456.updated']
  republish:
    source: 'order.*.created'
    dest: 'notifications.$1.new-order'

Stream B (Notifications):
  subjects: ['notifications.>']

Result: ✅ Relation detected - order.123.created transforms to notifications.123.new-order, which matches notifications.>

✅ Example 3: Multi-level Wildcard

yaml
Stream A (Sensors):
  subjects: ['sensor.temperature.>']
  republish:
    source: 'sensor.temperature.>'
    dest: 'processed.$1'

Stream B (Processed):
  subjects: ['processed.>']

Result: ✅ Relation detected - any sensor data will be republished to processed stream

Examples: Relations That WON'T Be Detected

❌ Example 1: Broad Source, Specific Pattern

yaml
Stream A (SCHED):
  subjects: ['sched.>']
  republish:
    source: 'sched.target.*.>'
    dest: '$1.>'

Stream B (Target):
  subjects: ['bar.x.y.z']

Result: ❌ No relation detected

Why not? Although SCHED accepts sched.> (which includes sched.target.* messages), the subjects don't explicitly state that sched.target.* messages are handled. The conservative approach only shows relations when subjects directly match the republish patterns, not when they're only implicitly included through broader wildcards.

❌ Example 2: Pattern Doesn't Match Destination

yaml
Stream A (Events):
  subjects: ['events.user.>']
  republish:
    source: 'events.user.>'
    dest: 'logs.audit.$1'

Stream B (Metrics):
  subjects: ['metrics.>']

Result: ❌ No relation detected

Why not? The republish transforms to logs.audit.*, but the target stream only accepts metrics.* subjects. No overlap means no guaranteed message flow.

❌ Example 3: Source Pattern Too Specific

yaml
Stream A (Data):
  subjects: ['data.>']
  republish:
    source: 'data.important.critical.>'
    dest: 'alerts.$1'

Stream B (Alerts):
  subjects: ['alerts.>']

Result: ❌ No relation detected

Why not? Stream A accepts data.> but the republish pattern data.important.critical.> is much more specific. The subjects only implicitly include this pattern through the broader data.> wildcard, rather than explicitly stating that data.important.critical.* messages are handled.

Understanding the Conservative Approach

Why Conservative?

The conservative approach prevents false positive flooding in the relations graph. Without it, almost every stream could appear as a potential target, making the visualization useless.

What "Explicit Handling" Means

A relation is only shown when:

  • The source stream's subjects directly match the republish source pattern
  • The republish transformation produces subjects the target stream accepts
  • The configuration clearly shows intentional message routing design

Benefits

  • Clean visualizations: Only meaningful relations are shown
  • Accurate understanding: Relations represent real message flows
  • Debugging clarity: Missing relations indicate configuration issues
  • Performance: No need to analyze countless theoretical connections

Troubleshooting Relations

"Why don't I see a relation I expect?"

  1. Check if source subjects explicitly match the republish pattern

    Stream subjects: ["events.>"]
    Republish source: "events.user.login"
    
    Problem: "events.>" includes "events.user.login" but doesn't explicitly state it
    Solution: Add "events.user.login" to stream subjects, or change republish to "events.>"
  2. Check if destination matches target subjects

    Republish dest: "audit.$1"
    Target subjects: ["logs.>"]
    
    Problem: "audit.*" doesn't match "logs.*"
    Solution: Change dest to "logs.$1" or target subjects to include "audit.>"
  3. Verify template syntax

    ✅ Valid: "$1", "$2", "\{{wildcard(1)\}\}", "\{\{split(1)\}\}"
    ❌ Invalid: "$0", "{{wildcard(0)}}", unmatched braces

FAQ

Q: Can I force a relation to appear? A: No, relations are detected automatically. Adjust your stream subjects to explicitly match the republish patterns, or adjust the republish patterns to match your subjects.

Q: Why did a relation disappear after I changed subjects? A: The conservative detection no longer sees explicit pattern matching. Check that your new subjects still directly match the republish source pattern.

Q: Can one stream republish to multiple targets? A: Yes, if the republish destination pattern matches multiple streams' subjects, relations will be shown to all matching targets.

Q: Do relations work with NATS 2.12+ template functions? A: Yes, Qaze supports all NATS template functions including the new ones introduced in 2.12.

Q: How deep can relation trees go? A: By default, 3 levels. This level is configurable between 1 and 5.

Powered by Qaze