Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LingEdge

High-performance HTTP / SIP / WebSocket load testing tool written in Rust.

Async I/O (Tokio), HdrHistogram latency, pluggable load models, multi-step scenarios, distributed workers, and a local Web UI — one binary, no runtime deps.

Features

  • HTTP/1.1 · HTTP/2 · experimental HTTP/3 — connection pooling, proxy (HTTP/SOCKS5), retries, dry-run
  • Load models — closed-loop, constant RPS, ramp, burst, step, peak, sawtooth, custom wave
  • Scenarios — multi-step flows with JSONPath / regex extraction, think time, data sources (CSV/JSON/faker)
  • SIP / VoIP — CPS + concurrent calls, RTP stats, answer/fail metrics
  • WebSocket · HAR record/replay · experimental gRPC
  • Reports — TUI, JSON, HTML + PNG charts, Prometheus, Markdown, CSV
  • Web UI — browser dashboard with live RPS / P99 via SSE
  • Distributed — worker agents + coordinator (HdrHistogram merge for accurate global percentiles)
  • Scripting — Lua or WASM per-request transforms

Install

# From this repo
cargo install --path .

# Or build a release binary
cargo build --release
./target/release/lingedge --help

Requires a recent Rust toolchain (edition = "2021").

Quick start

# Local Web UI
lingedge ui
# → http://127.0.0.1:8787/

# Closed-loop (fixed concurrency)
lingedge GET https://api.example.com/users -c 50 -d 30s

# Constant rate (open-loop)
lingedge GET https://api.example.com/users --rate 1000 -d 60s

# Ramp + TUI + multi-format export
lingedge GET https://api.example.com/users \
  --ramp-start 10 --ramp-end 500 --ramp-up 20s -d 60s \
  --tui -o ./results/run --format all

# Config file
lingedge run --config examples/burst.yaml

# SIP / VoIP (simulate without a real UA)
lingedge sip 'sip:bob@127.0.0.1:5060' --simulate -o ./results/voip --format all

Commands

Command Description
lingedge ui Local Web UI console
lingedge GET/POST/... <URL> Quick HTTP load test
lingedge run --config <FILE> YAML / JSON / TOML config
lingedge sip <URI> SIP / VoIP CPS load test
lingedge bench <URL> Fixed-iteration latency bench
lingedge ws <URL> WebSocket load test
lingedge grpc --endpoint ... Experimental gRPC-over-HTTP
lingedge record HTTP forward-proxy → HAR
lingedge replay --har <FILE> HAR multi-entry replay
lingedge compare <A> <B> Diff two JSON reports
lingedge worker Distributed worker agent
lingedge dist Distributed coordinator

Web UI

lingedge ui --bind 127.0.0.1:8787
# open http://127.0.0.1:8787/  (--no-open to skip browser)

Configure URL and load model in the form, Start to run, watch live charts via SSE. Default bind is loopback only.

Distributed

# On each worker host (optional auth + TLS)
lingedge worker --bind 0.0.0.0:9800 --token "$LINGEDGE_TOKEN" \
  --tls-cert ./cert.pem --tls-key ./key.pem

# Coordinator
lingedge dist --config examples/quick.yaml \
  --workers 10.0.0.1:9800,10.0.0.2:9800 \
  --token "$LINGEDGE_TOKEN" --tls --insecure

# Or via run
lingedge run --config examples/quick.yaml \
  --workers 10.0.0.1:9800 --workers 10.0.0.2:9800

The coordinator health-checks workers, streams live progress (/v1/progress), retries with exponential backoff, and merges raw HdrHistograms for accurate global percentiles.

# Scenario / SIP fan-out
lingedge run -c examples/scenario.yaml --workers host1:9800,host2:9800 \
  --progress-out ./progress.jsonl
lingedge sip 'sip:bob@127.0.0.1:5060' --simulate --workers 127.0.0.1:9800

Request scripting (Lua / WASM)

# Lua: export on_request(ctx) → { url?, body?, headers? } | nil
lingedge GET https://api.example.com/x \
  --script examples/scripts/on_request.lua -c 5 -d 5s

# WASM: export alloc / on_request (JSON in → packed ptr+len out)
lingedge GET https://api.example.com/x --script ./hook.wasm -c 5 -d 5s

Useful flags

Flag Meaning
--script <FILE> Lua (.lua) or WASM (.wasm) per-request transform
--workers host:port Fan-out to remote workers (repeatable)
--dry-run Print plan, send nothing
--proxy <URL> HTTP / SOCKS5 proxy
--retries N Exponential backoff retries
--slow-threshold 500ms Slow-request counter
--metrics-addr 127.0.0.1:9100 Live Prometheus /metrics
-v / --verbose Debug logs
--format json,html,png,prom,md,csv,all Report formats
-o <DIR> Output directory for reports

Load models

Set load.model in config (or use CLI flags for closed / constant / ramp):

Model Behavior
closed Fixed concurrency (closed-loop)
constant Fixed arrival rate (open-loop RPS)
ramp Linear ramp-up / hold
burst Periodic spikes
step Stair-step concurrency or rate
peak Short peak then settle
sawtooth Cyclic rise and fall
wave Custom waveform points

See examples/burst.yaml, examples/step.yaml, examples/peak.yaml, examples/quick.yaml.

Scenario example

# examples/scenario.yaml
load:
  concurrency: 5
  duration: 10s
scenario:
  name: login_then_me
  steps:
    - type: request
      method: POST
      url: http://127.0.0.1:8080/login
      body: '{"user":"demo"}'
      extract:
        token:
          type: json_path
          path: /token
    - type: think
      duration: 50ms
    - type: request
      method: GET
      url: http://127.0.0.1:8080/me
      headers:
        Authorization: "Bearer ${token}"

Reports

Format Notes
Terminal Summary after each run
TUI Live dashboard (--tui)
JSON Machine-readable, for compare
HTML + PNG Charts under <out>_charts/
Prometheus Textfile and/or --metrics-addr
Markdown / CSV Lightweight exports
Web UI Live SSE charts

Architecture

Module Responsibility
cli/ Clap parsing, subcommand dispatch
config/ YAML / JSON / TOML loading
http/ Reqwest client, pool, request builder
load/ Pluggable LoadModel strategies
scenario/ Multi-step engine + extraction
data/ CSV / JSON sources, templates, faker
metrics/ HdrHistogram, counters, VoIP / system
report/ TUI, JSON/HTML/PNG/Prom/MD/CSV
ui/ Local Web UI + SSE
protocol/ WebSocket, gRPC, HAR, SIP/RTP, record
distributed/ Worker + coordinator
script/ Lua / WASM hooks

Design notes: see DESIGN.md. Agent conventions: see AGENTS.md.

Development

cargo test
cargo clippy
cargo fmt --check

cargo run -- ui --no-open
cargo run -- GET http://127.0.0.1:8080/ -c 10 -d 5s --dry-run

Optional experimental HTTP/3 (QUIC via reqwest + quinn):

# .cargo/config.toml already sets --cfg reqwest_unstable for this repo
cargo build --release --features http3
./target/release/lingedge GET https://cloudflare-quic.com/ --http3 -c 10 -d 5s

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages