Self-hostable log storage and search.
Point any OTLP-compatible shipper at one HTTP endpoint, and get a fast,
searchable, live-tailing view of your logs — backed by ClickHouse, on your own box.
Log lines shown are illustrative — Bilis is pre-launch.
v1 is exactly that — nothing else. No traces, metrics, alerting, dashboards, saved searches, or billing.
- Ingest —
POST /api/v1/logsaccepts OTLP/HTTP (JSON or protobuf),POST /api/v1/ingestaccepts a simple JSON shape ({"level": "error", "message": "...", "service": "...", "context": {...}}), andPOST /api/v1/tracesaccepts OTLP spans. An API key resolves to a project; malformed records are skipped best-effort — ingest never returns 400, and overload returns 503 withRetry-After. OTLP over gRPC is not supported, which matters because collectors default to it. - Storage — OTel-compatible
otel_logsandotel_tracesMergeTree tables in ClickHouse (async inserts, atextindex onlower(Body),ProjectId-first ordering, 30 day TTL), plus atrace_summaryaggregate kept for 90 days. Requires ClickHouse 26.2+. Schema and its rules:database/clickhouse/SCHEMA.md. - UI — per-team log viewer (time range, project/service/severity filters, full-text search, expandable rows, live tail) and trace viewer (trace list, span waterfall, per-service latency). A log line links to its trace and a span links back to its logs.
Laravel 13 (PHP 8.4) · Inertia v3 + Vue 3 · Tailwind v4 · ClickHouse (HTTP interface, no client dependency) · SQLite for app data · Pest.
Requires PHP 8.4, Node 22+, and a reachable ClickHouse server.
composer install && npm install
cp .env.example .env && php artisan key:generate
# ClickHouse connection (defaults: 127.0.0.1:8123, database "bilis")
# -> set CLICKHOUSE_* in .env (ClickHouse 26.2+), then create the database and tables:
php artisan clickhouse:migrate
# Upgrading an install that predates the text body index? migrate swaps the index
# definition instantly; this rebuilds it for rows written before the swap. Run it
# once, deliberately — it is not part of migrate, which runs on every boot.
php artisan clickhouse:materialize-index
# App database + demo team/project/API key (the key is printed once)
php artisan migrate --seed
composer run devSend a first log:
curl -X POST http://localhost:8000/api/v1/ingest \
-H "Authorization: Bearer bilis_..." \
-H "Content-Type: application/json" \
-d '{"level":"info","message":"hello bilis","service":"demo"}'Then open /{team-slug}/logs. An OTLP exporter needs OTEL_EXPORTER_OTLP_PROTOCOL=http/json, endpoint https://your-host/api/v1, and the API key as a bearer token.
php artisan test --compact # Pest test suite
vendor/bin/pint --dirty # PHP formatting
vendor/bin/phpstan analyse # static analysis
npm run build # frontend build (vue-tsc + vite)The design system — palette, tokens, severity colours, every component — lives at /styleguide (any logged-in user). Agent/contributor conventions are in CLAUDE.md / AGENTS.md and .ai/rules/.
Functional Source License, Version 1.1, ALv2 Future License (FSL-1.1-ALv2).
In plain terms: self-host Bilis freely — for your company's internal use, for education, for research, and as part of professional services you provide to someone else running it. The one thing you may not do is offer Bilis (or a substantially similar log-search product built from it) to others as a commercial product or hosted service.
Every release converts to the Apache License 2.0 two years after it is published, so this code becomes fully open source on a rolling schedule.
Bilis is source available, not OSI open source. Contributions are welcome under the same terms.