# Metrics and logs

## Storage model

The bridge heartbeat never creates an unbounded row stream. The API aggregates
every sample into a unique five-minute `ServerMetric` bucket and retains sample
counts, sums, minima and maxima for players, CPU, resident memory and API
latency. The latest values remain on `Server` for realtime status.

Every five minutes the worker incrementally rebuilds the open hour/day buckets
in `ServerMetricRollup`. A first run backfills existing five-minute history;
later runs only revisit the current bucket. Uptime is heartbeat-bucket coverage,
bounded to the server's actual lifetime so time before registration is not
reported as downtime.

Raw `ServerEvent` rows are summarized in `ServerEventMinute`. These rows contain
total/error/resource-error counts, event-type counts and errors per resource.
The worker resumes from the latest aggregate with a one-hour overlap, so a
worker restart or delayed bridge outbox delivery does not leave gaps.

## API and panel

`GET /v1/organizations/:organizationId/servers/:serverId/observability` accepts
`resolution=FIVE_MINUTES|HOUR|DAY` plus optional ISO `from` and `to`. It returns
the graph series, uptime, summary values, events per minute, errors per resource
and the effective retention settings.

`GET /v1/organizations/:organizationId/activity` supports tenant-safe server,
type, resource and date filters with page/limit pagination. The corresponding
`/activity/export` endpoint creates CSV or JSON exports (maximum 10,000 events);
CSV cells are protected against spreadsheet-formula injection.

The Operations panel exposes these values under **Metrics & uptime** and
**Events & logs**.

## Retention

Organizations configure separate `rawEventRetentionDays` and
`metricRetentionDays` values in Privacy settings. The daily retention worker
deletes expired raw events, five-minute metrics, hour/day rollups and event
minute aggregates. Allowed ranges are 1–365 days for raw events and 7–730 days
for metrics.
