Help us shape the future of Go! Take the 2026 Go Developer Survey

obsdash

package
v1.0.14 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package obsdash turns a forge project's own service metadata into observability dashboards.

The package has two layers, and the split is the point:

  • Spec (this file) is a backend-neutral description of WHAT to show: dashboards made of panels, each panel a query intent (signal, aggregate, predicates on OpenTelemetry attribute names). It names no ClickHouse column, no HyperDX field and no chart library. Build derives it from the project's services, rpcs, frontends and database. It is also serialized (deploy/observability/spec/, one file for the project and one per service — see ProcessPart) so a second renderer — the Reliant console, drawing with uPlot — can consume exactly the same model, through the release bundle, without parsing HyperDX JSON. The panel vocabulary and its validator are published as pkg/dashspec (aliased in dashspec.go), so every reader of a dashboard file judges it by the same rules.

  • RenderHyperDX (hyperdx.go) is one renderer over the Spec: it emits HyperDX v2 dashboard JSON for the file provisioner (local dev, operators) or for the HyperDX API (hosted).

Everything is keyed on OpenTelemetry names (service.name, deployment.environment.name, span.name, ...), the contract forge's runtime and KCL already settle, so no panel depends on how a given backend stores them.

Index

Constants

View Source
const (
	SeverityCritical = "critical"
	SeverityWarning  = "warning"
	SeverityInfo     = "info"
)

Alert severities, the values of the `severity` label.

View Source
const (
	PlatformDeployFailed = "deploy-failed"
	PlatformQuota        = "observability-quota"
	// The issue alerts need the issue registry (new / regressed are state
	// transitions, and a spike is measured per issue), which the control plane
	// owns. They cover every issue the env has, browser or server.
	PlatformNewIssue       = "new-issue"
	PlatformIssueRegressed = "issue-regressed"
	PlatformIssueSpike     = "issue-spike"
	// PlatformReleaseRegressed fires when a promotion's after-window closes
	// and the release-health verdict is FAIL: the env's release_health.fail_on
	// findings, evaluated by the control plane with the same rule as
	// `forge obs check`. It stays silent on PASS and on INCONCLUSIVE.
	PlatformReleaseRegressed = "release-regressed"
	// PlatformServiceAnomaly fires when a service's request rate, error rate
	// or p95 leaves its seasonal baseline: the same hour of the week over the
	// previous 4 weeks (obsquery.EvalAnomalies, over the rpc.server.* metrics,
	// never spans). The control plane evaluates it; its limits (4 MADs, 50
	// requests, a 1 point error-rate rise or a 1.5x p95 rise, 7 days of
	// history) are obsquery.DefaultAnomalyParams, not tunable params. The
	// alert is one per service and release (labels: service, env, release,
	// dedupe_key), with every signal that moved a finding in its why payload,
	// so a summary can quote no signal label.
	PlatformServiceAnomaly = "service-anomaly"
)

Platform default ids: alerts the control plane raises from events it owns (a failed convergence, a quota state). They are tunable in forge.Alerts.defaults like any other id, and recorded in the shape's platform_alerts.

View Source
const (
	GroupOverview       = dashspec.GroupOverview
	GroupServices       = dashspec.GroupServices
	GroupJobs           = dashspec.GroupJobs
	GroupProduct        = dashspec.GroupProduct
	GroupPlatform       = dashspec.GroupPlatform
	GroupReleases       = dashspec.GroupReleases
	GroupCustom         = dashspec.GroupCustom
	Traces              = dashspec.Traces
	Metrics             = dashspec.Metrics
	Logs                = dashspec.Logs
	KindNumber          = dashspec.KindNumber
	KindLine            = dashspec.KindLine
	KindTable           = dashspec.KindTable
	KindSearch          = dashspec.KindSearch
	KindBar             = dashspec.KindBar
	KindHeatmap         = dashspec.KindHeatmap
	KindSQL             = dashspec.KindSQL
	KindIssues          = dashspec.KindIssues
	KindSessions        = dashspec.KindSessions
	KindFunnel          = dashspec.KindFunnel
	KindText            = dashspec.KindText
	FunnelBySession     = dashspec.FunnelBySession
	FunnelByUser        = dashspec.FunnelByUser
	DefaultFunnelWindow = dashspec.DefaultFunnelWindow
	DefaultFunnelBy     = dashspec.DefaultFunnelBy
	AggCount            = dashspec.AggCount
	AggCountDistinct    = dashspec.AggCountDistinct
	AggSum              = dashspec.AggSum
	AggAvg              = dashspec.AggAvg
	AggMax              = dashspec.AggMax
	AggQuantile         = dashspec.AggQuantile
	AggLast             = dashspec.AggLast
	AggRate             = dashspec.AggRate
	AggIncrease         = dashspec.AggIncrease
	AggMin              = dashspec.AggMin
	UnitNone            = dashspec.UnitNone
	UnitCount           = dashspec.UnitCount
	UnitMillis          = dashspec.UnitMillis
	UnitBytes           = dashspec.UnitBytes
	UnitPercent         = dashspec.UnitPercent
	UnitSeconds         = dashspec.UnitSeconds
	OpEq                = dashspec.OpEq
	OpNeq               = dashspec.OpNeq
	OpIn                = dashspec.OpIn
	OpNotIn             = dashspec.OpNotIn
	OpPrefix            = dashspec.OpPrefix
	OpMatch             = dashspec.OpMatch
	OpExists            = dashspec.OpExists
	OpGTE               = dashspec.OpGTE
	FieldService        = dashspec.FieldService
	FieldEnv            = dashspec.FieldEnv
	AnnotationReleases  = dashspec.AnnotationReleases
	SpecVersion         = dashspec.SpecVersion
)

The spec constants, from pkg/dashspec.

View Source
const (
	// DashboardsDir is the project-relative directory mounted as HyperDX's
	// DASHBOARD_PROVISIONER_DIR.
	DashboardsDir = "deploy/observability/dashboards"
	// SpecDir holds the serialized Spec, the renderer-neutral model, as its
	// parts: ProjectSpecFile and one ProcessSpecFile per service (see
	// ProcessPart for why it is not one file). It sits beside the dashboards
	// directory, not in it, because the provisioner reads every *.json it
	// finds there. ReadSpec assembles it.
	SpecDir = "deploy/observability/spec"
	// ProjectSpecFile is the project's ProjectPart.
	ProjectSpecFile = SpecDir + "/project" + genSuffix

	// LegacySpecFile is the whole-project spec the parts replace. Write
	// retires it when pristine, as it does the whole-project
	// saved-searches_gen.ndjson, an unwritten *_gen.ndjson like any other.
	LegacySpecFile = "deploy/observability/dashboard-spec_gen.json"
)
View Source
const (
	SourceLogs    = "Logs"
	SourceTraces  = "Traces"
	SourceMetrics = "Metrics"
)

Source names. The ClickStack local image pre-creates exactly these three sources (and Sessions); a tile names one of them in `config.source`.

The provisioner stores `source` verbatim, but the HyperDX UI resolves a tile's source by mongo id, and ids are random per database. So a rendered dashboard carries NAMES, and whatever delivers it resolves them: the local compose entrypoint rewrites names to ids before it provisions, and a hosted deliverer does the same through GET /api/v2/sources. Keeping names in the file keeps it identical across every database.

View Source
const (
	KindServiceProc  = "service"
	KindWorkerProc   = "worker"
	KindOperatorProc = "operator"
	KindJobProc      = "job"
	KindCronProc     = "cron"
)

Kinds a Process can have (the forge workload kinds that run something).

View Source
const AlertDefaultsFile = "deploy/observability/alert-defaults_gen.json"

AlertDefaultsFile is the project-relative file `forge generate` writes: the project metadata the default alert rules are derived from, plus the catalog of defaults with their tunable parameters. The per-service metadata is in each alertServicePart. `forge env shape` reads both back (ReadAlertInput) to resolve the defaults for one env (the SQL names the env, so a default is rendered per env, not once per project). It sits beside the dashboard spec, not in the dashboards directory the HyperDX provisioner scans.

View Source
const AlertDefaultsVersion = "forge.alert-defaults/v3"

AlertDefaultsVersion identifies the serialized shape of AlertDefaultsFile. v2 dropped input.services: each service's entry is its alertServicePart's Alert (see alertServicePart for why), and ReadAlertInput puts them back.

View Source
const CustomMetricsID = "custom-metrics"

CustomMetricsID is the id of the dashboard BuildCustomMetrics returns, so its file is "<project>-custom-metrics_gen.json".

View Source
const EnvIDPlaceholder = "{reliant_env_id:String}"

EnvIDPlaceholder stands for the env's id in a rule whose data is stamped with the id rather than the env's name: customer metadata, which the node agent labels from the namespace. The env id is not known when forge renders, so the SQL carries this token and whoever evaluates the rule binds it (BindEnvID here, for `forge obs alerts check`; the control plane for a deployed env).

View Source
const JobsID = "jobs"

JobsID is the id of the one dashboard every job and cron job shares, so its file is "<project>-jobs_gen.json".

View Source
const PartsVersion = "forge.dashboard-parts/v2"

PartsVersion identifies the shape of the files the Spec is written to disk as (ProjectPart, ProcessPart).

View Source
const PinnedHyperDX = "2.40.0"

PinnedHyperDX is the HyperDX / ClickStack version the rendered JSON is written and validated against. The provisioned-dashboard schema (DashboardWithoutIdSchema in @hyperdx/common-utils) is not a versioned public contract, so a bump of the ClickStack image is a bump of this constant AND a re-run of the schema gate (see hyperdx_schema_test.go).

View Source
const ReleasesID = "releases"

ReleasesID is the id of the dashboard BuildReleases returns, so its file is "<project>-releases_gen.json".

View Source
const WorkloadsID = "workloads"

WorkloadsID is the id of the dashboard BuildWorkloads returns, so its file is "<project>-workloads_gen.json".

Variables

This section is empty.

Functions

func AlertDefaultAlertNames

func AlertDefaultAlertNames() []string

AlertDefaultAlertNames are the rule names the defaults take: a user rule may not reuse one.

func AlertDefaultIDs

func AlertDefaultIDs() []string

AlertDefaultIDs are the ids a forge.Alerts.defaults map may tune.

func BindEnvID

func BindEnvID(expr, envID string) string

BindEnvID replaces EnvIDPlaceholder with envID as a quoted literal.

func BuildParts added in v0.1.46

func BuildParts(in Input) (ProjectPart, []ProcessPart)

BuildParts derives the project's Spec as process parts, sorted by process identity. RPC-free workers and gateways retain their runtime/workload panels.

func DashboardFile

func DashboardFile(project string, d Dashboard) string

DashboardFile is the file name of d inside the dashboards directory.

func DashboardName

func DashboardName(d Dashboard) string

DashboardName is the HyperDX dashboard name for d: the provisioner upserts by name, so it must be stable and unique across the project.

func IsBuiltinMetric

func IsBuiltinMetric(name string) bool

IsBuiltinMetric reports whether name is one of forge's own metrics (rpc.*, go.*, forge.*, a component's .calls/.errors/.duration). Those have purpose-built dashboards; the custom-metrics dashboard is for the rest.

func IsConsoleKind added in v0.1.46

func IsConsoleKind(k PanelKind) bool

IsConsoleKind is dashspec.IsConsoleKind.

func IsPlatformExpr

func IsPlatformExpr(expr string) bool

IsPlatformExpr reports whether expr is a recorded platform default.

func LooksLikeHyperDXDashboard

func LooksLikeHyperDXDashboard(raw []byte) bool

LooksLikeHyperDXDashboard is dashspec.LooksLikeHyperDXDashboard.

func LooksLikeSpecDashboard

func LooksLikeSpecDashboard(raw []byte) bool

LooksLikeSpecDashboard is dashspec.LooksLikeSpecDashboard.

func MarshalAlertDefaults

func MarshalAlertDefaults(in AlertInput) ([]byte, error)

MarshalAlertDefaults is the file's bytes: the catalog for in, with the services left to their alertServiceParts.

func OverridePath

func OverridePath(project string, d Dashboard) string

OverridePath is the file that, when present, replaces the generated dashboard d: forge neither writes nor refreshes its _gen twin. The file is the project's, and forge never touches it.

func PlatformExpr

func PlatformExpr(key string, off bool) string

PlatformExpr is the expr a platform default is recorded under; key is "<id>" or "<id>:<level>". It is a real SELECT that returns no row, so a ClickHouse evaluator that does not know the marker finds nothing and never fires; the control plane recognizes the comment, binds the env id and evaluates the event itself. `off` records that the env disabled the default.

func ProcessDashboardID added in v1.0.9

func ProcessDashboardID(name string) string

ProcessDashboardID is the dashboard id of the process named name.

func ProcessSpecFile added in v1.0.0

func ProcessSpecFile(service string) string

ProcessSpecFile is the project-relative file of service's ProcessPart.

func ResolveAlertDefaultsFor

func ResolveAlertDefaultsFor(in AlertInput, env string, tuning map[string]AlertTuning, disabled []string) ([]AlertRule, []AlertSkip, error)

ResolveAlertDefaultsFor is ResolveAlertDefaults for an env that opted out of the observability categories in disabled. A default that reads a disabled category's data has nothing to read, so it is left out and reported as skipped, not recorded as a rule that can only ever be empty.

A platform default (deploy-failed, observability-quota) is always recorded, because the control plane raises it from its own events: enabled, it is an entry carrying the env's `for` and labels; disabled, an entry marked off.

func SavedSearchesFile

func SavedSearchesFile(project, service string) string

SavedSearchesFile is the project-relative file holding service's HyperDX saved searches, one JSON object per line, named like the service's dashboard. It lives in the dashboards directory (the one directory compose mounts) under an extension the dashboard provisioner ignores; the compose entrypoint upserts every *_gen.ndjson there, because the file provisioner has no saved-search path. One file per service, for the reason in ProcessPart.

func ValidateAlertTuning

func ValidateAlertTuning(tuning map[string]AlertTuning) error

ValidateAlertTuning refuses a tuning that names an unknown default or an unknown parameter of one, so a typo is an error at render, not a default that silently keeps its old threshold.

func Write

func Write(projectDir string, in Input, cs *checksums.FileChecksums) ([]string, error)

Write generates the project's dashboards under projectDir through the checksummed writer (a hand-edited generated file is left alone, exactly like every other Tier-1 output). It returns the project-relative paths written or kept.

Types

type Agg

type Agg = dashspec.Agg

Agg is dashspec.Agg.

type AlertDefaultInfo

type AlertDefaultInfo struct {
	ID       string `json:"id"`
	Alert    string `json:"alert"`
	Title    string `json:"title"`
	Severity string `json:"severity"`
	For      string `json:"for"`
	Interval string `json:"interval"`
	// Signal is where the default reads: metrics, traces, metadata (the node
	// agent's customer metadata) or platform (the control plane's own events).
	Signal string `json:"signal"`
	// Requires names the observability category whose opt-out leaves the
	// default nothing to read ("metadata"). Empty = always applicable.
	Requires string `json:"requires,omitempty"`
	// AlertNames are further rule names the default also takes, beyond Alert.
	AlertNames []string     `json:"alert_names,omitempty"`
	Params     []AlertParam `json:"params"`
}

AlertDefaultInfo is a default as the generated file records it.

type AlertDefaultsDoc

type AlertDefaultsDoc struct {
	Version  string             `json:"version"`
	Input    AlertInput         `json:"input"`
	Defaults []AlertDefaultInfo `json:"defaults"`
}

AlertDefaultsDoc is the serialized AlertDefaultsFile.

func AlertDefaults

func AlertDefaults(in AlertInput) AlertDefaultsDoc

AlertDefaults is the catalog for the generated file: every default the input applies to, at its default parameters.

type AlertInput

type AlertInput struct {
	Project string `json:"project"`
	// Services are the project's services that have at least one rpc. The
	// generated file leaves them out (each is in its alertServicePart).
	Services []AlertService `json:"services,omitempty"`
	// FrontendServices are the service.names the project's web frontends'
	// browser SDK reports (naming.FrontendServiceName: "<project>-<frontend>",
	// what each otel_gen.ts bakes as SERVICE_NAME), empty when the project has
	// no web frontend. The frontend defaults fire per service.name.
	FrontendServices []string `json:"frontend_services,omitempty"`
	// UptimeChecks are the names of the env's uptime checks (the release
	// shape's uptime_checks). They are a fact about one env, not the project,
	// so the generated file never records them: the resolver sets them per
	// env. The uptime defaults apply only to an env that has checks, and read
	// only those checks' series, so a check an env opts out of cannot alert.
	UptimeChecks []string `json:"-"`
}

AlertInput is what the defaults are derived from.

func AlertInputOf

func AlertInputOf(in Input) AlertInput

AlertInputOf derives the defaults' input from the same Input the dashboards are built from, so the two can never disagree about what a project has.

func ParseAlertDefaults

func ParseAlertDefaults(b []byte) (AlertInput, error)

ParseAlertDefaults reads the generated file: the input without its services (ReadAlertInput adds them).

func ReadAlertInput added in v0.1.46

func ReadAlertInput(projectDir string) (in AlertInput, ok bool, err error)

ReadAlertInput reads the alert defaults' input forge generate last wrote under projectDir: AlertDefaultsFile, with each alertServicePart's Alert as its services. ok is false when there is no AlertDefaultsFile — a project that has not run `forge generate` since alerting landed has no defaults, which is not an error.

type AlertParam

type AlertParam struct {
	Name    string  `json:"name"`
	Default float64 `json:"default"`
	Doc     string  `json:"doc"`
}

AlertParam is one numeric knob of a default's query.

type AlertRule

type AlertRule struct {
	ID          string
	Alert       string
	Expr        string
	For         string
	Interval    string
	Labels      map[string]string
	Annotations map[string]string
}

AlertRule is one resolved default: a rule ready for an env's shape.

func ResolveAlertDefaults

func ResolveAlertDefaults(in AlertInput, env string, tuning map[string]AlertTuning) ([]AlertRule, error)

ResolveAlertDefaults renders the defaults for one env, with the env's tuning applied. A default the env disables is left out. Rules come back sorted by alert name.

type AlertService

type AlertService struct {
	Name       string `json:"name"`
	RPCService string `json:"rpc_service"`
}

AlertService is one Connect service the defaults watch. RPCService is the procedure prefix the RPC interceptors label metrics with: "<package>.<ProtoService>", the second segment of "/orders.v1.OrdersService/GetOrder".

type AlertSkip

type AlertSkip struct{ ID, Reason string }

AlertSkip is a default left out of an env's rules, and why.

type AlertTuning

type AlertTuning struct {
	Enabled bool
	Labels  map[string]string
	For     string
	Params  map[string]float64
}

AlertTuning is how an env adjusts one default (forge.AlertDefault).

type Annotation

type Annotation = dashspec.Annotation

Annotation is dashspec.Annotation.

type AnnotationSource

type AnnotationSource = dashspec.AnnotationSource

AnnotationSource is dashspec.AnnotationSource.

type BundleDashboard

type BundleDashboard struct {
	// Name is the file name without ".json", and without "_gen" for a
	// generated one: the key a project file overrides by.
	Name   string
	Source BundleDashboardSource
	// Path is the file's path inside the bundle.
	Path string
	// Dashboard is the parsed content; Data is the exact bytes shipped.
	Dashboard Dashboard
	Data      []byte
}

BundleDashboard is one file of the bundle's observability/dashboards/.

type BundleDashboardSource

type BundleDashboardSource string

BundleDashboardSource says who authored a bundled dashboard.

const (
	SourceGenerated BundleDashboardSource = "gen"
	SourceUser      BundleDashboardSource = "user"
)

The sources of a bundled dashboard.

type BundleFile

type BundleFile struct {
	Path string
	Data []byte
}

BundleFile is a path and its bytes.

func BundleFiles

func BundleFiles(s BundleSet) []BundleFile

BundleFiles returns the set as bundle files, in path order.

type BundleSet

type BundleSet struct {
	Dashboards []BundleDashboard
	// MetricsSchema is the raw forge.metrics/v1 document, or nil.
	MetricsSchema []byte
	// Notes are things worth telling the person cutting the release (a
	// HyperDX-only file that was not shipped).
	Notes []string
}

BundleSet is everything the bundle carries under observability/.

func CollectBundleSet

func CollectBundleSet(in BundleSetInput) (BundleSet, error)

CollectBundleSet assembles and validates the observability files of a bundle. It returns nothing for a project that has neither generated dashboards nor a metrics schema, and an error (a *ProblemsError for a bad dashboard file) when a file the project owns is not a valid dashboard.

type BundleSetInput

type BundleSetInput struct {
	// ProjectDir is the project root; the project's name is the one
	// dashboard-spec_gen.json records.
	ProjectDir string
	// MetricsSchema is the raw metrics schema the build produced, or nil.
	MetricsSchema []byte
	// Resolved is the selected environment's pure assembly. Non-nil replaces
	// disk generated dashboards, including stale process parts; owned overrides
	// still apply through the same stable filename/ID path.
	Resolved *Spec
}

BundleSetInput is what CollectBundleSet reads.

type Dashboard

type Dashboard = dashspec.Dashboard

Dashboard is dashspec.Dashboard.

func BuildCustomMetrics

func BuildCustomMetrics(project string, schema metrics.Schema) (Dashboard, bool)

BuildCustomMetrics turns a metrics schema into the "Custom metrics" dashboard: one section per project-declared metric, drawn by its type.

counter        a rate, per second
updowncounter  the current value (last)
gauge          the current value (last)
histogram      p50, p95 and p99

A metric with enumerated attribute values is grouped by each such attribute (one panel per attribute) — the closed set is what makes a group-by safe, since the series count is bounded by the declaration. Attributes without an enumerated set are offered as dashboard filters, not group-bys, so a high-cardinality key never fans a panel out into hundreds of lines.

Deprecated metrics are omitted. It returns false when the schema declares nothing of the project's own.

func BuildJobs added in v1.0.9

func BuildJobs(project string, jobs []Process) Dashboard

BuildJobs is the "Jobs" dashboard: every job and cron job of the project in one place, instead of one dashboard per job that is empty between runs.

A run is read from the Job controller's Kubernetes events, so it needs the cluster collector and a deployed environment; a local forge env up draws it empty. A JOB is a forge process (obsdash.Process): the workloads that run one command, which an environment may name differently.

EVERY panel is a SQL panel that selects through jobResolverSQL. That is not a style choice. The console hands the dashboard's service selector to every declarative panel as ServiceName IN (...) and a panel cannot opt out. The telemetry a job leaves carries three different names (metrics the workload, logs the service.name, events the Job object's), so a declarative panel selects a different subset than its neighbours, or nothing. A SQL panel receives the selection only through the resolver, which turns it into jobs and then filters each source by the identity that source carries.

jobs must be non-empty; Build only calls it when the project has some.

func BuildReleases

func BuildReleases(project string) Dashboard

BuildReleases is the "Releases" dashboard: how each release behaved, side by side. Every panel splits one signal by service.version, so the version that replaced another is a new line next to it and a regression is the line that departs at the cut-over. The Reliant console draws the deploy markers on these charts (and on every other time-series chart) from the dashboard's releases annotation, which is declared on all of them by Build.

The comparison table is the before/after view: one row per version over the selected time range, so choosing a range that spans a deploy puts the old and the new version in adjacent rows.

func BuildWorkloads

func BuildWorkloads(project string) Dashboard

BuildWorkloads is the "Workloads" dashboard: what the platform knows about every workload without the workload instrumenting anything. CPU and memory against what the container requested and may use, restarts and why the container last exited, the image versions that ran, and the Kubernetes events (crash loops, failed pulls, evictions).

It reads node-derived telemetry, which only a deployed environment has: a `forge env up` stack draws these panels empty. The owning org and environment are stamped from namespace labels, never from the payload, so a workload cannot spoof what these panels show.

Every panel is a line, number or search panel: a table over metrics is not something the console's query engine runs, so the per-container images and versions table is the console's workload view, and the version history is drawn here as CPU by image tag.

func ParseDashboard

func ParseDashboard(name string, raw []byte) (Dashboard, error)

ParseDashboard is dashspec.ParseDashboard.

type Filter

type Filter = dashspec.Filter

Filter is dashspec.Filter.

type Fragments added in v1.0.0

type Fragments struct {
	Frontends        []string
	FrontendServices []string `json:",omitempty"`
	HasDatabase      bool
	Funnels          []FrontendFunnel
}

Fragments holds only project-wide generation inputs. Per-service alert inputs live in separate parts, and dashboard RPC ownership comes from the rendered workloads (Process.RPCServices). Duplicating the service inventory here would make independent service additions change the same shared JSON; the merge driver keeps one side's certified render, losing the other addition.

type FrontendFunnel added in v0.1.46

type FrontendFunnel struct {
	ID    string
	Title string
	Funnel
}

FrontendFunnel is one declared funnel (forge.Funnel in KCL).

type Funnel added in v0.1.46

type Funnel = dashspec.Funnel

Funnel is dashspec.Funnel.

type FunnelBy added in v0.1.46

type FunnelBy = dashspec.FunnelBy

FunnelBy is dashspec.FunnelBy.

type Group added in v1.0.9

type Group = dashspec.Group

Group is dashspec.Group.

type HyperDXChart

type HyperDXChart struct {
	Name          string            `json:"name"`
	Source        string            `json:"source"`
	DisplayType   string            `json:"displayType"`
	Select        any               `json:"select"` // []HyperDXSelect, or a column string for a search tile
	Where         string            `json:"where"`
	WhereLanguage string            `json:"whereLanguage"`
	GroupBy       string            `json:"groupBy,omitempty"`
	Granularity   string            `json:"granularity,omitempty"`
	SeriesReturn  string            `json:"seriesReturnType,omitempty"`
	NumberFormat  *HyperDXNumFormat `json:"numberFormat,omitempty"`
	Align         *bool             `json:"alignDateRangeToGranularity,omitempty"`
}

HyperDXChart is a builder-style saved chart config.

type HyperDXDashboard

type HyperDXDashboard struct {
	Name    string          `json:"name"`
	Tags    []string        `json:"tags"`
	Tiles   []HyperDXTile   `json:"tiles"`
	Filters []HyperDXFilter `json:"filters,omitempty"`
}

HyperDXDashboard is a dashboard in the shape the HyperDX provisioner and the v2 dashboards API accept (DashboardWithoutIdSchema).

type HyperDXFilter

type HyperDXFilter struct {
	ID            string `json:"id"`
	Type          string `json:"type"`
	Name          string `json:"name"`
	Expression    string `json:"expression"`
	Source        string `json:"source"`
	WhereLanguage string `json:"whereLanguage"`
}

HyperDXFilter is a QUERY_EXPRESSION dashboard filter: a dropdown whose selection is added to every tile's WHERE.

type HyperDXNumFormat

type HyperDXNumFormat struct {
	Output            string `json:"output"`
	Mantissa          *int   `json:"mantissa,omitempty"`
	ThousandSeparated bool   `json:"thousandSeparated,omitempty"`
	Unit              string `json:"unit,omitempty"`
}

HyperDXNumFormat mirrors NumberFormatSchema.

type HyperDXSavedSearch

type HyperDXSavedSearch struct {
	Name          string   `json:"name"`
	Source        string   `json:"source"`
	Select        string   `json:"select"`
	Where         string   `json:"where"`
	WhereLanguage string   `json:"whereLanguage"`
	OrderBy       string   `json:"orderBy"`
	Tags          []string `json:"tags"`
}

HyperDXSavedSearch is the body of POST /api/v2/saved-searches style creation; the file provisioner has no saved-search path, so it is rendered for the API deliverer and listed in the spec.

func RenderHyperDXSavedSearches

func RenderHyperDXSavedSearches(sp Spec) ([]HyperDXSavedSearch, error)

RenderHyperDXSavedSearches renders the spec's saved searches in the shape of the HyperDX saved-search API.

type HyperDXSelect

type HyperDXSelect struct {
	AggFn         string            `json:"aggFn"`
	Level         float64           `json:"level,omitempty"`
	ValueExpr     string            `json:"valueExpression"`
	AggCondition  string            `json:"aggCondition,omitempty"`
	AggCondLang   string            `json:"aggConditionLanguage,omitempty"`
	Alias         string            `json:"alias,omitempty"`
	MetricName    string            `json:"metricName,omitempty"`
	MetricType    string            `json:"metricType,omitempty"`
	NumberFormatP *HyperDXNumFormat `json:"numberFormat,omitempty"`
}

HyperDXSelect is one aggregate of a chart.

type HyperDXTile

type HyperDXTile struct {
	ID     string       `json:"id"`
	X      int          `json:"x"`
	Y      int          `json:"y"`
	W      int          `json:"w"`
	H      int          `json:"h"`
	Config HyperDXChart `json:"config"`
}

HyperDXTile is one chart on the 24-column grid.

type Identities added in v1.0.0

type Identities struct {
	ServiceNames []string
	Workloads    []string
	// RPCServiceNames are the service.names of the processes that serve RPCs:
	// the only ones an rpc.server.* panel can have data for.
	RPCServiceNames []string
	// CPULimitWorkloads and MemoryLimitWorkloads are the workloads that
	// declare that limit: the only ones a *_limit_utilization panel can have
	// data for.
	CPULimitWorkloads    []string
	MemoryLimitWorkloads []string
}

Identities are the telemetry and workload names deployed processes run under: what the overview's panels are scoped to.

type Input

type Input struct {
	Project   string
	Services  []Service
	Processes []Process
	Frontends []string
	// FrontendServices, when set, are the service.names those frontends report
	// (a frontend built from another repository bakes its own); empty derives
	// each from the project and frontend name (naming.FrontendServiceName).
	FrontendServices []string
	// HasDatabase adds the database panels: true once the project has a
	// migration, since the panels read spans the ORM's query hook emits.
	HasDatabase bool
	// Funnels are the declared product funnels. Each becomes one panel on the
	// frontend dashboard, so they only matter when Frontends is non-empty.
	Funnels []FrontendFunnel
	// Deployed scopes the overview, together with Processes' own identities,
	// when the per-process inventory is not being built: forge generate knows
	// every environment's deployed service.names and workloads, but per-process
	// parts are the selected environment's alone (built at bundle time, see
	// ProcessPart). Without it a generate-time overview filtered on the
	// no-deployed-process sentinel and drew nothing.
	Deployed Identities
}

Input is what Build reads from the project.

func ReadFragments added in v1.0.0

func ReadFragments(projectDir string) (Input, bool, error)

ReadFragments reads reusable generation input without loading old process parts. This is the only disk input selected-env assembly consumes.

type Method

type Method struct {
	Name string
}

Method is one rpc of a service.

type Op

type Op = dashspec.Op

Op is dashspec.Op.

type Panel

type Panel = dashspec.Panel

Panel is dashspec.Panel.

type PanelKind

type PanelKind = dashspec.PanelKind

PanelKind is dashspec.PanelKind.

type Predicate

type Predicate = dashspec.Predicate

Predicate is dashspec.Predicate.

type Problem

type Problem = dashspec.Problem

Problem is dashspec.Problem.

func ProblemsOf

func ProblemsOf(err error) []Problem

ProblemsOf is dashspec.ProblemsOf.

type Process added in v1.0.0

type Process struct {
	// Name is the forge workload name (the first, when several workloads run
	// the same executable and command): "admin-api", never the rendered
	// Kubernetes object name, the command line or a hash. It names the
	// process's dashboard ("process-<name>").
	Name string `json:"name"`
	// Kind is the forge workload kind: service, worker, operator, job or
	// cron. Empty is a service. Jobs and crons share one Jobs dashboard.
	Kind         string   `json:"kind,omitempty"`
	Binary       string   `json:"binary"`
	Args         []string `json:"args,omitempty"`
	Root         string   `json:"root,omitempty"`
	ServiceNames []string `json:"serviceNames"`
	Workloads    []string `json:"workloads"`
	RPCServices  []string `json:"rpcServices,omitempty"`
	HasDatabase  bool     `json:"hasDatabase,omitempty"`
	// CPULimit and MemoryLimit say the workload declares that resource limit,
	// the only case the node agent's *_limit_utilization series exist.
	CPULimit    bool `json:"cpuLimit,omitempty"`
	MemoryLimit bool `json:"memoryLimit,omitempty"`
	// NodeMetadata says the process runs where the node agent delivers
	// per-container metadata (a cluster or hosted runtime); a host or compose
	// process has no saturation or restart series.
	NodeMetadata bool `json:"nodeMetadata,omitempty"`
	// ServesRPCDeclared is set for a Go process forge does not build (a sibling
	// repository's, built by a ShellBuild): a service with a port is taken to
	// serve RPCs, since forge cannot read its mounts.
	ServesRPCDeclared bool `json:"servesRpcDeclared,omitempty"`
	// NonGo is set for a process forge can tell is not a Go program of this
	// project or its siblings (a third-party or Docker-built image): it has no
	// Go runtime metrics and no RPC metrics to draw.
	NonGo bool `json:"nonGo,omitempty"`
	// Replaces are the names (dashboard ids minus "process-") this process
	// was known by before dashboards were named for the workload.
	Replaces []string `json:"replaces,omitempty"`
}

Process is a deployed executable and command/root, with the exact telemetry and workload identities it owns across environments. No RPC ownership is inferred from a package name, a workload name, or handler reach alone.

func (Process) IsJob added in v1.0.9

func (p Process) IsJob() bool

IsJob reports whether p runs to completion (a job or a cron), and so is drawn on the Jobs dashboard rather than on a dashboard of its own.

func (Process) ServesRPC added in v1.0.9

func (p Process) ServesRPC() bool

ServesRPC reports whether p serves RPCs, the only processes an rpc.server.* panel has data for.

type ProcessPart added in v1.0.0

type ProcessPart struct {
	Version       string        `json:"version"`
	Process       Process       `json:"process"`
	Dashboard     Dashboard     `json:"dashboard"`
	SavedSearches []SavedSearch `json:"savedSearches"`
}

ProcessPart holds one deployed executable/role's dashboard and saved searches. Separate files keep unrelated process changes disjoint; RPC alert inputs are independent alert-service parts, never duplicated for each mounting process.

type ProjectPart added in v0.1.46

type ProjectPart struct {
	// Input retains reusable generation fragments; selected-env assembly fills
	// Processes from rendered KCL, never from stale disk process parts.
	Input      *Fragments  `json:"input,omitempty"`
	Version    string      `json:"version"`
	Project    string      `json:"project"`
	Overview   Dashboard   `json:"overview"`
	Dashboards []Dashboard `json:"dashboards"`
}

ProjectPart is the part of the Spec that belongs to the project as a whole: the overview, which leads, and the dashboards that follow the services' (Workloads, Releases, the frontend's). See ProcessPart.

type Rendered

type Rendered struct {
	File    string
	Content []byte
}

Rendered is one output file: a name relative to the dashboards directory and its bytes.

func RenderHyperDX

func RenderHyperDX(sp Spec) ([]Rendered, error)

RenderHyperDX renders every dashboard of sp as one provisioner file each, named "<project>-<dashboard id>_gen.json".

func SortedFiles

func SortedFiles(rs []Rendered) []Rendered

SortedFiles returns rs ordered by file name.

type SavedSearch

type SavedSearch struct {
	ID      string      `json:"id"`
	Title   string      `json:"title"`
	Signal  Signal      `json:"signal"`
	Where   []Predicate `json:"where"`
	Columns []string    `json:"columns,omitempty"`
}

SavedSearch is a named log search a service owner returns to.

type Section added in v1.0.0

type Section = dashspec.Section

Section is dashspec.Section.

type Series

type Series = dashspec.Series

Series is dashspec.Series.

type Service

type Service struct {
	// Name is the short service name used in file names and titles
	// ("orders").
	Name string
	// Package is the proto package ("orders.v1"); ProtoService the proto
	// service name ("OrdersService"). Together they give the procedure
	// "orders.v1.OrdersService/GetOrder" the RPC interceptors name spans by.
	Package      string
	ProtoService string
	Methods      []Method
}

Service is one Connect/gRPC service.

type Signal

type Signal = dashspec.Signal

Signal is dashspec.Signal.

type Spec

type Spec struct {
	Version       string        `json:"version"`
	Project       string        `json:"project"`
	Dashboards    []Dashboard   `json:"dashboards"`
	SavedSearches []SavedSearch `json:"savedSearches"`
}

Spec is everything the generator derives for one project.

func Assemble added in v0.1.46

func Assemble(project ProjectPart, processes []ProcessPart) Spec

Assemble is the Spec its parts make: the overview, then each service's dashboard in service-name order, then the project's other dashboards; the saved searches in the same service order.

func Build

func Build(in Input) Spec

Build derives the project's Spec.

func ReadSpec added in v0.1.46

func ReadSpec(projectDir string) (sp Spec, ok bool, err error)

ReadSpec assembles the Spec forge generate last wrote under projectDir. ok is false when there is none (a project that has not generated dashboards). A part of another version is an error that names the fix.

func WithoutProcessDashboards added in v1.0.9

func WithoutProcessDashboards(sp Spec) Spec

WithoutProcessDashboards is sp for an environment that deploys no process: a static site has nothing for the overview, workloads and releases dashboards to measure (the overview would filter on the no-deployed-process sentinel), so only the dashboards that do not need a process remain.

type Thresholds added in v0.1.46

type Thresholds = dashspec.Thresholds

Thresholds is dashspec.Thresholds.

type Unit

type Unit = dashspec.Unit

Unit is dashspec.Unit.

Jump to

Keyboard shortcuts

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