Skip to content

Commit 94de208

Browse files
docs: add demo GIFs and recording scripts for README
- Created demo tool (cmd/demo) for showcasing parser + renderer - Recorded 4 GIFs: JSON, logfmt, plain text, pipe streaming - Added sample log files and record-all.sh for easy regeneration - Updated README with embedded GIF demos
1 parent 4e33703 commit 94de208

File tree

10 files changed

+178
-0
lines changed

10 files changed

+178
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
Stream, search, and correlate logs from files, Kubernetes, Docker, SSH, and more — all in one TUI.
1111

12+
![LogPilot Demo](docs/demos/demo-json.gif)
13+
1214
## Features
1315

1416
### ✅ Implemented
@@ -71,6 +73,9 @@ logpilot -f /var/log/app.log
7173

7274
# Pipe from another command
7375
kubectl logs -f my-pod | logpilot
76+
77+
# Streaming demo
78+
![Pipe demo](docs/demos/demo-pipe.gif)
7479
docker logs -f my-container | logpilot
7580
cat /var/log/syslog | logpilot
7681

@@ -83,16 +88,25 @@ logpilot /var/log/*.log
8388
LogPilot auto-detects the format from the first few lines:
8489

8590
### JSON
91+
92+
![JSON logs](docs/demos/demo-json.gif)
93+
8694
```json
8795
{"timestamp":"2026-02-17T20:30:00Z","level":"error","message":"connection timeout","service":"api","latency_ms":1523}
8896
```
8997

9098
### Logfmt
99+
100+
![Logfmt logs](docs/demos/demo-logfmt.gif)
101+
91102
```
92103
ts=2026-02-17T20:30:00Z level=error msg="connection timeout" service=api latency_ms=1523
93104
```
94105

95106
### Plain Text
107+
108+
![Plain text logs](docs/demos/demo-plain.gif)
109+
96110
```
97111
2026-02-17 20:30:00 ERROR connection timeout
98112
Feb 17 20:30:00 myhost app[1234]: connection timeout

cmd/demo/main.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Demo tool that showcases LogPilot's parsing and rendering capabilities.
2+
// Used for generating README GIF demos.
3+
package main
4+
5+
import (
6+
"bufio"
7+
"fmt"
8+
"os"
9+
"time"
10+
11+
"github.com/clarabennett2626/logpilot/internal/parser"
12+
"github.com/clarabennett2626/logpilot/internal/tui"
13+
)
14+
15+
func main() {
16+
if len(os.Args) < 2 {
17+
fmt.Fprintf(os.Stderr, "Usage: demo <logfile>\n")
18+
os.Exit(1)
19+
}
20+
21+
// Detect format
22+
f, err := os.Open(os.Args[1])
23+
if err != nil {
24+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
25+
os.Exit(1)
26+
}
27+
28+
var lines []string
29+
scanner := bufio.NewScanner(f)
30+
for scanner.Scan() {
31+
lines = append(lines, scanner.Text())
32+
}
33+
f.Close()
34+
35+
format := parser.DetectFormat(lines)
36+
fmt.Printf("📋 Detected format: %s (%d lines)\n\n", format, len(lines))
37+
38+
// Parse and render each line
39+
p := parser.NewAutoParser()
40+
renderer := tui.NewRenderer(tui.RenderConfig{
41+
TimestampFormat: tui.TimestampRelative,
42+
Theme: tui.ThemeDark,
43+
TerminalWidth: 120,
44+
WrapMode: tui.WrapTruncate,
45+
ShowAllFields: true,
46+
ANSIMode: tui.ANSIStrip,
47+
})
48+
49+
for _, line := range lines {
50+
entry := p.Parse(line)
51+
rendered := renderer.RenderEntry(entry)
52+
fmt.Println(rendered)
53+
time.Sleep(80 * time.Millisecond) // Simulate streaming
54+
}
55+
}

docs/demos/demo-json.gif

68 KB
Loading

docs/demos/demo-logfmt.gif

44.5 KB
Loading

docs/demos/demo-pipe.gif

70.2 KB
Loading

docs/demos/demo-plain.gif

40.8 KB
Loading

docs/demos/record-all.sh

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/bin/bash
2+
# Record all demo GIFs for LogPilot README.
3+
# Usage: ./docs/demos/record-all.sh
4+
# Requires: asciinema, agg (https://github.com/asciinema/agg)
5+
6+
set -e
7+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8+
REPO_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
9+
DEMO="$REPO_DIR/demo"
10+
GIF_DIR="$SCRIPT_DIR"
11+
12+
# Build demo tool
13+
echo "Building demo tool..."
14+
cd "$REPO_DIR"
15+
go build -o demo ./cmd/demo/
16+
17+
# Colors for output
18+
GREEN='\033[0;32m'
19+
NC='\033[0m'
20+
21+
record_demo() {
22+
local name="$1"
23+
local script="$2"
24+
local cast_file="$GIF_DIR/${name}.cast"
25+
local gif_file="$GIF_DIR/${name}.gif"
26+
27+
echo -e "${GREEN}Recording: ${name}${NC}"
28+
29+
asciinema rec "$cast_file" \
30+
--cols 120 \
31+
--rows 30 \
32+
--command "$script" \
33+
--overwrite \
34+
--quiet
35+
36+
echo -e "${GREEN}Converting to GIF: ${name}${NC}"
37+
"$REPO_DIR/agg" --cols 120 --rows 30 --speed 1.5 "$cast_file" "$gif_file" 2>/dev/null || \
38+
agg --cols 120 --rows 30 --speed 1.5 "$cast_file" "$gif_file"
39+
40+
# Clean up cast file
41+
rm -f "$cast_file"
42+
echo "$gif_file"
43+
}
44+
45+
# 1. Hero demo: JSON logs with color-coded output
46+
record_demo "demo-json" "$DEMO $SCRIPT_DIR/sample-json.log"
47+
48+
# 2. Logfmt format demo
49+
record_demo "demo-logfmt" "$DEMO $SCRIPT_DIR/sample-logfmt.log"
50+
51+
# 3. Plain text format demo
52+
record_demo "demo-plain" "$DEMO $SCRIPT_DIR/sample-plain.log"
53+
54+
# 4. Pipe demo: simulated streaming
55+
record_demo "demo-pipe" "bash -c 'echo \"Streaming logs via pipe...\"; echo; cat $SCRIPT_DIR/sample-json.log | $DEMO /dev/stdin'"
56+
57+
# 5. Format detection demo: show all 3 formats
58+
record_demo "demo-formats" "bash -c '
59+
echo \"=== JSON Logs ===\"
60+
$DEMO $SCRIPT_DIR/sample-json.log
61+
echo
62+
echo \"=== Logfmt Logs ===\"
63+
$DEMO $SCRIPT_DIR/sample-logfmt.log
64+
echo
65+
echo \"=== Plain Text Logs ===\"
66+
$DEMO $SCRIPT_DIR/sample-plain.log
67+
'"
68+
69+
echo ""
70+
echo -e "${GREEN}All demos recorded!${NC}"
71+
echo "GIFs saved to: $GIF_DIR/"
72+
ls -la "$GIF_DIR"/*.gif 2>/dev/null

docs/demos/sample-json.log

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{"timestamp":"2026-02-17T20:00:01Z","level":"info","message":"Server starting on :8080","service":"api","version":"1.2.3"}
2+
{"timestamp":"2026-02-17T20:00:02Z","level":"info","message":"Connected to PostgreSQL","service":"api","host":"db.internal:5432"}
3+
{"timestamp":"2026-02-17T20:00:02Z","level":"info","message":"Redis connection pool initialized","service":"api","pool_size":10}
4+
{"timestamp":"2026-02-17T20:00:03Z","level":"info","message":"Loading middleware: auth, cors, ratelimit","service":"api"}
5+
{"timestamp":"2026-02-17T20:00:05Z","level":"info","message":"Ready to accept connections","service":"api","workers":8}
6+
{"timestamp":"2026-02-17T20:01:12Z","level":"info","message":"GET /api/v1/users 200 12ms","service":"api","method":"GET","path":"/api/v1/users","status":200,"latency_ms":12}
7+
{"timestamp":"2026-02-17T20:01:15Z","level":"debug","message":"Cache hit for user:1234","service":"api","cache":"redis","key":"user:1234"}
8+
{"timestamp":"2026-02-17T20:01:18Z","level":"info","message":"POST /api/v1/orders 201 45ms","service":"api","method":"POST","path":"/api/v1/orders","status":201,"latency_ms":45}
9+
{"timestamp":"2026-02-17T20:02:30Z","level":"warn","message":"Slow query detected","service":"api","query":"SELECT * FROM orders WHERE...","duration_ms":850}
10+
{"timestamp":"2026-02-17T20:02:45Z","level":"warn","message":"Rate limit approaching for client 10.0.1.50","service":"api","client_ip":"10.0.1.50","remaining":5}
11+
{"timestamp":"2026-02-17T20:03:01Z","level":"error","message":"Connection refused to payment service","service":"api","target":"payments:443","retry":1}
12+
{"timestamp":"2026-02-17T20:03:03Z","level":"error","message":"Connection refused to payment service","service":"api","target":"payments:443","retry":2}
13+
{"timestamp":"2026-02-17T20:03:05Z","level":"error","message":"Payment service unavailable after 3 retries","service":"api","target":"payments:443","retry":3}
14+
{"timestamp":"2026-02-17T20:03:05Z","level":"fatal","message":"Critical dependency down — entering degraded mode","service":"api","dependency":"payments"}
15+
{"timestamp":"2026-02-17T20:03:10Z","level":"warn","message":"Health check reporting degraded","service":"api","healthy_deps":3,"total_deps":4}

docs/demos/sample-logfmt.log

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
ts=2026-02-17T20:00:01Z level=info msg="Starting worker pool" workers=4 queue=jobs
2+
ts=2026-02-17T20:00:02Z level=info msg="Connected to message broker" broker=rabbitmq host=mq.internal:5672
3+
ts=2026-02-17T20:01:00Z level=info msg="Processing job" job_id=j-8821 type=email_send queue=jobs
4+
ts=2026-02-17T20:01:01Z level=debug msg="Template rendered" job_id=j-8821 template=welcome_email render_ms=3
5+
ts=2026-02-17T20:01:02Z level=info msg="Job completed" job_id=j-8821 duration_ms=2100 status=success
6+
ts=2026-02-17T20:01:30Z level=info msg="Processing job" job_id=j-8822 type=image_resize queue=media
7+
ts=2026-02-17T20:01:35Z level=warn msg="Image resize took longer than expected" job_id=j-8822 duration_ms=5200 threshold_ms=3000
8+
ts=2026-02-17T20:02:00Z level=error msg="Job failed: invalid image format" job_id=j-8823 type=image_resize error="unsupported format: webp"
9+
ts=2026-02-17T20:02:01Z level=info msg="Retrying job" job_id=j-8823 attempt=2 max_attempts=3
10+
ts=2026-02-17T20:02:10Z level=error msg="Job permanently failed" job_id=j-8823 attempts=3 moved_to=dead_letter

docs/demos/sample-plain.log

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2026-02-17 20:00:01 INFO Application starting up
2+
2026-02-17 20:00:02 INFO Loading configuration from /etc/app/config.yaml
3+
2026-02-17 20:00:02 INFO Database migration: 3 pending
4+
2026-02-17 20:00:03 INFO Running migration 042_add_user_index
5+
2026-02-17 20:00:04 INFO Running migration 043_add_audit_table
6+
2026-02-17 20:00:05 INFO Running migration 044_add_notifications
7+
2026-02-17 20:00:05 INFO All migrations completed successfully
8+
2026-02-17 20:01:00 DEBUG Request received: GET /health
9+
2026-02-17 20:01:30 WARN Disk usage at 82% on /var/data
10+
2026-02-17 20:02:00 ERROR Failed to send notification: smtp timeout
11+
2026-02-17 20:02:15 ERROR Retrying notification send (attempt 2/3)
12+
2026-02-17 20:02:30 INFO Notification sent successfully on retry

0 commit comments

Comments
 (0)