Open source · Apache 2.0

Self-hosted observability, from one container to an enterprise cluster

Logs, traces and metrics in one place you run yourself. Point any OpenTelemetry exporter at it. Data lands as compressed Parquet in your own bucket.

OTLP inParquet on S3gRPC :4317HTTP :4005PromQL · Jaeger · MCP
Live tailharborline-shop · last 15 min
level:error OR level:warn service_name:checkout
  • 14:02:29.700warncheckout · payment provider slow: p95 1.8s over 5m
  • 14:02:28.000infocheckout · POST /api/orders 201 in 84ms
  • 14:02:26.300infocheckout · POST /api/orders 201 in 91ms
  • 14:02:24.600infoshipping · label printed for order 8f3a2c
  • 14:02:22.900errorcheckout · upstream payments returned 504
  • 14:02:21.200infocheckout · GET /api/orders/8f3a2c 200 in 12ms
  • 14:02:19.500warninventory · stock cache miss rate 12%
  • 14:02:17.800infocheckout · order 8f3a2c queued for fulfilment
  • 14:02:16.100errorpayments · card authorisation timeout after 3000ms
  • 14:02:14.400infocart · cart merged for session 7c1e
  • 14:02:12.700warncheckout · payment provider slow: p95 1.8s over 5m
  • 14:02:11.000infocheckout · POST /api/orders 201 in 84ms
/v1/logs · /v1/traces · /v1/metrics

Three signals, one project, one API key

Every signal arrives over OTLP and is stored the same way, so a log links to its trace and a dashboard can mix all three.

Logs

  • Full-text and field search, query builder or SQL
  • Live tail, log patterns and anomalies
  • Logs around any result, and a link to its trace
Logs in detail →

Traces

  • OTLP trace ingestion and a trace explorer
  • Service map from real calls
  • Jaeger-compatible query API for existing clients
Traces in detail →

Metrics

  • OTLP and Prometheus remote-write ingestion
  • PromQL-compatible API for Grafana
  • 5-minute and 1-hour rollups that outlive raw samples
Metrics in detail →
New in v0.55 and v0.56

Beyond the three signals

Check your endpoints from where your users are, and see every host, pod and cloud resource with its health, from the data you already send.

Synthetic monitoring

Payments/EU
api-gateway99.98% · 182 ms
quotes-apiimpacted
Storefront
shop.harborline.examplecert 12 d
  • HTTP with assertions, TLS, TCP, DNS and ICMP
  • Dependencies: one outage, one page
  • Probe groups that fail over within a minute
Synthetics in detail →

Infrastructure inventory

harbor-prod-1cluster
shopnamespace
cart2/3 ready
cart-5d8f-q2x7rCrashLoop
  • Clusters to containers, hosts and services
  • Health with the reason, and a change feed
  • Nothing to install: built from your data
Infrastructure in detail →

Cloud connections

AWS · 1111222233334 regions
Azure · harborline-prod1 subscription
Load balancers · databases · buckets212
  • Read-only access to AWS and Azure
  • A wizard writes the CloudFormation or Bicep
  • Obzly stores identifiers, never cloud keys
Cloud connections in detail →
How it works

OTLP in, Parquet on S3

A batch is acknowledged only once the JetStream buffer has stored it. Workers write ZSTD Parquet to object storage, and queriers read it back with a warm cache.

Data flows from your services and synthetic probes into the api role, through the JetStream buffer to workers that write Parquet to object storage; queriers read it back for searches, dashboards, PromQL, Jaeger and MCP.Your servicesApp SDKs · OTLPOTel CollectorPrometheus remote-writeHTTP JSON · curlobzly-probe · syntheticsapiingestgRPC :4317HTTP :4005querycoordinatorUI · PromQLJaeger · /mcpYouBrowser · GrafanaClaude · CursorbrokerNATS JetStream3 replicasworkerParquet · ZSTDcompactionObject storageS3 · GCSAzure BlobMinIOqueriersegment cachequery fragmentsPostgrescatalog · file stats
Small installs run every role in one container. Larger ones run each role on its own and scale it separately, using the same image.
What's included

Everything a platform team asks for in the first month

logs

Patterns and anomalies

New, spiking and dropping patterns compared with an earlier period, with alerts on new error patterns.

logs

Log context

See the logs around any result from the same source, to find what led up to an error.

logs → traces

Log to trace

Jump from a log line to its trace. Kubernetes rollout markers show on the histogram.

dashboards

Grafana import

Build dashboards, or bring over a Grafana or OpenObserve dashboard's panels and layout.

incidents

Incidents

Error logs, failed spans and their shared traces grouped into incident sessions.

alerting

Alerts in ~15 s

Rules over PromQL, log searches or trace latency, sent to webhooks, Slack, PagerDuty or email.

ai

AI observability

Claude Code usage per project: cost, tokens, cache use and sessions.

/mcp

MCP server

Claude and Cursor search logs, inspect traces and run PromQL with your own access.

35+ sources

Generated configs

Pick Nginx, Postgres, Kafka, Kubernetes and more; get a ready-to-run Collector config.

lifecycle

Retention and sampling

Retention per project and signal, tail sampling that keeps whole traces, log head sampling.

governance

Audit log and API keys

Who changed what and when. Keys show last use, and unused keys are easy to clean up.

synthetics

Folders and dependencies

Group monitors in folders. A child of a down parent shows Impacted and stays quiet.

probe groups

Probes that fail over

Run several probes per location. If one stops, the others take its monitors within a minute.

inventory

Cloud resources

Load balancers, databases, buckets and functions from AWS and Azure join your hosts and clusters.

settings

Shared channels

Slack, PagerDuty, webhook and email channels defined once and shared by every project.

self-monitoring

Watch Obzly itself

Prometheus metrics on every role, a ready Grafana dashboard and SLO alert rules.

SERVICE_MODE=all → api · worker · broker · querier

From one container to a cluster

Start small. The same image grows into a highly available deployment when your volume does.

1Install script

One Linux host

Installs Docker if needed, starts Obzly with Postgres and Valkey, and restarts on reboot. About two minutes.

Quick install →
2Docker Compose

Your own compose file

Copy the example compose and .env, set a Postgres password, run docker compose up -d.

Docker Compose →
3Helm, mode: ha

A highly available Site

Three brokers, plus api, worker and querier replicas on Kubernetes, with Parquet in your bucket.

Helm chart →
4Control plane

Many Sites, one login

One control plane in front of regions, environments or business units. Data stays in each Site.

Control plane & Sites →
Enterprise, included

Built for the security review and the 3 a.m. page

No paid tier holds these back. They ship in the same Apache 2.0 image.

SSO with any OIDC provider

Entra ID, Google Workspace, Cognito and others. IdP groups map to project and Site roles.

SCIM 2.0 provisioning

Users and groups from Okta or Entra ID into organizations and teams. Deprovisioning deactivates.

TOTP MFA

Required for admins. One switch in Settings requires it for everyone, and every reset lands in the audit log.

Multi-site control plane

Central identities and per-Site access grants. A Site's query API never faces the internet.

Disaster recovery

Backup, restore, DR and upgrade runbooks, a measured restore drill and obzly reconcile.

Quotas and plans

Ingest rate, storage, retention and project limits per organization, enforced on every Site.

All enterprise features →

License

Apache 2.0. Read every line.

Your data stays on your infrastructure, and you or your security team can audit all of the code.