Ankusa.Metrics.Cardinality (ankusa v0.7.0)

Copy Markdown View Source

The series ceiling of Ankusa.Metrics: how many distinct label sets one metric may keep before the rest are folded into "other".

Only the identity tags, :tenant_id, :source_id and :tenant, are policed. Every other label comes from a fixed set (an outcome, a sink module, an HTTP status), and metrics.detail decides which identity tags a metric carries at all. A metric's first metrics.max_series_per_metric - 1 label sets that include an identity are admitted and remembered; one slot is left for the "other" series that every later label set is rewritten into (:tenant_id, :source_id and :tenant each become "other", the other labels are kept, so a metric holds one "other" series per combination of its fixed labels). A real tenant named other shares that series.

The admitted sets live in one public ETS table per instance, owned by this process (a restart empties it, and Ankusa.Metrics restarts the reporter with it, so the two never disagree). Admission runs in the process that emitted the telemetry event, once per event and metric:

  • a known label set is a single :ets.member/2;
  • an unknown one reads the metric's counter, and once it is full returns without writing anything, so a flood of new tenants does not contend on the counter;
  • otherwise it reserves a slot (:ets.update_counter/4), claims the label set (:ets.insert_new/2) and gives the slot back when another process claimed the same set first. A reserved slot is only ever released, so the admitted sets never exceed the ceiling.

A series is never forgotten: TelemetryMetricsPrometheus.Core keeps one for as long as the reporter runs, and so does this table.

Summary

Functions

Admit values' label set into name's series, or refuse it when cap - 1 sets are already held. tags are the metric's labels.

Returns a specification to start this module under a supervisor.

The label values to report for one event: values itself when its label set is (or can become) one of name's admitted series, else values with every identity tag in tags replaced by "other".

The label names this policy bounds.

Whether tags carry an identity label, i.e. whether a metric with them is policed.

Name of instance's admitted-series table.

Functions

admit(table, name, tags, cap, values)

@spec admit(atom(), term(), [atom()], pos_integer(), map()) :: :admitted | :overflow

Admit values' label set into name's series, or refuse it when cap - 1 sets are already held. tags are the metric's labels.

child_spec(init_arg)

@spec child_spec(keyword()) :: Supervisor.child_spec()

Returns a specification to start this module under a supervisor.

See Supervisor.

fold(table, name, tags, cap, values)

@spec fold(atom(), term(), [atom()], pos_integer(), map()) :: map()

The label values to report for one event: values itself when its label set is (or can become) one of name's admitted series, else values with every identity tag in tags replaced by "other".

identity_tags()

@spec identity_tags() :: [atom()]

The label names this policy bounds.

policed?(tags)

@spec policed?([atom()]) :: boolean()

Whether tags carry an identity label, i.e. whether a metric with them is policed.

start_link(instance)

@spec start_link(atom()) :: GenServer.on_start()

table(instance)

@spec table(atom()) :: atom()

Name of instance's admitted-series table.