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/dashboard-spec_gen.json) so a second renderer — the Reliant console, drawing with uPlot — can consume exactly the same model without parsing HyperDX JSON.
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
- func AlertDefaultAlertNames() []string
- func AlertDefaultIDs() []string
- func BindEnvID(expr, envID string) string
- func DashboardFile(project string, d Dashboard) string
- func DashboardName(d Dashboard) string
- func FrontendServiceName(project string) string
- func IsBuiltinMetric(name string) bool
- func IsPlatformExpr(expr string) bool
- func LooksLikeHyperDXDashboard(raw []byte) bool
- func LooksLikeSpecDashboard(raw []byte) bool
- func MarshalAlertDefaults(in AlertInput) ([]byte, error)
- func OverridePath(project string, d Dashboard) string
- func PlatformExpr(key string, off bool) string
- func ResolveAlertDefaultsFor(in AlertInput, env string, tuning map[string]AlertTuning, disabled []string) ([]AlertRule, []AlertSkip, error)
- func ValidateAlertTuning(tuning map[string]AlertTuning) error
- func Write(projectDir string, in Input, cs *checksums.FileChecksums) ([]string, error)
- type Agg
- type AlertDefaultInfo
- type AlertDefaultsDoc
- type AlertInput
- type AlertParam
- type AlertRule
- type AlertService
- type AlertSkip
- type AlertTuning
- type Annotation
- type AnnotationSource
- type BundleDashboard
- type BundleDashboardSource
- type BundleFile
- type BundleSet
- type BundleSetInput
- type Dashboard
- type Filter
- type HyperDXChart
- type HyperDXDashboard
- type HyperDXFilter
- type HyperDXNumFormat
- type HyperDXSavedSearch
- type HyperDXSelect
- type HyperDXTile
- type Input
- type Method
- type Op
- type Panel
- type PanelKind
- type Predicate
- type Problem
- type Rendered
- type SavedSearch
- type Series
- type Service
- type Signal
- type Spec
- type Unit
Constants ¶
const ( SeverityCritical = "critical" SeverityWarning = "warning" SeverityInfo = "info" )
Alert severities, the values of the `severity` label.
const ( PlatformDeployFailed = "deploy-failed" PlatformQuota = "observability-quota" )
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.
const ( // DashboardsDir is the project-relative directory mounted as HyperDX's // DASHBOARD_PROVISIONER_DIR. DashboardsDir = "deploy/observability/dashboards" // SpecFile is the serialized Spec: the renderer-neutral model. It sits // beside the dashboards directory, not in it, because the provisioner // reads every *.json it finds there. SpecFile = "deploy/observability/dashboard-spec_gen.json" // SavedSearchesFile holds the HyperDX saved searches, one JSON object per // line. It lives in the dashboards directory (the one directory compose // mounts) under an extension the dashboard provisioner ignores; the // compose entrypoint upserts it, because the file provisioner has no // saved-search path. SavedSearchesFile = DashboardsDir + "/saved-searches_gen.ndjson" )
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.
const ( FieldService = "service.name" FieldEnv = "deployment.environment.name" )
Semantic field names. A field is one of:
service.name, deployment.environment.name (every signal) span.name, span.kind, span.status, span.status_message, span.duration (traces) span.attr.<key> (traces) log.severity, log.body, log.attr.<key> (logs) metric.attr.<key> (metrics) resource.attr.<key> (every signal)
span.kind is "server" or "client"; span.status and log.severity compare against "error". span.duration is milliseconds.
const AlertDefaultsFile = "deploy/observability/alert-defaults_gen.json"
AlertDefaultsFile is the project-relative file `forge generate` writes: the service metadata the default alert rules are derived from, plus the catalog of defaults with their tunable parameters. `forge env shape` reads it back 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.
const AlertDefaultsVersion = "forge.alert-defaults/v1"
AlertDefaultsVersion identifies the serialized shape of AlertDefaultsFile.
const CustomMetricsID = "custom-metrics"
CustomMetricsID is the id of the dashboard BuildCustomMetrics returns, so its file is "<project>-custom-metrics_gen.json".
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 observe alerts check`; the control plane for a deployed env).
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).
const ReleasesID = "releases"
ReleasesID is the id of the dashboard BuildReleases returns, so its file is "<project>-releases_gen.json".
const SpecVersion = "forge.dashboards/v1"
SpecVersion identifies the serialized shape of Spec. Bump it on a breaking change so a consumer can refuse a spec it does not understand.
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 DashboardFile ¶
DashboardFile is the file name of d inside the dashboards directory.
func DashboardName ¶
DashboardName is the HyperDX dashboard name for d: the provisioner upserts by name, so it must be stable and unique across the project.
func FrontendServiceName ¶
FrontendServiceName is the service.name the scaffolded frontends report (src/lib/otel_gen.ts: '<project>-frontend').
func IsBuiltinMetric ¶
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 IsPlatformExpr ¶
IsPlatformExpr reports whether expr is a recorded platform default.
func LooksLikeHyperDXDashboard ¶
LooksLikeHyperDXDashboard reports whether raw is a HyperDX v2 dashboard.
func LooksLikeSpecDashboard ¶
LooksLikeSpecDashboard reports whether raw is a spec-form dashboard rather than a HyperDX one: it has a "panels" array and no "tiles".
func MarshalAlertDefaults ¶
func MarshalAlertDefaults(in AlertInput) ([]byte, error)
MarshalAlertDefaults is the file's bytes.
func OverridePath ¶
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 ¶
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 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 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.
Types ¶
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.
Services []AlertService `json:"services"`
// FrontendService is the browser SDK's service.name ("<project>-frontend"),
// empty when the project has no web frontend.
FrontendService string `json:"frontend_service,omitempty"`
}
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.
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 ¶
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 struct {
Source AnnotationSource `json:"source"`
Label string `json:"label,omitempty"`
}
Annotation is a marker series drawn over every KindLine panel of a dashboard. HyperDX has no such concept, so RenderHyperDX ignores it.
type AnnotationSource ¶
type AnnotationSource string
AnnotationSource names where a dashboard's time-series markers come from.
const ( // AnnotationReleases marks every promotion of a release into the // environment on the dashboard's time-series panels. AnnotationReleases AnnotationSource = "releases" )
The annotation sources. The spec only DECLARES a source; the renderer draws it from data it owns (the Reliant console reads the release ledger).
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 ¶
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
}
BundleSetInput is what CollectBundleSet reads.
type Dashboard ¶
type Dashboard struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
Filters []Filter `json:"filters,omitempty"`
Annotations []Annotation `json:"annotations,omitempty"`
Panels []Panel `json:"panels"`
}
Dashboard is an ordered list of panels under a shared set of filters.
func BuildCustomMetrics ¶
BuildCustomMetrics turns a metrics schema into the "Custom metrics" dashboard: one section per project-declared metric, drawn by its type.
counter a rate: the increase per time bucket 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 BuildReleases ¶
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 ¶
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 ¶
ParseDashboard decodes and validates one dashboard file: a single Dashboard object in the renderer-neutral spec vocabulary (the objects of dashboard-spec_gen.json's "dashboards" array). name is only used in errors.
Every problem found is reported, each with the line and column of the offending value (or, for an unknown field, of its key). Validation covers what the renderers and the console's query engine would otherwise discover one request at a time: field names that exist on the panel's signal, the operator set, series limits, a quantile's range, a metric series naming its metric and type, and unique ids.
type Filter ¶
type Filter struct {
ID string `json:"id"`
Label string `json:"label"`
Field string `json:"field"`
// Signal is the telemetry the dropdown reads its values from. Empty is
// Traces, which every dashboard but the metrics ones draws.
Signal Signal `json:"signal,omitempty"`
}
Filter is a dashboard-level dropdown that narrows every panel.
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 Input ¶
type Input struct {
Project string
Services []Service
Frontends []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
}
Input is what Build reads from the project.
type Panel ¶
type Panel struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
Kind PanelKind `json:"kind"`
Signal Signal `json:"signal"`
Series []Series `json:"series,omitempty"`
// Ratio makes a two-series line panel plot Series[0]/Series[1]
// (an error rate is failed requests over all requests).
Ratio bool `json:"ratio,omitempty"`
// Where narrows every series of the panel.
Where []Predicate `json:"where,omitempty"`
GroupBy []string `json:"groupBy,omitempty"`
// Columns are the fields a KindSearch panel shows.
Columns []string `json:"columns,omitempty"`
Unit Unit `json:"unit,omitempty"`
// Width is in grid columns out of 24; Height in rows. Zero takes the
// default for the kind.
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
}
Panel is one tile.
type PanelKind ¶
type PanelKind string
PanelKind is how a panel is drawn.
const ( // KindNumber is one headline value over the selected time range. KindNumber PanelKind = "number" // KindLine is a time series; with GroupBy, one line per group. KindLine PanelKind = "line" // KindTable is one row per GroupBy value, one column per Series. KindTable PanelKind = "table" // KindSearch is a log or span search (no aggregate): the rows themselves. KindSearch PanelKind = "search" )
type Predicate ¶
type Predicate struct {
Field string `json:"field"`
Op Op `json:"op"`
Value string `json:"value,omitempty"`
Values []string `json:"values,omitempty"`
}
Predicate is one condition. Values are literals; Field is a semantic field.
type Problem ¶
type Problem struct {
// Line and Col are 1-based; zero when the position is unknown.
Line, Col int
// Path is where in the document: panels[2].series[0].agg.
Path string
Message string
}
Problem is one thing wrong with a dashboard file, located in it.
func ProblemsOf ¶
ProblemsOf returns the problems a ParseDashboard error carries, or nil for an error that is not one.
type Rendered ¶
Rendered is one output file: a name relative to the dashboards directory and its bytes.
func RenderHyperDX ¶
RenderHyperDX renders every dashboard of sp as one provisioner file each, named "<project>-<dashboard id>_gen.json".
func SortedFiles ¶
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 Series ¶
type Series struct {
Label string `json:"label"`
Agg Agg `json:"agg"`
// Quantile is the level for AggQuantile, e.g. 0.95.
Quantile float64 `json:"quantile,omitempty"`
// Field is the aggregated value: a semantic field for traces and logs
// (span.duration, span.attr.lcp), the metric NAME for metrics. Empty for
// AggCount.
Field string `json:"field,omitempty"`
// MetricType is "sum" or "gauge" (metrics only).
MetricType string `json:"metricType,omitempty"`
// Where narrows this series alone (e.g. only the failed requests).
Where []Predicate `json:"where,omitempty"`
}
Series is one aggregate shown by a panel.
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 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.