Skip to content

staack/crowbar

Repository files navigation

Crowbar

Self-hosted app telemetry and website analytics. One binary. No cloud. No cookies.

What it does

Crowbar collects two kinds of data: app telemetry and website analytics. App telemetry tracks events with type, phase, operation, and result fields. It detects failures and slow operations so you know when something breaks before your users tell you. Website analytics tracks page views, unique visitors, engagement time, scroll depth, browser/device/OS/language/country breakdowns, referrers, and UTM campaigns.

It's a single Go binary backed by PostgreSQL. That's the whole stack. No Redis, no Kafka, no message queue, no fourteen microservices.

Privacy is the default, not a feature flag. No cookies. Visitor identity is a daily-rotating hash — same person gets a different hash tomorrow. IP addresses are resolved to a country via GeoIP and then thrown away. Nothing is stored that could identify a person.

Quick start

git clone https://github.com/staack/crowbar.git
cd crowbar
docker compose up -d
open http://localhost:8080

The dashboard is at / with basic auth. Default creds are in the docker-compose file. Change them.

Configuration

All configuration is through environment variables.

Variable Default Description
DATABASE_URL (required) PostgreSQL connection string
LISTEN_ADDR :8080 Address and port to bind
DASH_USER admin Dashboard basic auth username
DASH_PASS (required) Dashboard basic auth password
PROJECT_NAME crowbar Project name shown in dashboard and emails
ALLOWED_ORIGINS * Comma-separated allowed CORS origins
NOTIFY_ON (empty) Event types that trigger email alerts (comma-separated)
SMTP2GO_API_KEY (empty) SMTP2Go API key for email notifications
SMTP2GO_FROM (empty) Sender address for notifications
SMTP2GO_TO (empty) Recipient address for notifications
ADMIN_TOKEN_HASH (empty) SHA-256 hash of the admin API token
GEOIP_DB_PATH (empty) Path to MaxMind GeoLite2 Country database
MAX_REQUEST_BYTES 1048576 Maximum request body size in bytes
RATE_LIMIT_RPS 10 Requests per second per IP
RATE_LIMIT_BURST 20 Burst allowance for rate limiting
LOG_LEVEL info Log level: debug, info, warn, error
LOG_FORMAT json Log format: json or text

Tracking snippet

Paste before </body> on pages you want to track. Replace YOUR_DOMAIN with your crowbar host. The full snippet is in docs/tracking-snippet.html — copy it from there.

It collects page path, title, referrer, screen size, viewport, timezone, device pixel ratio, touch support, connection type, UTM params, scroll depth, and time on page. No cookies. Uses sessionStorage for page-count-per-visit (clears when the tab closes). Fires a beacon on page hide for engagement data.

Sending telemetry

Register an installation, then send events:

# Register — save the token.
curl -s -X POST https://YOUR_DOMAIN/api/v1/installations/register | jq .

# Send an event.
curl -X POST https://YOUR_DOMAIN/api/v1/ingest \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [{
      "event_type": "deploy",
      "phase": "database",
      "operation": "migrate",
      "result": "success",
      "duration_ms": 1230,
      "app_version": "1.0.0"
    }]
  }'

More examples

See docs/client-examples/ for Python, Node.js, and Go.

Reverse proxy

See docs/reverse-proxy/ for Caddy, Nginx, HAProxy, Apache, and Traefik configs.

License

MIT. See LICENSE.

About

Self-hosted app telemetry and website analytics. One binary. No cloud. No cookies.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors