Full rebrand across cosmetic branding, code identifiers, and infrastructure/data-plane naming, using the supplied Cairn OBS logo package. Cosmetic: favicon/logo swap (also closes a stale license-audit finding -- the old favicon was SvelteKit's unreplaced scaffold logo), new centered welcome landing page, larger/legible sidebar logo, page titles, CLAUDE.md/README/docs prose. Code identifiers: Go module path github.com/sentry/sentry -> github.com/cairnobs/cairnobs across all 13 modules and ~91 files (protoc regenerated); Rust crates sentry-agent/sentry-parser/sentry-search -> cairnobs-*; CLI sentryctl -> cairnobsctl; Terraform provider fully renamed (sentry_dashboard etc. -> cairnobs_dashboard, provider type, env vars); every session/auth cookie name; agent config paths and Windows service identity. Deliberately preserved: the gRPC wire protocol's protobuf packages (sentry.logs.v1, sentry.agent.v1) and their Go import directory (proto/sentry/...) -- renaming the wire-level package would break every currently-deployed agent binary (confirmed two real hosts, including mail.inbuxa.com, are actively streaming through this exact contract) until rebuilt and redeployed in lockstep with an ingest cutover. Only the Go module path wrapping the generated code changes. Infrastructure: every docker-compose container name (root and three component-level compose files); the Helm chart (directory, Chart.yaml, named-template helpers, all templates, values.yaml image repos); Kubernetes Operator (CRD group sentry.io -> cairnobs.io, both CRD YAML files, Go identifiers, RBAC markers); the coupled enterprise/tenantcrd package. Caught and fixed real path-coupling bugs along the way: the Helm chart's search/ingest volume mounts and the dev-only-credential detection constant vs. docker-compose.yml's literal values had to move together or a security warning would have silently stopped firing. Data plane: Postgres database sentry_metadata -> cairnobs_metadata and role sentry -> cairnobs; ClickHouse database sentry -> cairnobs; Kafka topic sentry.logs.raw -> cairnobs.logs.raw and its consumer groups. Source-level defaults, docker-compose.yml, and every migrate.sh/ provision script default updated together; already-applied migration files left untouched per this repo's immutable-migration convention. Verified at every layer: all 13 Go modules build/vet/test clean, both Rust workspaces (agent, search) build/clippy/test clean, npm run check/ build clean, docker compose config validates on all four compose files. Live-verified against a real docker stack multiple times through this work, including a final fresh-volume run confirming the actual renamed Postgres database/role, ClickHouse database, and Kafka topic all work end to end with a real login and query, zero console errors.
214 lines
7.9 KiB
Markdown
214 lines
7.9 KiB
Markdown
# Phase 0 runbook
|
|
|
|
Walks one log line from a Linux host, through the Rust agent, Redpanda,
|
|
ingest, and ClickHouse, to a browser table. This is the actual
|
|
"done" criterion for Phase 0 — if this doesn't work, Phase 0 isn't done,
|
|
regardless of what any individual component's tests say.
|
|
|
|
**Update:** this sequence has since been run for real, more than once,
|
|
against a live Docker install — not just written and trusted. Two real
|
|
bugs turned up doing that (ClickHouse's official image silently disabling
|
|
network access without a password set; `rpk`'s exact flag syntax) and got
|
|
fixed; see the git history around the "Fix two bugs found by actually
|
|
running the Phase 0 pipeline end-to-end" commit if you want the details.
|
|
The steps below reflect what was actually run, not just planned. The
|
|
"Troubleshooting" section below is still worth reading first if something
|
|
doesn't work — it's not an exhaustive list, but it does reflect real
|
|
failures encountered, not hypothetical ones.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker with **Compose v2** (`docker compose`, not the legacy
|
|
`docker-compose` v1 binary) — the compose file uses
|
|
`service_completed_successfully` conditions that v1 doesn't support.
|
|
- Rust toolchain (`cargo`) and `protoc` — to build the agent.
|
|
- `openssl` — to generate dev mTLS certs.
|
|
- A systemd-based Linux host to run the agent on (journald is the default
|
|
source). If you're not on such a host, see `/agent/README.md`'s
|
|
`file-tail` feature as an alternative source.
|
|
|
|
You do **not** need the musl cross-compilation target for this runbook —
|
|
that's for producing the distro-agnostic release binary. A native
|
|
`cargo build --release` is enough to run the agent on the same machine
|
|
you're testing on.
|
|
|
|
## 1. Generate dev mTLS certs
|
|
|
|
```sh
|
|
./hack/dev-certs/generate.sh
|
|
```
|
|
|
|
Writes a throwaway CA plus a server cert (for `ingest`) and a client cert
|
|
(for the agent) to `hack/dev-certs/out/`. Dev-only — see the script's
|
|
header comment for why.
|
|
|
|
## 2. Bring up the backend stack
|
|
|
|
```sh
|
|
docker compose up -d --build
|
|
```
|
|
|
|
This builds and starts, in dependency order: `redpanda` → `redpanda-provision`
|
|
(creates the `sentry.logs.raw` topic, then exits) → `clickhouse` →
|
|
`clickhouse-migrate` (applies `/storage/migrations`, then exits) →
|
|
`ingest` and `api` → `web`.
|
|
|
|
Check everything came up:
|
|
|
|
```sh
|
|
docker compose ps
|
|
```
|
|
|
|
`redpanda-provision` and `clickhouse-migrate` should show `Exited (0)`
|
|
(one-shot jobs, not long-running). Everything else should show `Up` /
|
|
`healthy`.
|
|
|
|
If `ingest` or `api` crash-looped, they likely started before their
|
|
`depends_on` conditions were actually satisfied, or the dev certs from
|
|
step 1 don't exist yet — check `docker compose logs ingest`.
|
|
|
|
## 3. Sanity-check the backend before involving the agent
|
|
|
|
```sh
|
|
curl http://localhost:8080/healthz
|
|
# -> 200, empty body
|
|
|
|
curl -X POST http://localhost:8080/query \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"sql": "SELECT 1"}'
|
|
# -> {"columns":["1"],"rows":[[1]]} (exact column name may vary by ClickHouse version)
|
|
```
|
|
|
|
This confirms `api` can reach `clickhouse` before you go looking for bugs
|
|
anywhere else. It doesn't touch the `logs` table, so it works even before
|
|
any agent has sent data.
|
|
|
|
## 4. Install the agent's mTLS material
|
|
|
|
The agent's default config expects certs at `/etc/cairnobs-agent/` (see
|
|
`/agent/config/agent.example.toml`), which requires root:
|
|
|
|
```sh
|
|
sudo mkdir -p /etc/cairnobs-agent
|
|
sudo cp hack/dev-certs/out/ca.pem \
|
|
hack/dev-certs/out/client.pem \
|
|
hack/dev-certs/out/client-key.pem \
|
|
/etc/cairnobs-agent/
|
|
```
|
|
|
|
## 5. Build and run the agent
|
|
|
|
```sh
|
|
cd agent
|
|
cargo build --release
|
|
```
|
|
|
|
The agent's built-in defaults already match this setup with **zero
|
|
config file**: journald source (whole journal), service name `default`,
|
|
ingest endpoint `https://127.0.0.1:4317` (matches the port `ingest`
|
|
publishes in `docker-compose.yml`), and the cert paths from step 4. This
|
|
is the "no required flags for the common case" design goal from
|
|
`/agent/README.md` — if it doesn't just run, that design assumption is
|
|
wrong somewhere and worth reporting as a bug, not working around.
|
|
|
|
Reading the system journal generally needs root (or membership in the
|
|
`systemd-journal` group with a distro that grants it read access — varies
|
|
by distro, root is the reliable path for this runbook):
|
|
|
|
```sh
|
|
sudo RUST_LOG=info ./target/release/cairnobs-agent
|
|
```
|
|
|
|
`RUST_LOG=info` matters: `tracing_subscriber`'s default filter is
|
|
otherwise strict enough to suppress even the startup log line, and the
|
|
agent will look like it's silently doing nothing. Leave it running in
|
|
this terminal — you should see a `connected to ingest service` log line.
|
|
If you see a TLS or connection error instead, stop here and check the
|
|
Troubleshooting section before continuing.
|
|
|
|
## 6. Generate a test log line
|
|
|
|
In another terminal, **after** the agent is running and connected
|
|
(journald tailing starts from "now" — anything logged before the agent
|
|
started won't be picked up):
|
|
|
|
```sh
|
|
logger "hello from sentry phase 0"
|
|
```
|
|
|
|
`logger` (part of util-linux, present on virtually every Linux distro)
|
|
writes this to the system log, which journald captures immediately.
|
|
|
|
Give it a couple of seconds — the agent batches with a 2-second flush
|
|
interval by default, so the line won't hit ingest instantly.
|
|
|
|
## 7. Confirm it's queryable
|
|
|
|
**Via the web UI:**
|
|
|
|
`web` is already running from step 2 (`docker compose up -d --build`
|
|
starts every service in the file). Open `http://localhost:3000`, run the
|
|
default query (`SELECT * FROM logs
|
|
ORDER BY timestamp DESC LIMIT 100`), and look for a row with
|
|
`message = "hello from sentry phase 0"`.
|
|
|
|
**Or via curl, if you want to skip the browser:**
|
|
|
|
```sh
|
|
curl -X POST http://localhost:8080/query \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"sql": "SELECT * FROM logs ORDER BY timestamp DESC LIMIT 10"}'
|
|
```
|
|
|
|
**Or via sentryctl, just to confirm api is up (doesn't check the data
|
|
itself):**
|
|
|
|
```sh
|
|
cd cli && go run ./cmd/sentryctl ping
|
|
```
|
|
|
|
If you see the row: that's Phase 0 done, end to end. If you don't, see
|
|
Troubleshooting below.
|
|
|
|
## Tearing down
|
|
|
|
```sh
|
|
docker compose down # stops and removes containers, keeps volumes
|
|
docker compose down -v # also wipes Redpanda/ClickHouse data — start clean next time
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
**Agent logs a TLS/certificate error on startup.**
|
|
Check the server cert's SAN actually covers how the agent is connecting
|
|
(`openssl x509 -in hack/dev-certs/out/server.pem -noout -ext
|
|
subjectAltName` — should list `DNS:ingest, DNS:localhost,
|
|
IP:127.0.0.1`). If you changed the agent's `ingest.endpoint` to something
|
|
not in that list, regenerate certs with an updated SAN in
|
|
`hack/dev-certs/generate.sh`, don't disable TLS verification.
|
|
|
|
**Agent connects but no data ever shows up in ClickHouse.**
|
|
Check each hop in order rather than guessing:
|
|
1. `docker compose logs ingest` — look for "batch produced to redpanda"
|
|
(gRPC front end got the batch) vs. errors.
|
|
2. `docker compose logs ingest` again — look for "batch flushed to
|
|
clickhouse" from the consumer half. If you see repeated "clickhouse
|
|
batch write failed... will redeliver" messages, `clickhouse-migrate`
|
|
likely hasn't finished (check `docker compose ps`) — the consumer will
|
|
keep retrying and self-heal once the table exists, per its
|
|
at-least-once design (see `/ingest/README.md`), so this may just need
|
|
more time rather than intervention.
|
|
3. `docker compose exec redpanda rpk topic list` — confirm
|
|
`sentry.logs.raw` exists (if `redpanda-provision` failed, it won't).
|
|
|
|
**`docker compose up` fails on `service_completed_successfully`.**
|
|
You're likely on Compose v1 (`docker-compose`, hyphenated) rather than v2
|
|
(`docker compose`, space) — see Prerequisites.
|
|
|
|
**Web UI query returns an error instead of rows.**
|
|
Open the browser's network tab — if the request never leaves the page
|
|
(CORS error in the console), confirm `api`'s `CORS_ALLOWED_ORIGIN`
|
|
(defaults to `*`, should not be the issue) and that `VITE_API_BASE_URL`
|
|
was set correctly at `web`'s build time (it's baked in, not read at
|
|
container start — see `/web/README.md`).
|