api

package
v0.9.68 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 61 Imported by: 0

Documentation

Overview

Package api — AI observability endpoints (v0.5.163). The /ai page is the Coremetry-native counterpart to Langfuse: every Copilot Explain call lands as a row in the ai_calls CH table and these endpoints surface it as KPIs / timeseries / a recent- calls table. No external service involvement: prompts + samples stay inside the customer's CH cluster.

Package api handler for /admin/alert-tuning — surfaces the noisiest rules in a window plus per-rule actionable suggestions for the v0.5.127-129 dampening knobs. Admin-only read endpoint; cached 5 min because rule-noise pattern doesn't shift minute- to-minute and operators commonly load this page in bursts.

Package api handler for SLO autocreate (v0.5.147). Scans recent telemetry, picks the busiest N services, and stamps a baseline-grounded availability + latency SLO for each one the install doesn't already have. Admin-only, audit-logged, idempotent.

Tempo-compatible HTTP API. Lets Grafana add Coremetry as a Tempo datasource: only the endpoints Grafana actually calls during search and trace view are implemented (echo, search, search/tags, search/tag/{name}/values, traces/{id}).

Both the v1 and v2 paths are wired so older / newer Grafana versions work.

Spec reference: https://grafana.com/docs/tempo/latest/api_docs/

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AIRate added in v0.5.167

type AIRate struct {
	InputPer1M  float64 `json:"inputPer1M"`
	OutputPer1M float64 `json:"outputPer1M"`
}

AIRate is the per-model price quote used by the /ai cost estimate (v0.5.167). USD per 1M tokens, separately for input and output. Stored as a JSON blob in system_settings["ai.rates"] so admins can override the bundled defaults without code change. Local-model endpoints (Ollama, vLLM, LM Studio) should configure 0/0 — that's the default shape for any model not in the table.

type AnomalyRootCause added in v0.8.167

type AnomalyRootCause struct {
	RootCause
	AnomalyID   string `json:"anomalyId"`
	AnomalyKind string `json:"anomalyKind"` // log_pattern | log_template_new | trace_op
	Pattern     string `json:"pattern"`     // log pattern name OR operation name (trace_op)
}

AnomalyRootCause is the anomaly-anchored sibling of RootCause (v0.8.x). It embeds the SAME RootCause fan-out result so /anomalies and /problems share one rendering path later, and stamps the anchor from the AnomalyEvent (id/kind/pattern/service) instead of a Problem. Read-only.

type AvailablePage added in v0.5.251

type AvailablePage struct {
	ID    string `json:"id"`    // route path; matches Sidebar href
	Label string `json:"label"` // i18n key (e.g. "nav.inbox")
	Group string `json:"group"` // i18n key for group heading
}

AvailablePage is one entry in the canonical sidebar-page registry that powers the custom-role checkbox grid in Settings → Roles. The frontend Sidebar.tsx mirrors these IDs as `href` values; keeping the registry on the backend means the role catalog's page IDs are validated against a single source of truth instead of drifting when somebody adds a sidebar entry.

IDs match the frontend route paths verbatim (e.g. "/inbox", "/services"). Group + label are i18n keys; the frontend resolves them via useT() so a language switch surfaces immediately.

AdminOnly pages are excluded from this registry — custom roles subset viewer's access only; admin/editor surfaces remain gated by their hard-coded role checks.

type CHAsyncInsert added in v0.5.346

type CHAsyncInsert struct {
	Database         string `json:"database"`
	Table            string `json:"table"`
	TotalBytes       uint64 `json:"totalBytes"`
	EntriesCount     uint64 `json:"entriesCount"`
	FirstUpdateMsAgo uint64 `json:"firstUpdateMsAgo"`
}

CHAsyncInsert mirrors one row of system.asynchronous_inserts — a buffered INSERT awaiting the server-side coalescing flush. ageMs > 0 = how long it's been sitting; bytes/rows reflect what's queued so far. The whole list usually has a few rows during steady ingest, climbs visibly under burst (good sign — coalescence working) and falls back as the busy_timeout fires.

type CHClusterNode added in v0.5.388

type CHClusterNode struct {
	Cluster     string `json:"cluster"`
	ShardNum    uint32 `json:"shardNum"`
	ReplicaNum  uint32 `json:"replicaNum"`
	HostName    string `json:"hostName"`
	HostAddress string `json:"hostAddress,omitempty"`
	Port        uint16 `json:"port"`
	IsLocal     bool   `json:"isLocal"`
}

type CHHealth added in v0.5.319

type CHHealth struct {
	// v0.5.388 — topology banner. First field on the payload so
	// the operator's eye lands on the cluster mode + node count
	// before drilling into the perf panels. Powered by:
	//   - cfg.ClusterName (operator-set env var) → "configured"
	//     side
	//   - system.clusters lookup (CH self-report) → "live" side
	//   - system.tables engine filter → which tables wear the
	//     Distributed wrapper vs plain MergeTree
	// All three are needed because a misconfigured cluster name
	// looks identical to standalone from the driver — only
	// system.clusters confirms ZK actually wired the node up.
	Topology     CHTopology         `json:"topology"`
	SlowQueries  []CHSlowQuery      `json:"slowQueries"`
	Merges       []CHMerge          `json:"merges"`
	PartHotspots []CHPartHotspot    `json:"partHotspots"`
	Replication  []CHReplicationLag `json:"replicationLag,omitempty"`
	// v0.5.346 — in-flight async_insert batches. Each row =
	// one currently-buffered INSERT awaiting flush. Lets the
	// operator see whether the tuned async_insert_busy_timeout
	// is doing useful coalescence or sitting idle.
	AsyncInserts []CHAsyncInsert `json:"asyncInserts,omitempty"`
	// v0.6.22 — in-flight ALTER TABLE … DELETE / UPDATE
	// mutations. Healthy queue is empty; growing queue is an
	// operator-visible signal that a state-table mutation
	// pattern needs rethinking (tombstone, ReplacingMergeTree,
	// etc.). Top 20 most-recent unfinished, sorted by parts-
	// remaining desc so the worst offender lands on top.
	Mutations []CHMutation `json:"mutations,omitempty"`
	Generated int64        `json:"generatedAt"` // unix ns of snapshot
}

CHHealth — v0.5.319. Datadog-style ClickHouse dashboard payload. Gives the operator a single-page view of CH-side perf health: slow queries, merge queue depth, part overflow risk, async insert pressure. Powers the new /admin/clickhouse page.

Read directly from system.* tables which CH provides as built-in observability surface. Each panel is fail-isolated — a CH version without one of the views (e.g. older OS edition without system.async_inserts) leaves the slot at its zero value rather than 500-ing the whole page.

func (CHHealth) String added in v0.5.319

func (h CHHealth) String() string

String — short summary line used in /admin/stats footer link.

type CHMerge added in v0.5.319

type CHMerge struct {
	Database    string  `json:"database"`
	Table       string  `json:"table"`
	ElapsedSec  float64 `json:"elapsedSec"`
	ProgressPct float64 `json:"progressPct"`
	RowsRead    uint64  `json:"rowsRead"`
	MergedSize  uint64  `json:"mergedSizeBytes"`
}

type CHMutation added in v0.6.22

type CHMutation struct {
	Database   string `json:"database"`
	Table      string `json:"table"`
	Command    string `json:"command"`   // trimmed; full text would be unbounded
	Parts      uint64 `json:"parts"`     // parts left to mutate
	ElapsedMs  int64  `json:"elapsedMs"` // since the mutation was submitted
	LatestFail string `json:"latestFail,omitempty"`
}

CHMutation — v0.6.22. One row per in-flight or recently-stuck ALTER TABLE … DELETE / UPDATE mutation. ALTER mutations rewrite matching parts in the background; healthy systems clear them within seconds. A growing queue is the operator-visible signature that a state table is being mutated faster than CH can rebuild parts — at which point the right fix is a tombstone or ReplacingMergeTree pattern, not "wait longer".

Powered by system.mutations. Filter is_done = 0 so only the queue depth shows up; finished mutations age out of the table after ~7 days and don't matter for live ops.

type CHPartHotspot added in v0.5.319

type CHPartHotspot struct {
	Database   string `json:"database"`
	Table      string `json:"table"`
	Parts      uint64 `json:"parts"` // active parts count
	RowsTotal  uint64 `json:"rowsTotal"`
	BytesTotal uint64 `json:"bytesTotal"`
}

type CHReplicationLag added in v0.5.319

type CHReplicationLag struct {
	Database      string `json:"database"`
	Table         string `json:"table"`
	QueueSize     uint32 `json:"queueSize"`
	AbsoluteDelay uint64 `json:"absoluteDelaySec"`
}

type CHSlowQuery added in v0.5.319

type CHSlowQuery struct {
	Query       string  `json:"query"`
	ElapsedMs   float64 `json:"elapsedMs"`
	MemoryMB    float64 `json:"memoryMb"`
	ReadRows    uint64  `json:"readRows"`
	ResultRows  uint64  `json:"resultRows"`
	EventTimeNs int64   `json:"eventTimeNs"`
	User        string  `json:"user"`
}

type CHTopology added in v0.5.388

type CHTopology struct {
	// Mode is "cluster" when an ON CLUSTER name is configured AND
	// system.clusters confirms it exists; "standalone" otherwise.
	// A misconfigured cluster name (operator set the env var but
	// the CH server has no matching <remote_servers> block) shows
	// up as "standalone" with a non-empty ConfiguredCluster — the
	// banner flags this mismatch.
	Mode              string   `json:"mode"`
	ConfiguredCluster string   `json:"configuredCluster,omitempty"`
	Database          string   `json:"database"`
	ConnectedHosts    []string `json:"connectedHosts,omitempty"`
	// Nodes — one entry per (shard, replica) registered in
	// system.clusters for the configured cluster. Empty in
	// standalone mode.
	Nodes []CHClusterNode `json:"nodes,omitempty"`
	// Table engine breakdown — drives the "distributed table?"
	// answer. DistributedTables > 0 = the install is running the
	// full cluster pattern (Distributed wrapper + _local
	// Replicated tables). LocalReplicated = Replicated*MergeTree
	// count. Plain = MergeTree / ReplacingMergeTree without
	// replication. Used to confirm migrations actually built the
	// cluster pattern they were supposed to.
	DistributedTables int `json:"distributedTables"`
	LocalReplicated   int `json:"localReplicated"`
	PlainMergeTree    int `json:"plainMergeTree"`
	// ZK / Keeper presence — system.zookeeper exists only when
	// CH is configured with a Keeper endpoint. ReplicatedMergeTree
	// needs this; absence on a cluster mode install is a config
	// bug that should surface here, not via a CREATE TABLE failure
	// six hours into ingest.
	ZooKeeperConnected bool `json:"zookeeperConnected"`
	// v0.5.419 — resolved per-table shard expression map. Lets
	// the operator audit "which shard key did each table actually
	// get?" without `SHOW CREATE TABLE` round-trips. Empty in
	// standalone mode.
	ShardPolicy map[string]string `json:"shardPolicy,omitempty"`
	// v0.5.428 — bug-fix: distinguish "system.clusters probe failed"
	// from "probe succeeded but returned no rows". Without this the
	// frontend's misconfig banner false-positives when CH is busy
	// enough to time out the probe (v0.5.424 raised the timeout
	// from 3s to 8s, but operators still hit it intermittently).
	// Empty when the probe completed cleanly (regardless of result
	// count); populated with the error string when it failed. The
	// frontend treats a populated error as "soft warning, can't
	// confirm cluster" rather than the hard "misconfig" banner.
	ClusterProbeError string `json:"clusterProbeError,omitempty"`
	// v0.5.439 — when the live probe fails but a recent successful
	// probe is cached, Nodes is filled from the cache and these
	// two flags surface the staleness so the frontend renders a
	// small "last refreshed N min ago" pill instead of the warn
	// banner. ClusterProbeError stays empty in this path — the
	// banner only fires when there's no cache to fall back on.
	ClusterNodesStale bool  `json:"clusterNodesStale,omitempty"`
	ClusterNodesAgeMs int64 `json:"clusterNodesAgeMs,omitempty"`
}

CHTopology — what cluster does Coremetry think it's talking to, and does the live CH agree.

type CacheKeyHit added in v0.5.37

type CacheKeyHit struct {
	Key  string `json:"key"`
	Hits int64  `json:"hits"`
}

type CacheStatsSnapshot added in v0.5.37

type CacheStatsSnapshot struct {
	SinceUnixNano int64            `json:"sinceUnixNano"`
	Counts        map[string]int64 `json:"counts"`
	TopKeys       []CacheKeyHit    `json:"topKeys"`
	L1Size        int              `json:"l1Size"`
	L1Cap         int              `json:"l1Cap"`
}

CacheStatsSnapshot is the wire shape for the admin endpoint. Counts is a tier → hit count map; TopKeys is a sorted slice of the most-frequently-served keys (capped at 20).

type CorrelationAnchor added in v0.8.153

type CorrelationAnchor struct {
	Kind    CorrelationKind `json:"kind"`
	TraceID string          `json:"traceId,omitempty"`
	Service string          `json:"service,omitempty"`
	TsNs    int64           `json:"tsNs,omitempty"`
	FromNs  int64           `json:"fromNs"`
	ToNs    int64           `json:"toNs"`
	// JoinKey is the strongest join the bundle actually used:
	//   "trace_id"       — exact cross-signal join (no time fuzz)
	//   "exemplar"       — a real representative trace from the spanmetrics
	//                      rollup (or the slowest/erroring raw span): the
	//                      metric→trace pivot for latency/error anchors. Not the
	//                      literal data point, but exact-enough to pivot into.
	//   "service+window" — the genuinely-fuzzy fallback (throughput/count
	//                      metric, or no exemplar resolved): the operator must
	//                      see this.
	JoinKey string `json:"joinKey"`
}

CorrelationAnchor is what the operator pivoted FROM, echoed back so the drawer's anchor header + join-key chip can render which join is being trusted.

type CorrelationContext added in v0.8.153

type CorrelationContext struct {
	Anchor   CorrelationAnchor          `json:"anchor"`
	Trace    *CorrelationTrace          `json:"trace,omitempty"`
	Logs     []*logstore.LogRecord      `json:"logs"`               // always present (possibly empty)
	Metrics  []chstore.SpanMetricSeries `json:"metrics"`            // anchor service RED series (possibly empty)
	Exemplar *chstore.Exemplar          `json:"exemplar,omitempty"` // metric anchor: a REAL representative trace to pivot INTO (slow/error rollup exemplar, raw-span fallback)
}

CorrelationContext is the assembled pivot bundle. Every lens is best-effort: a lens with no data soft-fails to nil/empty, exactly like rootcause.go — a partial bundle still helps the operator.

type CorrelationKind added in v0.8.153

type CorrelationKind string

CorrelationKind is the pivot anchor's signal shape.

const (
	CorrelateTrace  CorrelationKind = "trace"
	CorrelateLog    CorrelationKind = "log"
	CorrelateMetric CorrelationKind = "metric"
)

type CorrelationTrace added in v0.8.153

type CorrelationTrace struct {
	TraceID     string   `json:"traceId"`
	RootName    string   `json:"rootName"`
	Service     string   `json:"service"`
	DurationMs  float64  `json:"durationMs"`
	SpanCount   int      `json:"spanCount"`
	Services    []string `json:"services"`
	ErrSpans    int      `json:"errSpans"`
	StartTimeNs int64    `json:"startTimeNs"`
	EndTimeNs   int64    `json:"endTimeNs"`
	// Spans is the raw span list (capped) so the drawer's extracted
	// ServiceTimeline sub-component renders the SAME per-service density bars
	// TracePeekDrawer does — no second derivation. Capped to keep the bundle
	// bounded for very large traces.
	Spans []chstore.SpanRow `json:"spans"`
}

CorrelationTrace is the condensed trace lens — enough for the service-timeline mini-waterfall + a header, without re-loading the full /trace page. Derived from the same GetTrace spans the /api/traces/{id} endpoint returns.

type FlowsResponse added in v0.5.103

type FlowsResponse struct {
	Flows []chstore.RootFlow `json:"flows"`
	From  int64              `json:"from"`
	To    int64              `json:"to"`
	// v0.7.39 — total distinct flows in the window (the list is capped at
	// ?top). >len(Flows) → the UI shows "showing N of M flows — raise top".
	TotalFlows int `json:"totalFlows,omitempty"`
}

FlowsResponse lists the top root-anchored business flows in a window. Each entry pairs a root signature with its trace count and the unique set of services those traces touched.

type GraphEdge added in v0.8.10

type GraphEdge struct {
	Source    string  `json:"source"`
	Target    string  `json:"target"`
	Calls     uint64  `json:"calls"`
	Errors    uint64  `json:"errors"`
	ErrorRate float64 `json:"errorRate"`
	Rate      float64 `json:"rate"` // calls per minute over the window (v0.8.x)
	AvgMs     float64 `json:"avgMs"`
	P99Ms     float64 `json:"p99Ms"`
	Protocol  string  `json:"protocol,omitempty"` // http | grpc | db | kafka — SpanKind proxy
}

GraphEdge is one directed caller→callee edge carrying RED metrics + protocol.

type GraphNode added in v0.8.10

type GraphNode struct {
	ID        string  `json:"id"`               // canonical id (the MV's raw name, e.g. "payments" or "db:h2")
	Name      string  `json:"name"`             // display name, prefix-decoded ("payments", "h2")
	Kind      string  `json:"kind"`             // service | database | queue | external | internal
	System    string  `json:"system,omitempty"` // db.system / messaging.system when applicable
	DbName    string  `json:"dbName,omitempty"` // db.name (schema/instance) — database nodes only
	Env       string  `json:"env,omitempty"`    // deployment.environment
	Calls     uint64  `json:"calls"`            // node throughput (inbound preferred, else outbound)
	Errors    uint64  `json:"errors"`
	ErrorRate float64 `json:"errorRate"` // (errors/calls)*100 — drives health color
	Rate      float64 `json:"rate"`      // calls per minute over the window — node-size encoding (v0.8.x)
}

GraphNode is one node in the OTel-native service map.

type InboxAnomalyRef added in v0.5.211

type InboxAnomalyRef struct {
	ID           string  `json:"id"`
	Kind         string  `json:"kind"` // "log_pattern" | "trace_op"
	Pattern      string  `json:"pattern"`
	PeakRatio    float64 `json:"peakRatio"`
	CurrentRatio float64 `json:"currentRatio"`
}

type InboxExceptionRef added in v0.5.211

type InboxExceptionRef struct {
	Fingerprint string `json:"fingerprint"`
	Type        string `json:"type"`
	Message     string `json:"message"`
	Occurrences uint64 `json:"occurrences"`
}

type InboxItem added in v0.5.211

type InboxItem struct {
	ID             string `json:"id"`       // composite: "<kind>:<nativeId>"
	Kind           string `json:"kind"`     // problem | exception | anomaly
	Source         string `json:"source"`   // human label: "Alert rule" / "Exception" / "Anomaly"
	Priority       string `json:"priority"` // P1 | P2 | P3
	PriorityReason string `json:"priorityReason"`
	Severity       string `json:"severity"` // critical | warning | info
	Service        string `json:"service"`
	Title          string `json:"title"` // rule name / exception type / pattern
	Description    string `json:"description"`
	StartedAt      int64  `json:"startedAt"` // unix ns
	LastSeen       int64  `json:"lastSeen"`  // unix ns; for problems == StartedAt
	Assignee       string `json:"assignee,omitempty"`
	// OwnerTeam + SRETeam attached server-side from
	// service_metadata so the inbox can render team chips
	// without each row firing a per-service lookup. Empty when
	// no catalog row exists for the service. OwnerTeam mirrors
	// what's auto-set on Problem.Assignee at open time;
	// surfacing it on every row (even exceptions / anomalies)
	// keeps the column meaningful across kinds.
	OwnerTeam string `json:"ownerTeam,omitempty"`
	SRETeam   string `json:"sreTeam,omitempty"`
	Status    string `json:"status"` // open | acknowledged | resolved (problems);
	// open | regressed (exceptions); active | cleared (anomalies)
	Clusters []string `json:"clusters,omitempty"`
	// Kind-specific drill-down hints. Only one is populated per
	// row. Keeps the JSON shape skinny — frontend reads exactly
	// the one matching `kind`.
	Problem   *InboxProblemRef   `json:"problem,omitempty"`
	Exception *InboxExceptionRef `json:"exception,omitempty"`
	Anomaly   *InboxAnomalyRef   `json:"anomaly,omitempty"`
}

InboxItem is the unified shape every triage-worthy thing (Problem / Exception group / Anomaly event) collapses into. Kind discriminates which source it came from; the kind- specific blob carries the bits needed to drill-down.

Designed so a single table on /inbox can show "everything needing a human" without operators tab-hopping between Problems / Exceptions / Anomalies pages — same priority blend, same age column, same assignee column. The per-source pages still exist as drill-down targets.

type InboxProblemRef added in v0.5.211

type InboxProblemRef struct {
	ID        string  `json:"id"`
	RuleID    string  `json:"ruleId"`
	Metric    string  `json:"metric"`
	Value     float64 `json:"value"`
	Threshold float64 `json:"threshold"`
}

type NoisyRuleWithSuggestion added in v0.5.131

type NoisyRuleWithSuggestion struct {
	chstore.NoisyRule
	Suggestion   string `json:"suggestion"`
	SuggestedFor uint32 `json:"suggestedForSec,omitempty"`
	SuggestedMin uint32 `json:"suggestedMinSamples,omitempty"`
	SuggestedCD  uint32 `json:"suggestedCooldownSec,omitempty"`
	CurrentFor   uint32 `json:"currentForSec"`
	CurrentMin   uint32 `json:"currentMinSamples"`
	CurrentCD    uint32 `json:"currentCooldownSec"`
}

NoisyRuleWithSuggestion enriches the raw NoisyRule with a heuristic suggestion string + structured deltas the UI can apply with one click via the existing AlertRule edit endpoint.

type RootCause added in v0.7.51

type RootCause struct {
	ProblemID    string                   `json:"problemId"`
	Service      string                   `json:"service"`
	Metric       string                   `json:"metric"`
	StartedAt    int64                    `json:"startedAt"`
	FromNs       int64                    `json:"fromNs"`
	ToNs         int64                    `json:"toNs"`
	RecentDeploy *chstore.RecentDeploy    `json:"recentDeploy,omitempty"`
	Correlations []chstore.ChangedService `json:"correlations"`
	BlastRadius  *chstore.BlastRadius     `json:"blastRadius,omitempty"`
	BubbleUp     *chstore.BubbleUpResult  `json:"bubbleUp,omitempty"`
	Exemplar     *chstore.Exemplar        `json:"exemplar,omitempty"`
}

RootCause is the assembled "what changed / likely cause" bundle for one Problem (v0.7.51). It orchestrates signals that already exist but were scattered — recent deploy, correlated service changes, dimension bubble-up, blast radius, an exemplar trace — into a single cached read so the Problem triage drawer shows one root-cause surface instead of the operator hopping across pages. Read-only.

type SchemaColumn

type SchemaColumn struct {
	Name string `json:"name"`
	Type string `json:"type"`
}

type SchemaTable

type SchemaTable struct {
	Table   string         `json:"table"`
	Engine  string         `json:"engine"`
	Columns []SchemaColumn `json:"columns"`
}

SchemaTable + SchemaColumn drive the playground's left-side browser. Operator clicks a column → it pastes into the editor at cursor; click a table → SELECT * FROM <table> LIMIT 100 gets generated. Both query system.tables / system.columns, pre-filtered to the current database. Results cached 60s.

type Server

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

func NewServer

func NewServer(addr string, ing *otlp.Ingester, store *chstore.Store, logs logstore.Store, webFS embed.FS, authSvc *auth.Service, oidcSvc *auth.OIDCService, ldapSvc *ldap.Service, c cache.Cache, n *notify.Notifier, cop *copilot.Service, bus *sse.Broker) *Server

func (*Server) EnableDemoMode

func (s *Server) EnableDemoMode(email, password string)

EnableDemoMode wires the demo credentials returned by /api/auth/config. Loud no-op when called with empty credentials so a misconfigured demo flag doesn't silently expose nothing.

func (*Server) SetAutocomplete added in v0.8.80

func (s *Server) SetAutocomplete(a *acache.Store)

SetAutocomplete wires the Redis autocomplete cache (v0.8.80). Called once from main() after the api.Server is constructed. nil-safe — the picker handlers fall back to ClickHouse when it's absent or cold.

func (*Server) SetBackgroundConfig added in v0.4.95

func (s *Server) SetBackgroundConfig(b config.BackgroundConfig)

SetBackgroundConfig wires the cadence/timeout knobs to the Server. Called once from main() after Load() so the status probe respects the configured ceiling.

func (*Server) SetCluster added in v0.5.253

func (s *Server) SetCluster(c *cluster.Service)

SetCluster wires the per-pod heartbeat / membership service (v0.5.253). Always called from main() — the service degenerates to a single-pod view when Redis isn't configured so handlers don't need to nil-check before calling Members.

func (*Server) SetLdapGroupSync added in v0.8.526

func (s *Server) SetLdapGroupSync(e *ldap.SyncEngine)

SetLdapGroupSync wires the LDAP group-sync engine (v0.8.526).

func (*Server) SetLockDegraded added in v0.8.212

func (s *Server) SetLockDegraded(b bool)

SetLockDegraded records that the distributed leader lock fell back to the always-leader Noop despite Redis being configured (Redis down at boot) — so /admin/stats can warn that multi-pod background jobs are duplicated. v0.8.212. Called with false by the Redis re-probe (v0.8.341) once the real lock is swapped back in — the /admin/stats warning clears without a pod restart.

func (*Server) SetLogstoreESManager added in v0.8.232

func (s *Server) SetLogstoreESManager(m *logstore.ESManager)

SetLogstoreESManager wires the UI-managed logstore config owner (v0.8.232). main() constructs the manager alongside the Switchable logstore; the Settings → Elasticsearch handlers are 503 no-ops without it (partial init / tests).

func (*Server) SetMCP added in v0.6.4

func (s *Server) SetMCP(m *mcp.Server)

SetMCP wires the Model Context Protocol server (v0.6.4). Called once from main() after the api.Server is constructed. nil is valid — leaves the /api/mcp/* routes unregistered.

func (*Server) SetPipeline added in v0.5.263

func (s *Server) SetPipeline(p *pipeline.Engine)

SetPipeline wires the engine. Always called from main(); the admin handlers nil-check so a misconfigured boot doesn't 500 every request — they return 503 with a clear reason.

func (*Server) SetRAG added in v0.8.441

func (s *Server) SetRAG(r *rag.Service)

SetRAG bağlar (v0.8.438) — cluster.Set deseninde opsiyonel bağımlılık.

func (*Server) SetRoles added in v0.8.346

func (s *Server) SetRoles(ingest, apiRole bool)

SetRoles wires the pod's runtime role split into the HTTP surface (v0.8.346, HA audit H6). main.go's old comment claimed "api.NewServer handles the role guard internally" — no such code existed: every role registered POST /v1/* while only ingest pods Start() the consumers, so a collector pointed at an api-role pod had its Exports 200-OK'd into channels NOBODY DRAINED (silent black hole; queue gauges even looked healthy at a constant 100%). Defaults (unset) = all roles on, which keeps monolithic mode and test-constructed Servers byte-identical.

func (*Server) SetTempo added in v0.5.208

func (s *Server) SetTempo(t *tempo.Service)

SetTempo wires the external Tempo client. Always called from main() with a non-nil service — Configured() reports whether the operator has actually filled in the settings.

func (*Server) SetThanos added in v0.8.576

func (s *Server) SetThanos(t *thanos.Service)

SetThanos wires the multi-cluster Thanos Querier client (v0.8.576). Always called from main() with a non-nil service — HasEnabledClusters() reports whether the operator configured any cluster.

func (*Server) SetVersion

func (s *Server) SetVersion(v string)

SetVersion records the build-time tag. Called once from main(); safe to call before Start() since /api/version is only consulted by SPA after the server is listening.

func (*Server) Shutdown added in v0.8.336

func (s *Server) Shutdown(ctx context.Context) error

Shutdown drains the HTTP server (v0.8.336, HA audit H1): stops accepting new connections, lets in-flight requests finish within ctx's deadline. Safe before Start() (nil server = no-op).

func (*Server) Start

func (s *Server) Start() error

func (*Server) StartAuditDrainer added in v0.5.339

func (s *Server) StartAuditDrainer(ctx context.Context)

StartAuditDrainer runs the batched audit-write loop until ctx is cancelled. Triggers a flush when either the channel hits 64 pending entries or the 200ms tick elapses — whichever comes first. Errors are logged but don't tear down the drainer; the next tick reattempts.

func (*Server) StartCacheInvalidation added in v0.5.337

func (s *Server) StartCacheInvalidation(ctx context.Context)

StartCacheInvalidation subscribes to the invalidation channel and drains incoming messages into l1.del. Runs once per Server; the subscription lifetime is bound to the server's lifetime context. When Subscribe returns an error (Redis down, or pub/sub unsupported), we log and exit — the soft TTL keeps the L1 tier from growing stale unbounded, just for longer.

Called from main.go alongside the other StartConfigRefresh loops, exported because the constructor doesn't take a ctx.

func (*Server) StartRAGSync added in v0.8.442

func (s *Server) StartRAGSync(ctx context.Context, lock cache.Lock)

StartRAGSync — 30 dk'lık leader-gated arka plan senkronu (deriver deseni). api rolündeki pod'larda main.go'dan başlatılır.

type ServiceGraphResponse added in v0.8.10

type ServiceGraphResponse struct {
	Nodes []GraphNode `json:"nodes"`
	Edges []GraphEdge `json:"edges"`
	Scope string      `json:"scope"`
	Focus string      `json:"focus,omitempty"`
	// TotalNodes / ShownNodes (v0.8.295, re-land of v0.8.277) — set by
	// pruneServiceGraphTopN. When the global render budget trims a large
	// graph, ShownNodes < TotalNodes and the UI can show "showing X of Y
	// services" (same contract as the v0.8.215 cap on sampled
	// /api/service-map).
	TotalNodes int `json:"totalNodes"`
	ShownNodes int `json:"shownNodes"`
}

ServiceGraphResponse is the compact payload the canonical renderer consumes.

type ServiceTopologyNode added in v0.5.102

type ServiceTopologyNode struct {
	ID   string `json:"id"`   // canonical id used by edges (service name OR "db:postgresql")
	Name string `json:"name"` // display label, sans prefix for infra ("postgresql" not "db:postgresql")
	Kind string `json:"kind"` // "service" | "db" | "queue" | "external"
	// v0.5.312 — Phase 2 enrichment for the topology redux:
	// soft-cluster the diagram by k8s.namespace / service.namespace
	// and paint each node with a health badge from open-problems
	// count. Both are read-time-enriched (no schema change), nil-
	// safe (omitempty), so older frontends keep working.
	Namespace    string `json:"namespace,omitempty"`
	Health       string `json:"health,omitempty"`       // "" | "green" | "yellow" | "red"
	HealthReason string `json:"healthReason,omitempty"` // short "2 open criticals" etc.
	OpenCritical int    `json:"openCritical,omitempty"`
	OpenWarning  int    `json:"openWarning,omitempty"`
	// v0.5.409 — known 3rd-party SaaS / cloud annotation for
	// external nodes. Populated from the edge's ExtDisplay /
	// ExtKind (set by external_catalogue lookup). UI renders a
	// human-readable display name + category badge instead of
	// the raw `ext:api.stripe.com` hostname.
	ExtDisplay string `json:"extDisplay,omitempty"`
	ExtKind    string `json:"extKind,omitempty"`
	// v0.5.410 — display-only environment annotation
	// (deployment.environment / service.namespace /
	// k8s.namespace.name). Populated from the edge that
	// brought this node into the graph. UI surfaces it as a
	// small chip ("prod" / "stage") next to the service name
	// so multi-env installs distinguish at-a-glance.
	Env string `json:"env,omitempty"`
	// v0.7.32 — for a collapsed broadcast queue node, the real number of
	// distinct consumer services its fan-out was hidden behind. The renderer
	// shows "→ N services (broadcast)" on the node instead of N edges. Only set
	// on queue nodes whose consumer count exceeded the broadcast threshold.
	BroadcastFanout int `json:"broadcastFanout,omitempty"`
}

ServiceTopologyNode is one node in the service-level graph. Kind distinguishes a real service from synthetic infra nodes (db, queue, cache, external) so the renderer can paint them differently without per-node lookup.

type ServiceTopologyResponse added in v0.5.102

type ServiceTopologyResponse struct {
	Nodes     []ServiceTopologyNode         `json:"nodes"`
	Edges     []chstore.ServiceTopologyEdge `json:"edges"`
	From      int64                         `json:"from"`
	To        int64                         `json:"to"`
	Truncated bool                          `json:"truncated"`
	// v0.6.48 — server-side scoping for thousand-service fabrics.
	// TotalServices is the distinct service count BEFORE the top-N /
	// focus bound was applied, so the UI can show "showing N of M
	// services — search or focus to refine". Scoped is true when the
	// returned graph is a bounded subset (top-N by call volume, or a
	// focus neighbourhood) rather than the full fabric.
	TotalServices int    `json:"totalServices"`
	Scoped        bool   `json:"scoped"`
	ScopeReason   string `json:"scopeReason,omitempty"` // "top-50 by call volume" | "focus: <svc> +2 hops"
	// v0.7.32 — number of broadcast queue topics whose consumer fan-out was
	// collapsed (a topic with >threshold distinct consumers, e.g. a kafka
	// cache-refresh broadcast). The UI shows a "N broadcast topics collapsed —
	// show" affordance that flips ?broadcast=show. 0 when none / ?broadcast=show.
	BroadcastCollapsed int `json:"broadcastCollapsed,omitempty"`
}

ServiceTopologyResponse is the JSON shape served by /api/topology/service — flat node + edge lists matching the chstore ServiceTopologyEdge model. Includes the time window so the UI can render the active window and a draw.io export can embed it in the filename.

type SpanMetricServiceRow added in v0.5.350

type SpanMetricServiceRow struct {
	Service   string  `json:"service"`
	Calls     uint64  `json:"calls"`
	Errors    uint64  `json:"errors"`
	ErrorRate float64 `json:"errorRate"`
	AvgMs     float64 `json:"avgMs,omitempty"`
	MaxMs     float64 `json:"maxMs,omitempty"`
	P50Ms     float64 `json:"p50Ms,omitempty"`
	P99Ms     float64 `json:"p99Ms,omitempty"`
	// Inline call-rate sparkline — 30 buckets evenly spread
	// across the requested window. Float so a SVG renderer can
	// scale by max() without integer truncation; counts are
	// integers in the source data but we already pay the
	// float math in the aggregation step.
	Sparkline []float64 `json:"sparkline,omitempty"`
	// Source metric names this row aggregated — surfaced to
	// the UI so the operator can confirm which spanmetrics
	// processor variant their collector is emitting.
	CallsMetric    string `json:"callsMetric,omitempty"`
	DurationMetric string `json:"durationMetric,omitempty"`
}

SpanMetricServiceRow is one row of the span-metric-derived service overview — call volume + error fraction in the window, optionally augmented with histogram-derived latency once we wire that. Returned by /api/spanmetrics/services.

type TopologyNode added in v0.5.100

type TopologyNode struct {
	ID      string `json:"id"`
	Service string `json:"service"`
	Op      string `json:"op"`
}

TopologyNode is a service.operation node in the response. The frontend keys nodes by `id` (service|op) so render-time edge lookups stay O(1).

type TopologyResponse added in v0.5.100

type TopologyResponse struct {
	Nodes       []TopologyNode         `json:"nodes"`
	Edges       []chstore.TopologyEdge `json:"edges"`
	RootService string                 `json:"rootService"`
	Depth       int                    `json:"depth"`
	From        int64                  `json:"from"` // unix ns
	To          int64                  `json:"to"`
	Truncated   bool                   `json:"truncated"`
}

TopologyResponse is the JSON shape served by /api/topology. Truncated is true when the underlying edge query hit the LIMIT — the UI shows a banner so the operator knows the view is partial.

Jump to

Keyboard shortcuts

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