Skip to content
sigiro
Esc
navigateopen⌘Jpreview
On this page

Quickstart

Run sigiro with one docker command. Point OpenTelemetry at it. Then ask it what changed and why. This takes five minutes. You need no collector and no configuration file.

In this tutorial you start a sigiro server, send it telemetry from your own service, and ask it two questions. At the end you read a diagnosis and run the SQL behind it. This takes five minutes.

sigiro is one process. You deploy no collector and you write no configuration file.

1. Run it

curl -fsSL https://sigiro.com/install | sh
sigiro serve

The script reads your operating system and processor. Then it checks the SHA-256 of the download against the published checksum. It writes the binary to ~/.local/bin. Set SIGIRO_INSTALL_DIR for a different directory.

Builds exist for Linux and macOS on arm64, and for Linux on x86-64. On another platform, use the container.

docker run -p 4317:4317 -p 4318:4318 -p 9999:9999 ghcr.io/sigiroai/sigiro

Add -v sigiro-data:/var/lib/sigiro to keep the data across container restarts.

Each of the three ports has one function:

Port Protocol
4317 OTLP over gRPC
4318 OTLP over HTTP
9999 the query and diagnose API

At the first start, sigiro downloads its query extensions. This can take 30–90 seconds, so expect a pause before the server accepts a request. Each later start is immediate. sigiro writes the data to SIGIRO_DATA_DIR. That directory is ~/.local/share/sigiro for the binary, and /var/lib/sigiro in the image.

Notice that the server asks you for no key. A self-hosted server authenticates no request, so keep it on a private network. To read why the network is the boundary, see About the one-process design.

2. Send it telemetry

Any OpenTelemetry SDK or collector in your stack works without a change. Point the standard environment variables at sigiro:

OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
OTEL_SERVICE_NAME=checkout \
  <your-app-start-command>

If your code has no instrumentation yet, do not add it by hand. Follow Instrument your code with an agent first, then come back here.

Now send some real traffic through your service, and confirm that the telemetry arrived:

curl http://localhost:9999/v1/services

The response is a JSON object with a services array. Your service appears in that array within a few seconds of the first request. If the array is empty, check that the port is 4318 for OTLP over HTTP and 4317 for OTLP over gRPC.

3. Ask what changed

anomalies is the entry point of the loop. It returns the shifts that deviate from the recent baseline of each service, biggest shift first.

sigiro anomalies
sigiro anomalies --service checkout

You configure nothing here. There are no thresholds to choose, and a service that is always slow but stable is not an anomaly. To read how sigiro decides that, see About evidence instead of a dashboard.

Notice that the list can be empty on a young server. sigiro needs a few 5-minute buckets of history before it can compare anything, so run your service for a while and then ask again.

4. Ask why

diagnose returns one structured evidence block for a service and a time window. The block starts with a ranked list of what deserves attention. Under that, it holds error counts, error breakdowns for each operation, LLM statistics for each model, sampled spans, and deduplicated log patterns. Every row also carries a ready-to-run SQL query.

sigiro diagnose checkout
sigiro diagnose checkout --from $(date -v-1H +%s) --grep POST

The command prints indented JSON. Read the findings array first: it is sorted critical first, and each item carries a summary you can read and a drill_down_sql you can run.

An agent asks the same question over HTTP. The HTTP request needs an explicit window, and both timestamps are microseconds since the Unix epoch:

curl -X POST http://localhost:9999/v1/diagnose \
  -H 'content-type: application/json' \
  -d "{\"service\":\"checkout\",
       \"from_ts\":$(( $(date +%s) - 900 ))000000,
       \"to_ts\":$(date +%s)000000}"

The --from/--to flags on the CLI take epoch seconds, and the CLI defaults the window to the last 15 minutes. The HTTP body takes microseconds and defaults nothing. sigiro rejects a seconds value on the HTTP path with a message that names the unit, so a wrong unit fails loudly rather than returns an empty window.

5. Run the query behind a row

When the evidence block does not answer your question, run the SQL that a row gave you. Your telemetry is a set of tables, and the body of a query request is the raw SQL rather than JSON:

curl -X POST http://localhost:9999/v1/query \
  --data "SELECT service_name, count(*) AS errors
          FROM sigiro_spans
          WHERE status_code = 2 AND timestamp > now() - INTERVAL '1 hour'
          GROUP BY 1 ORDER BY errors DESC"

The response is a JSON array of row objects. status_code is the OTLP enum, so 2 is an error.

Notice that the query bounds timestamp. Bound timestamp in every query: sigiro keeps no secondary index, so a bounded query reads a small number of files and an unbounded query reads every file. About the one-process design explains why.

sigiro_spans is one of nine tables. The hosted guide lists all nine with the rules that apply to them, and About the tables explains what each family measures.

What you did

You started a server, sent it OpenTelemetry, asked it what changed, asked it why, and ran the query that proves one of its answers. That is the whole loop that an agent runs on its own.

Next

Was this page helpful?