AuroraMeter.Event (Aurora Meter v1.0.0)

View Source

A recorded usage fact, as Aurora Meter hands it back.

This is a read struct. Hosts pattern match on it and read its fields; nothing outside the library builds one. It is the return shape of AuroraMeter.record/4, record_batch/2 and correct/4, and of AuroraMeter.Events.get/2 and stream/2.

Fields

  • id: the row's internal UUID, assigned by the database. Useful in a support conversation and nowhere else. It is not the identity of the fact; event_id is.
  • event_id: the caller's identity for this fact, unique per tenant, at most 128 bytes. Recording twice with the same event_id and the same payload is a duplicate, not a second fact.
  • tenant_key: the resolved tenant key.
  • feature: the feature atom.
  • quantity: a positive integer.
  • kind: :usage or :correction.
  • original_event_id: for a correction, the event_id of the fact it corrects, in the same tenant. nil for a usage event.
  • occurred_at: when the usage happened, as the caller stated it.
  • recorded_at: when Aurora Meter wrote the row. The same column the Ecto schema calls inserted_at.
  • period_start: the start of the billing window the fact is charged to.
  • period_source: the period source module that resolved it, as a string.
  • dimensions: the caller's breakdown keys, string keys and scalar values.
  • metadata: the caller's free-form map.
  • plan_id, plan_version: the plan in force when the usage occurred. Recorded for attribution, never used to reprice (decision D05).
  • attribution: how much to trust the period and plan on this row.
  • durability: :durable when the row is committed, :conditional when it was written inside a transaction the host still owns.
  • seq: the row's insertion order, assigned by a database sequence.

The attribution vocabulary

  • :resolved: the period source placed occurred_at in a window without ambiguity, and the plan in force at that instant was resolved. Both the period and the plan on this row are facts.
  • :plan_unresolved: the period is a fact and the plan is not there. The tenant had no subscription at all, or none that covers occurred_at, so there is no commercial contract to name. plan_id and plan_version are NULL, and they are NULL rather than today's plan on purpose: substituting the current plan for a historical fact is exactly the repricing decision D05 forbids. Build unit 07c added this value; before it, every row whose period resolved said :resolved and carried no plan at all.
  • :unresolved: the source could not place the instant, so the calendar month containing it was used instead. The period on this row is an approximation, and this value is how you tell. The plan is not resolved either, and deliberately not even attempted: a period this code had to guess is not an instant worth resolving a contract against.
  • :legacy_track: the row was written by AuroraMeter.track/4 before the durable path existed, and given an identity afterwards by mix aurora_meter.events.backfill. Its occurred_at is the instant the row was written, not the instant the usage happened, and it was never billed.

The vocabulary is a list, not a database constraint, so a later release can add a kind of attribution without a migration. Match on the values you know and treat an unknown one as untrusted.

Summary

Types

How much to trust the period and plan recorded on an event.

Whether the row is committed, or still inside a transaction the host owns.

t()

Types

attribution()

@type attribution() ::
  :resolved | :plan_unresolved | :unresolved | :legacy_track | String.t()

How much to trust the period and plan recorded on an event.

durability()

@type durability() :: :durable | :conditional

Whether the row is committed, or still inside a transaction the host owns.

t()

@type t() :: %AuroraMeter.Event{
  attribution: attribution() | nil,
  dimensions: map(),
  durability: durability(),
  event_id: String.t() | nil,
  feature: atom(),
  id: String.t(),
  kind: :usage | :correction,
  metadata: map(),
  occurred_at: DateTime.t() | nil,
  original_event_id: String.t() | nil,
  period_source: String.t() | nil,
  period_start: DateTime.t() | nil,
  plan_id: String.t() | nil,
  plan_version: String.t() | nil,
  quantity: integer(),
  recorded_at: DateTime.t(),
  seq: integer() | nil,
  tenant_key: String.t()
}