Files
go-otel/internal/storage/store.go
T
mats 49f9bb3458
Build and Publish / Metadata (push) Successful in 2s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 1m3s
materialized view and a bit better ui
2026-09-19 12:43:17 +02:00

112 lines
4.2 KiB
Go

package storage
import (
"context"
"encoding/json"
"git.tornberg.me/go-otel/internal/websocket"
)
// SearchOptions narrows a Search call beyond the free-text query.
type SearchOptions struct {
// Query is a case-insensitive substring match against the raw entry JSON.
Query string
// Type restricts results to a single telemetry type (traces, metrics, logs).
// Empty matches any type.
Type string
// Since restricts results to entries with Timestamp >= Since (unix nanoseconds).
// Zero means no lower bound.
Since int64
// Until restricts results to entries with Timestamp <= Until (unix nanoseconds).
// Zero means no upper bound.
Until int64
}
// Store interface for telemetry history persistence.
type Store interface {
Append(ctx context.Context, entry websocket.HistoryEntry) error
GetHistory(ctx context.Context, limit int) ([]websocket.HistoryEntry, error)
Search(ctx context.Context, opts SearchOptions, limit int) ([]websocket.HistoryEntry, error)
}
// StatsQuerier is implemented by stores that can answer aggregate
// time-series questions (currently ClickHouseStore). The stats HTTP
// endpoints are only enabled when the configured store implements it.
type StatsQuerier interface {
// ErrorStats returns hourly/daily total and error entry counts.
ErrorStats(ctx context.Context, service string, hours int, daily bool) ([]StatsPoint, error)
// ReleaseSeries returns per-release error-count time series.
ReleaseSeries(ctx context.Context, service string, hours int) (map[string][]StatsPoint, error)
// Services lists distinct services seen in the rollup.
Services(ctx context.Context) ([]string, error)
}
// TraceSummary is the per-trace rollup shown in overview tables: everything
// needed to render a row without reading any span payloads. Times are unix
// nanoseconds, matching the rest of the API.
type TraceSummary struct {
ID string `json:"id"`
Name string `json:"name"`
StartTime int64 `json:"startTime"`
EndTime int64 `json:"endTime"`
Duration int64 `json:"duration"`
SpanCount int `json:"spanCount"`
ErrorCount int `json:"errorCount"`
Services []string `json:"services"`
}
// TraceQuerier is implemented by stores that can look a trace up by id
// without scanning payloads, and can summarise many traces cheaply
// (ClickHouseStore).
type TraceQuerier interface {
// TraceEntries returns every stored entry that contains the trace, with
// each payload trimmed to that trace's spans/log records. Newest first.
TraceEntries(ctx context.Context, traceID string, limit int) ([]websocket.HistoryEntry, error)
// TraceSummaries returns summaries keyed by trace id; unknown ids are absent.
TraceSummaries(ctx context.Context, ids []string) (map[string]TraceSummary, error)
}
// Occurrence is one persisted occurrence of an issue. Sample is the issue
// sample as JSON, so its shape can evolve without a schema change.
type Occurrence struct {
IssueID string
Kind string
Service string
Timestamp int64
TraceID string
SpanID string
Sample json.RawMessage
}
// IssueTrace is one trace an issue occurred in.
type IssueTrace struct {
TraceID string `json:"traceId"`
Hits int `json:"hits"`
FirstSeen int64 `json:"firstSeen"`
LastSeen int64 `json:"lastSeen"`
Summary *TraceSummary `json:"summary,omitempty"`
Samples []json.RawMessage `json:"-"`
}
// IssueTracesOptions pages through an issue's traces, most recently hit first.
// Before is a LastSeen boundary (exclusive); zero starts from the newest.
type IssueTracesOptions struct {
Limit int
Before int64
}
// IssueTracesPage is one page of an issue's traces plus totals. Untraced holds
// occurrences that carried no trace id (only on the first page).
type IssueTracesPage struct {
Traces []IssueTrace
Untraced []json.RawMessage
TotalOccurrences int
HasMore bool
}
// OccurrenceStore persists every issue occurrence and answers "which traces
// did this issue happen in" in one query (ClickHouseStore).
type OccurrenceStore interface {
AppendOccurrence(ctx context.Context, occ Occurrence) error
IssueTraces(ctx context.Context, issueID string, opts IssueTracesOptions) (IssueTracesPage, error)
}