tempo

package
v0.9.685 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package tempo implements a read-through client for an external Grafana Tempo deployment (v0.5.189). Used as a fallback for trace-by-id lookups when Coremetry sampled the trace out — many operators keep 100% retention in Tempo (+ S3) while running Coremetry at 5% for affordable hot-path observability. Without this, the operator hits "trace not found" on every long-tail ID and has to switch tabs to Grafana. With it, the same `/trace?id=` URL silently falls back, with a banner explaining where the data came from so the operator isn't misled about coverage.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is the per-process Tempo client. Holds the live config + an HTTP client tuned for typical Tempo S3-backed cold lookup latency (1-5s in practice; we allow up to 30s for the long tail).

func New

func New() *Service

func (*Service) Configure

func (s *Service) Configure(cfg Settings)

Configure swaps the live config. Called by SavePersisted + LoadPersisted; safe for concurrent reads via the RWMutex. Also rebuilds the HTTP client when the TLS-verify flag flips so an admin toggling "Skip TLS verify" takes effect without restarting the process.

func (*Service) Configured

func (s *Service) Configured() bool

Configured reports whether Tempo is wired up and ready to answer lookups. Used by the trace-fallback path to skip the HTTP attempt when no backend is configured.

func (*Service) CurrentSettings

func (s *Service) CurrentSettings() Settings

CurrentSettings returns the full config including the token — only used by SavePersisted to round-trip the existing token when the operator submits a partial update that doesn't include a new one. Never call this from a handler that echoes its return value over the wire.

func (*Service) LoadPersisted

func (s *Service) LoadPersisted(ctx context.Context, store settingsStore) error

LoadPersisted hydrates the in-memory config from the saved JSON blob in system_settings. Missing blob = empty config (Configured reports false; lookups skip the HTTP attempt). Called once at boot from main(); safe to call again on demand if the operator wants a hard re-read.

func (*Service) LookupTrace

func (s *Service) LookupTrace(ctx context.Context, traceID string) ([]chstore.SpanRow, error)

LookupTrace asks Tempo for a trace by ID. Returns an empty slice + nil error when Tempo doesn't have it (404) so callers can treat "not found" as a clean fall-through rather than an error condition. Network / parse failures surface as real errors.

Tempo's GET /api/traces/{id} returns OTLP-encoded data; we request JSON via Accept so we don't have to pull in a protobuf dependency for a single endpoint.

func (*Service) SavePersisted

func (s *Service) SavePersisted(ctx context.Context, store settingsStore, cfg Settings) error

SavePersisted writes the typed config to system_settings. The HTTP handler calls this after merging the operator's submitted payload with the previously stored token (so a partial update without a new token doesn't blank the existing one).

func (*Service) Snapshot

func (s *Service) Snapshot() Snapshot

Snapshot returns the public config view (no token).

func (*Service) StartConfigRefresh added in v0.5.324

func (s *Service) StartConfigRefresh(ctx context.Context, store settingsStore, interval time.Duration)

StartConfigRefresh — v0.5.324. Background poll that keeps the in-memory Tempo config in sync with the shared persisted blob in a multi-pod cluster. interval ≤ 0 → 30s.

type Settings

type Settings struct {
	Enabled bool   `json:"enabled"`
	BaseURL string `json:"baseUrl"`
	// AuthType — none | bearer | basic. Bearer covers most
	// Grafana Cloud setups (Tempo API key as Bearer); basic
	// covers self-hosted Tempo behind nginx with htpasswd.
	AuthType string `json:"authType,omitempty"`
	// Token holds the bearer token OR the basic-auth password.
	// Never echoed in Snapshot() responses — the UI only sees
	// HasToken so the operator can tell if one is configured.
	Token string `json:"token,omitempty"`
	// Username — only used for basic auth.
	Username string `json:"username,omitempty"`
	// OrgID — X-Scope-OrgID header for multi-tenant Tempo (Grafana
	// Cloud requires this; self-hosted single-tenant ignores it).
	OrgID string `json:"orgId,omitempty"`
	// InsecureSkipVerify disables TLS certificate verification on
	// the HTTPS path. Useful for self-hosted Tempo behind a
	// self-signed cert during a POC; left off by default since
	// production deployments should fix their PKI instead.
	InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
}

Settings is the persisted Tempo backend config. Only one Tempo endpoint per Coremetry install today; if federation becomes a real need, extend to a list.

type Snapshot

type Snapshot struct {
	Enabled            bool   `json:"enabled"`
	BaseURL            string `json:"baseUrl"`
	AuthType           string `json:"authType,omitempty"`
	HasToken           bool   `json:"hasToken"`
	Username           string `json:"username,omitempty"`
	OrgID              string `json:"orgId,omitempty"`
	InsecureSkipVerify bool   `json:"insecureSkipVerify,omitempty"`
}

Snapshot is the version returned by GET /api/settings/tempo. Mirrors Settings but masks the token + adds a HasToken signal.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL