Thanks to visit codestin.com
Credit goes to github.com

Skip to content
/ sigil Public

Actually Useful AI Observability | OSS, OTel-Native, Inside Grafana

License

Notifications You must be signed in to change notification settings

grafana/sigil

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

313 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Grafana Sigil

Grafana Sigil logo

Sigil is an open-source AI observability project from Grafana.

It's actually useful AI o11y.

It combines OpenTelemetry traces with normalized LLM generation data, so you can inspect conversations, completions, and traces in one place.

What You Get

  • Grafana app plugin (/apps/plugin) for conversations, completions, traces, and settings.
  • Go service (/sigil) for generation ingest and query APIs on :8080.
  • Evaluations: online evaluation (live scoring on production traffic) is supported; offline experiments (datasets/regressions) are planned. See docs/references/ai-observability-evaluation-market.md.
  • SDKs (/sdks) for Go, Python, TypeScript/JavaScript, Java, and .NET/C#:
    • OTel traces with AI-specific attributes (gen_ai.*).
    • OTel metrics: latency histograms and token usage distributions.
    • Structured generation export to Sigil.
  • Alloy / OTel Collector as the telemetry pipeline (traces + metrics).
  • Tempo (docker compose) as trace storage.
  • Prometheus as metrics storage for SDK-emitted AI metrics.
  • MySQL as default metadata and record-reference storage.
  • Object storage for compacted payloads:
    • MinIO (default local/core profile)
    • AWS S3
    • Google Cloud Storage
    • Azure Blob Storage

Why Sigil

  • Trace + generation correlation: connect model calls, tool executions, and request traces.
  • OpenTelemetry-native: SDKs emit OTel traces and metrics via standard OTLP. Works with any OTel-compatible collector.
  • Built-in AI metrics: latency histograms (streaming, sync, tool calls), token usage distributions, error rates -- per provider, model, agent, and namespace.
  • Generation-first ingest: export normalized generation payloads across providers.
  • Grafana-native experience: query and explore from the Sigil app plugin.
  • SDK support: Go, Python, TypeScript/JavaScript, Java, and .NET/C# SDKs with provider helpers.

Architecture At A Glance

flowchart LR
    A["Your AI App"]
    A -->|"OTLP traces + metrics"| AL["Alloy / Collector"]
    A -->|"Normalized generations"| B["Sigil API"]
    AL -->|"enriched traces"| C["Grafana Tempo"]
    AL -->|"enriched metrics"| P["Prometheus"]
    B --> D["MySQL (hot metadata + payloads)"]
    B --> E["Object storage (compacted payloads)"]
    F["Grafana"] -->|"generations"| B
    F -->|"traces"| C
    F -->|"metrics"| P
Loading

Get Started (Local)

Prerequisites

1. Clone the repository

git clone https://github.com/grafana/sigil.git
cd sigil

2. Install toolchain and dependencies

mise trust
mise install
mise run doctor:go
mise run deps

3. Start the local stack

mise run up

This starts Grafana, the Sigil app plugin, the Sigil API service, Alloy, Tempo, Prometheus, MySQL, and MinIO. The mise run up task also enables Grafana development mode (DEVELOPMENT=true) and Docker Compose watch mode so plugin/frontend and plugin backend changes reload without manually restarting containers. Local Compose config runs Tempo in multitenant mode and Alloy injects X-Scope-OrgID: fake on trace ingest so local query and ingest tenant semantics stay aligned.

4. Open the Sigil app

Local default runs with anonymous Grafana auth enabled.

5. Verify the API is running

curl -s http://localhost:8080/healthz
curl -s http://localhost:8080/api/v1/conversations
curl -s http://localhost:8080/api/v1/completions

6. Run local hot/cold storage E2E

With mise run up still running in another terminal:

mise run test:e2e:storage-local

If compaction is slower on your machine, increase the wait budget:

SIGIL_E2E_COMPACTION_WAIT=5m mise run test:e2e:storage-local

Deploy On Kubernetes (Helm)

The Sigil Helm chart lives in charts/sigil.

Basic install (defaults to ghcr.io/grafana/sigil:latest):

helm upgrade --install sigil ./charts/sigil \
  --namespace sigil \
  --create-namespace

To pin to an immutable published image from CI, set the image tag explicitly:

helm upgrade --install sigil ./charts/sigil \
  --namespace sigil \
  --create-namespace \
  --set image.tag=<git-sha>

Image publishing automation:

  • GitHub Actions workflow: .github/workflows/sigil-image-publish.yml
  • Trigger: pushes to main that touch sigil/** or workflow/go workspace files.
  • Published tags: ghcr.io/grafana/sigil:<git-sha> and ghcr.io/grafana/sigil:latest

Chart docs and reference:

SDK Quick Examples

TypeScript

import { SigilClient } from "@grafana/sigil-sdk-js";

const client = new SigilClient({
  generationExport: {
    protocol: "http",
    endpoint: "http://localhost:8080/api/v1/generations:export",
    auth: { mode: "tenant", tenantId: "dev-tenant" },
  },
});

// Configure OTEL exporters (traces/metrics) in your app OTEL setup.

await client.startGeneration(
  {
    conversationId: "conv-1",
    model: { provider: "openai", name: "gpt-5" },
  },
  async (recorder) => {
    recorder.setResult({
      output: [{ role: "assistant", content: "Hello from Sigil" }],
    });
  }
);

await client.shutdown();

JavaScript

import { SigilClient } from "@grafana/sigil-sdk-js";

const client = new SigilClient({
  generationExport: {
    protocol: "http",
    endpoint: "http://localhost:8080/api/v1/generations:export",
    auth: { mode: "tenant", tenantId: "dev-tenant" },
  },
});

await client.startGeneration(
  {
    conversationId: "conv-1",
    model: { provider: "openai", name: "gpt-5" },
  },
  async (recorder) => {
    recorder.setResult({
      output: [{ role: "assistant", content: "Hello from Sigil" }],
    });
  }
);

await client.shutdown();

Go

cfg := sigil.DefaultConfig()
cfg.GenerationExport.Protocol = sigil.GenerationExportProtocolHTTP
cfg.GenerationExport.Endpoint = "http://localhost:8080/api/v1/generations:export"
cfg.GenerationExport.Auth = sigil.AuthConfig{
	Mode:     sigil.ExportAuthModeTenant,
	TenantID: "dev-tenant",
}

client := sigil.NewClient(cfg)
defer func() { _ = client.Shutdown(context.Background()) }()

ctx, rec := client.StartGeneration(context.Background(), sigil.GenerationStart{
	ConversationID: "conv-1",
	Model:          sigil.ModelRef{Provider: "openai", Name: "gpt-5"},
})
defer rec.End()

rec.SetResult(sigil.Generation{
	Output: []sigil.Message{sigil.AssistantTextMessage("Hello from Sigil")},
}, nil)

Python

from sigil_sdk import Client, ClientConfig, GenerationStart, ModelRef, assistant_text_message

client = Client(
    ClientConfig(
        generation_export_endpoint="http://localhost:8080/api/v1/generations:export",
    )
)

with client.start_generation(
    GenerationStart(
        conversation_id="conv-1",
        model=ModelRef(provider="openai", name="gpt-5"),
    )
) as rec:
    rec.set_result(output=[assistant_text_message("Hello from Sigil")])

client.shutdown()

SDKs We Support

Provider helper docs:

Documentation

Contributing

Forking and contribution workflow lives in CONTRIBUTING.md.

License

  • Repository code is licensed under GNU AGPL v3.0. See LICENSE.
  • SDK subfolders under sdks/ are licensed under Apache License 2.0. See sdks/LICENSE.

About

Actually Useful AI Observability | OSS, OTel-Native, Inside Grafana

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors