| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Telemetry.Metrics
Description
The ecluse.* metric catalogue and its bounded-label discipline.
An inline proxy sees thousands of distinct packages, so the failure mode for metrics is a series explosion: a single high-cardinality label (a package name, a version, a denial message) multiplied across every package turns a handful of series into millions. This module is the structural defence. It defines the catalogue of metric names and, crucially, the closed set of label types a metric may carry — every one a small, fixed-domain enum.
Bounded labels
The label vocabulary is a closed sum, Label, whose every constructor pairs a
bounded-domain key with a bounded value. High-cardinality identifiers — package,
version, scope, and a denial message — have no constructor here at all, so
they cannot be made into a metric label: the type system forbids it. They live on
spans and the structured log line (Ecluse.Log) instead, which is where a specific
decision is debugged. The one operator-bounded label is rule (a rule's configured
name): a deployment defines a small, fixed set of rules, so it is bounded by
configuration rather than by an enum, and is the sole label carrying free text.
renderLabel projects a Label to its (key, value) wire pair, and metricAttributes
materialises a label list into the OpenTelemetry Attributes an instrument is recorded
with. The catalogue and the cardinality rule are described in
docs/architecture/observability.md.
Synopsis
- data MetricName
- = HttpServerRequestDuration
- | ServeDecision
- | RuleDenials
- | RuleEvalDuration
- | RuleEffectfulFailures
- | RuleBreakerState
- | UpstreamFetchDuration
- | UpstreamFetchErrors
- | MetadataCacheRequests
- | MetadataCacheEntries
- | MirrorEnqueued
- | MirrorEnqueueFailures
- | MirrorJobsProcessed
- | MirrorPublishDuration
- | CredentialRefresh
- | CredentialTokenTtlSeconds
- metricName :: MetricName -> Text
- allMetricNames :: [MetricName]
- data LabelKey
- labelKeyName :: LabelKey -> Text
- allLabelKeys :: [LabelKey]
- highCardinalityKeys :: [Text]
- data Decision
- = Admit
- | Deny
- | Unavailable
- data ReasonClass
- data Upstream
- data StatusClass
- statusClassOf :: Int -> StatusClass
- data Provider
- = CodeArtifact
- | Static
- | Adc
- data Cause
- data Tier
- data CacheResult
- data MirrorResult
- data CredentialResult
- data BreakerSource
- data BreakerState
- breakerStateCode :: BreakerState -> Int64
- data Label
- = LDecision Decision
- | LReasonClass ReasonClass
- | LRule Text
- | LEcosystem Ecosystem
- | LMount Ecosystem
- | LUpstream Upstream
- | LStatusClass StatusClass
- | LCacheResult CacheResult
- | LMirrorResult MirrorResult
- | LCredentialResult CredentialResult
- | LProvider Provider
- | LCause Cause
- | LBreakerSource BreakerSource
- | LTier Tier
- labelKey :: Label -> LabelKey
- renderLabel :: Label -> (Text, Text)
- metricAttributes :: [Label] -> Attributes
The metric-name catalogue
data MetricName Source #
The catalogue of metric instruments Écluse emits: the ecluse.* domain signals
plus the OpenTelemetry HTTP server semantic convention. Each maps to its wire name
through metricName; a typed enum so the catalogue is enumerable (and asserted whole
in the tests) rather than a scatter of string literals.
Queue backlog and DLQ depth are deliberately absent — those are cloud-native metrics (CloudWatch, Cloud Monitoring), not signals Écluse re-emits. Advisory-sync metrics are deferred until the advisory subsystem exists.
Constructors
| HttpServerRequestDuration |
|
| ServeDecision |
|
| RuleDenials |
|
| RuleEvalDuration |
|
| RuleEffectfulFailures |
|
| RuleBreakerState |
|
| UpstreamFetchDuration |
|
| UpstreamFetchErrors |
|
| MetadataCacheRequests |
|
| MetadataCacheEntries |
|
| MirrorEnqueued |
|
| MirrorEnqueueFailures |
|
| MirrorJobsProcessed |
|
| MirrorPublishDuration |
|
| CredentialRefresh |
|
| CredentialTokenTtlSeconds |
|
Instances
metricName :: MetricName -> Text Source #
The wire name of a MetricName.
allMetricNames :: [MetricName] Source #
Label keys (the closed set)
The closed set of metric label keys. Every label Écluse attaches is one of these
bounded-domain keys. High-cardinality identifiers (package, version, scope, a
denial message) are deliberately absent — see highCardinalityKeys — so they
can never become a metric label.
Constructors
| KeyDecision | |
| KeyReasonClass | |
| KeyRule | |
| KeyEcosystem | |
| KeyMount | |
| KeyUpstream | |
| KeyStatusClass | |
| KeyResult | |
| KeyProvider | |
| KeyCause | |
| KeyBreakerSource | |
| KeyTier |
Instances
| Bounded LabelKey Source # | |
| Enum LabelKey Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Show LabelKey Source # | |
| Eq LabelKey Source # | |
| Ord LabelKey Source # | |
Defined in Ecluse.Telemetry.Metrics | |
allLabelKeys :: [LabelKey] Source #
Every label key in the closed set.
highCardinalityKeys :: [Text] Source #
Bounded label values
The serve decision (ecluse.serve.decision).
Constructors
| Admit | |
| Deny | |
| Unavailable |
Instances
| Bounded Decision Source # | |
| Enum Decision Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Show Decision Source # | |
| Eq Decision Source # | |
data ReasonClass Source #
The bucketed class of a denial reason — a bounded summary of Ecluse.Server.Response.RejectReason, not the rule name or the message (those are high-cardinality and stay on the log line).
Instances
| Bounded ReasonClass Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum ReasonClass Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: ReasonClass -> ReasonClass # pred :: ReasonClass -> ReasonClass # toEnum :: Int -> ReasonClass # fromEnum :: ReasonClass -> Int # enumFrom :: ReasonClass -> [ReasonClass] # enumFromThen :: ReasonClass -> ReasonClass -> [ReasonClass] # enumFromTo :: ReasonClass -> ReasonClass -> [ReasonClass] # enumFromThenTo :: ReasonClass -> ReasonClass -> ReasonClass -> [ReasonClass] # | |
| Show ReasonClass Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> ReasonClass -> ShowS # show :: ReasonClass -> String # showList :: [ReasonClass] -> ShowS # | |
| Eq ReasonClass Source # | |
Defined in Ecluse.Telemetry.Metrics | |
Which upstream a data-plane fetch targeted.
Instances
| Bounded Upstream Source # | |
| Enum Upstream Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Show Upstream Source # | |
| Eq Upstream Source # | |
data StatusClass Source #
The HTTP status class of an upstream response (the bounded summary of the code).
Constructors
| Status2xx | |
| Status3xx | |
| Status4xx | |
| Status5xx | |
| StatusOther |
Instances
| Bounded StatusClass Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum StatusClass Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: StatusClass -> StatusClass # pred :: StatusClass -> StatusClass # toEnum :: Int -> StatusClass # fromEnum :: StatusClass -> Int # enumFrom :: StatusClass -> [StatusClass] # enumFromThen :: StatusClass -> StatusClass -> [StatusClass] # enumFromTo :: StatusClass -> StatusClass -> [StatusClass] # enumFromThenTo :: StatusClass -> StatusClass -> StatusClass -> [StatusClass] # | |
| Show StatusClass Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> StatusClass -> ShowS # show :: StatusClass -> String # showList :: [StatusClass] -> ShowS # | |
| Eq StatusClass Source # | |
Defined in Ecluse.Telemetry.Metrics | |
statusClassOf :: Int -> StatusClass Source #
Classify an HTTP status code into its bounded StatusClass, so a status never
becomes a per-code label.
The outbound-credential provider a refresh/ttl signal concerns.
Constructors
| CodeArtifact | |
| Static | |
| Adc |
Instances
| Bounded Provider Source # | |
| Enum Provider Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Show Provider Source # | |
| Eq Provider Source # | |
A bounded error class for a failure signal (never the exception text).
Constructors
| Timeout | |
| Connection | |
| Decode | |
| UpstreamStatus | |
| OtherCause |
The rule-evaluation tier a duration is measured at.
Constructors
| Structural | |
| Effectful |
data CacheResult Source #
A metadata-cache lookup result.
Instances
| Bounded CacheResult Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum CacheResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: CacheResult -> CacheResult # pred :: CacheResult -> CacheResult # toEnum :: Int -> CacheResult # fromEnum :: CacheResult -> Int # enumFrom :: CacheResult -> [CacheResult] # enumFromThen :: CacheResult -> CacheResult -> [CacheResult] # enumFromTo :: CacheResult -> CacheResult -> [CacheResult] # enumFromThenTo :: CacheResult -> CacheResult -> CacheResult -> [CacheResult] # | |
| Show CacheResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> CacheResult -> ShowS # show :: CacheResult -> String # showList :: [CacheResult] -> ShowS # | |
| Eq CacheResult Source # | |
Defined in Ecluse.Telemetry.Metrics | |
data MirrorResult Source #
A processed mirror job's result. The idempotent "already present" outcome (a
registry 409) is not a distinct value: the worker treats it as a success, so it is
counted as Published — a series that could never emit is not published.
Instances
| Bounded MirrorResult Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum MirrorResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: MirrorResult -> MirrorResult # pred :: MirrorResult -> MirrorResult # toEnum :: Int -> MirrorResult # fromEnum :: MirrorResult -> Int # enumFrom :: MirrorResult -> [MirrorResult] # enumFromThen :: MirrorResult -> MirrorResult -> [MirrorResult] # enumFromTo :: MirrorResult -> MirrorResult -> [MirrorResult] # enumFromThenTo :: MirrorResult -> MirrorResult -> MirrorResult -> [MirrorResult] # | |
| Show MirrorResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> MirrorResult -> ShowS # show :: MirrorResult -> String # showList :: [MirrorResult] -> ShowS # | |
| Eq MirrorResult Source # | |
Defined in Ecluse.Telemetry.Metrics | |
data CredentialResult Source #
A credential-refresh result.
Constructors
| Refreshed | |
| RefreshFailed |
Instances
| Bounded CredentialResult Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum CredentialResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: CredentialResult -> CredentialResult # pred :: CredentialResult -> CredentialResult # toEnum :: Int -> CredentialResult # fromEnum :: CredentialResult -> Int # enumFrom :: CredentialResult -> [CredentialResult] # enumFromThen :: CredentialResult -> CredentialResult -> [CredentialResult] # enumFromTo :: CredentialResult -> CredentialResult -> [CredentialResult] # enumFromThenTo :: CredentialResult -> CredentialResult -> CredentialResult -> [CredentialResult] # | |
| Show CredentialResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> CredentialResult -> ShowS # show :: CredentialResult -> String # showList :: [CredentialResult] -> ShowS # | |
| Eq CredentialResult Source # | |
Defined in Ecluse.Telemetry.Metrics Methods (==) :: CredentialResult -> CredentialResult -> Bool # (/=) :: CredentialResult -> CredentialResult -> Bool # | |
data BreakerSource Source #
Which circuit breaker a state gauge concerns.
Constructors
| EffectfulRule | |
| CredentialMint |
Instances
| Bounded BreakerSource Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum BreakerSource Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: BreakerSource -> BreakerSource # pred :: BreakerSource -> BreakerSource # toEnum :: Int -> BreakerSource # fromEnum :: BreakerSource -> Int # enumFrom :: BreakerSource -> [BreakerSource] # enumFromThen :: BreakerSource -> BreakerSource -> [BreakerSource] # enumFromTo :: BreakerSource -> BreakerSource -> [BreakerSource] # enumFromThenTo :: BreakerSource -> BreakerSource -> BreakerSource -> [BreakerSource] # | |
| Show BreakerSource Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> BreakerSource -> ShowS # show :: BreakerSource -> String # showList :: [BreakerSource] -> ShowS # | |
| Eq BreakerSource Source # | |
Defined in Ecluse.Telemetry.Metrics Methods (==) :: BreakerSource -> BreakerSource -> Bool # (/=) :: BreakerSource -> BreakerSource -> Bool # | |
Breaker state (a bounded gauge value, not a label)
data BreakerState Source #
The circuit-breaker state, recorded as the value of the ecluse.rule.breaker.state
gauge (labelled by BreakerSource). It is a bounded measurement, not a label.
Instances
| Bounded BreakerState Source # | |
Defined in Ecluse.Telemetry.Metrics | |
| Enum BreakerState Source # | |
Defined in Ecluse.Telemetry.Metrics Methods succ :: BreakerState -> BreakerState # pred :: BreakerState -> BreakerState # toEnum :: Int -> BreakerState # fromEnum :: BreakerState -> Int # enumFrom :: BreakerState -> [BreakerState] # enumFromThen :: BreakerState -> BreakerState -> [BreakerState] # enumFromTo :: BreakerState -> BreakerState -> [BreakerState] # enumFromThenTo :: BreakerState -> BreakerState -> BreakerState -> [BreakerState] # | |
| Show BreakerState Source # | |
Defined in Ecluse.Telemetry.Metrics Methods showsPrec :: Int -> BreakerState -> ShowS # show :: BreakerState -> String # showList :: [BreakerState] -> ShowS # | |
| Eq BreakerState Source # | |
Defined in Ecluse.Telemetry.Metrics | |
breakerStateCode :: BreakerState -> Int64 Source #
The gauge code for a breaker state: 0 closed, 1 half-open, 2 open — a small
ordinal so a dashboard can alarm on "not closed" without a high-cardinality label.
Labels
A single metric label: a bounded key paired with its bounded value. There is no
constructor for a package, version, scope, or message, so a high-cardinality identifier
cannot be turned into a label. LRule carries a rule's configured name — the one
operator-bounded label (a deployment defines a small, fixed rule set).
Constructors
Attribute construction
metricAttributes :: [Label] -> Attributes Source #
Materialise a label list into the OpenTelemetry Attributes an instrument is
recorded with. Every value is bounded, so the attribute set an instrument ever sees is
drawn from a small fixed product of the label domains — never the unbounded space of
package identifiers.