All your errors in one beautiful dashboard. No more tab-switching between Sentry, LogRocket, Cloudflare, and Vercel.
You use Sentry for backend errors. LogRocket for frontend. Cloudflare Workers has its own logging. Vercel Functions too. Each one is good at what it does, but you're constantly switching contexts to get the full picture.
error-wall pulls errors from all these sources into a single self-hosted dashboard. One view, all your errors, no subscriptions.
- Aggregates errors from Sentry, LogRocket, Cloudflare, and Vercel
- Beautiful dark-mode dashboard with error trends
- Smart deduplication via fingerprinting
- Search and filter across all sources
- Resolve/unresolve errors across all platforms
- Self-hosted, single binary, SQLite storage
- Encrypted credential storage
- Automatic periodic sync
# From source
git clone https://github.com/sudokatie/error-wall
cd error-wall
go build -o error-wall ./cmd/error-wall
# Move to PATH
mv error-wall /usr/local/bin/# Start the server
error-wall serve
# Add a source
error-wall sources add sentry production
# Manually sync
error-wall sync
# Open http://localhost:8080Create ~/.config/error-wall/config.yaml:
server:
port: 8080
host: 0.0.0.0
database:
path: /var/lib/error-wall/errors.db
sync:
interval_minutes: 15
enabled: true
sources:
- name: production-sentry
type: sentry
enabled: true
config:
organization: my-org
token: your-sentry-token
- name: frontend-logrocket
type: logrocket
enabled: true
config:
app_id: my-app
token: your-logrocket-tokenConfigure alert rules to get notified when specific conditions are met.
- rate: Triggers when error count exceeds threshold within a time window
- pattern: Triggers when error message matches a regex pattern
- threshold: Triggers when error count exceeds a value
alerts:
enabled: true
rules:
- id: high-error-rate
name: High Error Rate
enabled: true
condition:
type: rate
threshold: 10
window: 5m
filters:
levels: [error, fatal]
severity: warning
cooldown: 30m
- id: database-errors
name: Database Connection Errors
enabled: true
condition:
type: pattern
pattern: "(?i)database.*connection"
filters:
sources: [sentry]
severity: critical
cooldown: 1h
- id: any-fatal
name: Any Fatal Error
enabled: true
condition:
type: threshold
threshold: 1
filters:
levels: [fatal]
severity: critical
cooldown: 15mAlert rules support multiple action types. Add actions to your rule config:
alerts:
rules:
- id: critical-errors
name: Critical Errors
# ... condition and filters ...
actions:
- type: slack
config:
webhook_url: https://hooks.slack.com/services/T00/B00/xxx
- type: log
config:
level: errorSends rich formatted messages to Slack via incoming webhooks.
- type: slack
config:
webhook_url: https://hooks.slack.com/services/xxxFeatures:
- Color-coded by severity (green/yellow/red)
- Includes project, source, environment metadata
- Groups multiple alerts into summary messages
- Pattern match details for pattern-triggered alerts
- Error message preview (truncated for long messages)
To set up:
- Create an incoming webhook in Slack: Apps > Incoming Webhooks > Add New Webhook
- Copy the webhook URL to your config
Sends alerts to any HTTP endpoint (uses Slack message format).
- type: webhook
config:
url: https://your-endpoint.com/alertsWrites alerts to the error-wall log. Useful for debugging rules.
- type: log
config:
level: info # optional: info, warn, error- Deduplication: Same rule won't fire again within cooldown period
- Rate-based alerts: Track error frequency over sliding time windows
- Pattern matching: Regex patterns for message matching
- Filtering: Alert on specific sources, projects, environments, levels, or tags
- Severity levels: info, warning, critical
- Multiple actions: Each rule can trigger multiple notifications
type: sentry
config:
organization: your-org
token: your-auth-tokentype: logrocket
config:
app_id: your-app-id
token: your-api-tokentype: cloudflare
config:
account_id: your-account-id
token: your-api-tokentype: vercel
config:
project_id: your-project-id
token: your-api-tokenerror-wall serve # Start the web server
error-wall sync # Manually sync all sources
error-wall sources list # List configured sources
error-wall sources add # Add a new source
error-wall sources remove # Remove a source
error-wall sources test # Test source connection
error-wall version # Show versionThe dashboard is powered by a REST API. All endpoints except /api/health require authentication via Authorization: Bearer <token> header.
GET /api/errors # List errors (filterable, paginated)
GET /api/errors/:id # Get single error with full details
PATCH /api/errors/:id # Update error status
POST /api/errors/:id/resolve # Mark error as resolved
POST /api/errors/:id/ignore # Mark error as ignored
POST /api/errors/:id/unresolve # Reopen error
DELETE /api/errors/:id # Delete error
Query params for list: source, project, environment, level, status, search, since, until, page, limit, sort, order
GET /api/sources # List configured sources
POST /api/sources # Add new source
GET /api/sources/:id # Get source details
PATCH /api/sources/:id # Update source
DELETE /api/sources/:id # Remove source
POST /api/sources/:id/sync # Trigger sync for source
GET /api/sources/:id/validate # Test source credentials
GET /api/sources/:id/projects # List available projects
GET /api/stats # Aggregate statistics
GET /api/stats/trends # Error rate trends
GET /api/sync/status # Current sync status
POST /api/sync/trigger # Trigger full sync
GET /api/health # Health check (no auth required)
docker run -d \
-p 8080:8080 \
-v /path/to/config.yaml:/config.yaml \
-v /path/to/data:/data \
sudokatie/error-wall- Credentials are encrypted at rest using AES-256-GCM
- Never logs sensitive tokens
- CORS enabled for local development
- No external dependencies beyond the configured error sources
- One screen for all your errors
- Self-hosted - your data stays yours
- Single binary - no Docker required (but supported)
- Zero JavaScript frameworks on the backend
MIT
Katie
Stop switching tabs. Start fixing bugs.