Skip to content

AkZcH/SpanTide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SpanTide

A lightweight distributed tracing collector for your terminal — built in Rust.

SpanTide receives trace spans from your services over UDP, stores them in memory, and displays a live waterfall dashboard in your terminal. No config files, no database, no browser required.

SpanTide TUI showing traces and span waterfall


What it does

When a request travels through multiple services, something always slows it down or breaks. SpanTide tells you exactly where.

Each service sends a small JSON message (a "span") to SpanTide over UDP saying "I handled this request, it took X milliseconds, status was Y." SpanTide collects all these spans, groups them by trace, and shows you the full picture in real time.

your services  →  UDP spans  →  SpanTide  →  live terminal dashboard
                                         →  HTTP REST API

Features

  • UDP span receiver on port 4317
  • Live terminal dashboard with waterfall view (ratatui)
  • Keyboard navigation between traces
  • Color coded spans — green for success, red for errors
  • HTTP REST API to query traces programmatically
  • Zero config, zero dependencies — just cargo run

Getting started

Prerequisites: Rust 1.75+ (install here)

git clone https://github.com/AkZcH/SpanTide
cd spantide
cargo run

You should see:

UDP listening on 0.0.0.0:4317
HTTP listening on 0.0.0.0:8080

And the terminal dashboard opens automatically.


Sending spans

SpanTide receives spans as JSON over UDP on port 4317.

Span format:

{
  "trace_id": "req001",
  "span_id": "s1",
  "parent_id": null,
  "service": "api-gateway",
  "operation": "/users",
  "started_at": "2024-01-01T00:00:00Z",
  "duration_ms": 312,
  "status": 200
}

Send a test span (PowerShell):

$udpClient = New-Object System.Net.Sockets.UdpClient
$udpClient.Connect("127.0.0.1", 4317)
$bytes = [System.Text.Encoding]::UTF8.GetBytes('{"trace_id":"req001","span_id":"s1","parent_id":null,"service":"api-gateway","operation":"/users","started_at":"2024-01-01T00:00:00Z","duration_ms":312,"status":200}')
$udpClient.Send($bytes, $bytes.Length)
$udpClient.Close()

Send a test span (Linux/macOS):

echo '{"trace_id":"req001","span_id":"s1","parent_id":null,"service":"api-gateway","operation":"/users","started_at":"2024-01-01T00:00:00Z","duration_ms":312,"status":200}' | nc -u 127.0.0.1 4317

Demo script

Run the included demo to see SpanTide in action with realistic multi-service traces:

# Windows Powershell
.\demo.ps1
# Linux/macOS
chmod +x demo.sh && ./demo.sh

This sends a realistic trace with 3 spans across api-gateway, db, and cache — including a simulated error.


HTTP API

While SpanTide is running, query your traces programmatically:

Endpoint Description
GET /traces List all traces with span count and total duration
GET /traces/:id Get all spans for a specific trace
GET /stats Total trace and span counts

Examples:

curl http://localhost:8080/traces
curl http://localhost:8080/traces/req001
curl http://localhost:8080/stats

TUI keyboard shortcuts

Key Action
/ Navigate between traces
q Quit

Architecture

┌─────────────────────────────────────────────────────┐
│                      SpanTide                       │
│                                                     │
│   ┌──────────┐     ┌──────────┐     ┌───────────┐   │
│   │  udp.rs  │     │ http.rs  │     │  tui.rs   │   │
│   │          │     │          │     │           │   │
│   │ :4317    │     │ :8080    │     │ terminal  │   │
│   └────┬─────┘     └────┬─────┘     └─────┬─────┘   │
│        │                │                 │         │
│        └────────────────┴─────────────────┘         │
│                         │                           │
│                  ┌──────▼──────┐                    │
│                  │  store.rs   │                    │
│                  │             │                    │
│                  │ Arc<Mutex<  │                    │
│                  │  HashMap>>  │                    │
│                  └─────────────┘                    │
└─────────────────────────────────────────────────────┘

All three components share a single SpanStore wrapped in Arc<Mutex<...>>, allowing safe concurrent access across async tasks.


Project structure

spantide/
├── src/
│   ├── main.rs      # entry point, spawns UDP, HTTP, and TUI
│   ├── span.rs      # Span data model
│   ├── store.rs     # thread-safe in-memory span storage
│   ├── udp.rs       # async UDP listener
│   ├── http.rs      # axum HTTP REST API
│   └── tui.rs       # ratatui terminal dashboard
└── Cargo.toml

Built with


License

MIT

About

A self-contained distributed tracing backend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors