ecluse
Safe HaskellNone
LanguageGHC2021

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

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

http.server.request.duration — server request latency (histogram).

ServeDecision

ecluse.serve.decision — admit/deny/unavailable (counter).

RuleDenials

ecluse.rule.denials — rule denials by rule and reason class (counter).

RuleEvalDuration

ecluse.rule.eval.duration — rule-evaluation latency by tier (histogram).

RuleEffectfulFailures

ecluse.rule.effectful.failures — effectful-rule failures (counter).

RuleBreakerState

ecluse.rule.breaker.state — effectful/mint breaker state by source (gauge).

UpstreamFetchDuration

ecluse.upstream.fetch.duration — upstream fetch latency (histogram).

UpstreamFetchErrors

ecluse.upstream.fetch.errors — upstream fetch errors (counter).

MetadataCacheRequests

ecluse.metadata_cache.requests — metadata-cache hit/miss (counter).

MetadataCacheEntries

ecluse.metadata_cache.entries — metadata-cache occupancy (gauge).

MirrorEnqueued

ecluse.mirror.enqueued — mirror jobs enqueued (counter).

MirrorEnqueueFailures

ecluse.mirror.enqueue.failures — mirror enqueue failures (counter).

MirrorJobsProcessed

ecluse.mirror.jobs.processed — mirror jobs processed by result (counter).

MirrorPublishDuration

ecluse.mirror.publish.duration — mirror publish latency (histogram).

CredentialRefresh

ecluse.credential.refresh — credential refreshes by result and provider (counter).

CredentialTokenTtlSeconds

ecluse.credential.token.ttl.seconds — remaining token lifetime by provider (gauge).

metricName :: MetricName -> Text Source #

The wire name of a MetricName.

allMetricNames :: [MetricName] Source #

Every metric in the catalogue (the Bounded/Enum enumeration).

Label keys (the closed set)

data LabelKey Source #

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.

labelKeyName :: LabelKey -> Text Source #

The wire name of a LabelKey.

allLabelKeys :: [LabelKey] Source #

Every label key in the closed set.

highCardinalityKeys :: [Text] Source #

The high-cardinality identifiers that must never be metric labels: they live on spans and the structured log line instead. The label-domain guard asserts none of these is a LabelKey wire name; there is, by construction, no Label that produces one.

Bounded label values

data Decision Source #

The serve decision (ecluse.serve.decision).

Constructors

Admit 
Deny 
Unavailable 

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).

data Upstream Source #

Which upstream a data-plane fetch targeted.

Constructors

Private 
Public 

statusClassOf :: Int -> StatusClass Source #

Classify an HTTP status code into its bounded StatusClass, so a status never becomes a per-code label.

data Provider Source #

The outbound-credential provider a refresh/ttl signal concerns.

Constructors

CodeArtifact 
Static 
Adc 

data Cause Source #

A bounded error class for a failure signal (never the exception text).

Instances

Instances details
Bounded Cause Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Enum Cause Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Show Cause Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

showsPrec :: Int -> Cause -> ShowS #

show :: Cause -> String #

showList :: [Cause] -> ShowS #

Eq Cause Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

(==) :: Cause -> Cause -> Bool #

(/=) :: Cause -> Cause -> Bool #

data Tier Source #

The rule-evaluation tier a duration is measured at.

Constructors

Structural 
Effectful 

Instances

Instances details
Bounded Tier Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Enum Tier Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

succ :: Tier -> Tier #

pred :: Tier -> Tier #

toEnum :: Int -> Tier #

fromEnum :: Tier -> Int #

enumFrom :: Tier -> [Tier] #

enumFromThen :: Tier -> Tier -> [Tier] #

enumFromTo :: Tier -> Tier -> [Tier] #

enumFromThenTo :: Tier -> Tier -> Tier -> [Tier] #

Show Tier Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

showsPrec :: Int -> Tier -> ShowS #

show :: Tier -> String #

showList :: [Tier] -> ShowS #

Eq Tier Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

(==) :: Tier -> Tier -> Bool #

(/=) :: Tier -> Tier -> Bool #

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.

Constructors

Published 
Failed 

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.

Constructors

Closed 
HalfOpen 
Open 

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

data Label Source #

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).

Instances

Instances details
Show Label Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

showsPrec :: Int -> Label -> ShowS #

show :: Label -> String #

showList :: [Label] -> ShowS #

Eq Label Source # 
Instance details

Defined in Ecluse.Telemetry.Metrics

Methods

(==) :: Label -> Label -> Bool #

(/=) :: Label -> Label -> Bool #

labelKey :: Label -> LabelKey Source #

The LabelKey a Label is filed under.

renderLabel :: Label -> (Text, Text) Source #

Project a Label to its (key, value) wire pair.

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.