What Is Horopter
What Horopter is for, and the words the tutorials use.
Horopter is a store for change events. Deployments, migrations, feature-flag flips and incidents happen in many systems, and each system records them in its own way. Horopter takes them in from all of those systems in one shape, then serves them to your observability tools, so each can show what changed beside the data it already shows you.
This page explains the words the tutorials use. It describes Horopter v0.14.2.
Events
An event is a fact that something happened: a deployment started, a migration failed.
Systems that post events to Horopter are producers: a CI job, Flux, or a person running
horo.
An event is never updated or deleted once Horopter has stored it. Each one carries three required fields:
| field | holds |
|---|---|
type | what happened, dot-separated, such as deployment.started |
subject | what it happened to, such as acme/prod |
occurred_at | when it happened |
and these optional ones:
| field | holds |
|---|---|
title | a human-readable name |
correlation_ref | the value that joins it to other events |
lifecycle | what it says about its change's lifecycle |
actor | who or what performed it |
attributes | any further JSON the producer wants to keep |
idempotency_key | a key that makes posting the same event twice store it once |
Changes
A change is what Horopter derives from every event that shares a ref: one deployment, from the event that started it to the event that finished it. It is what Horopter serves to your tools. A change is never written directly; Horopter rebuilds it from its events, so the events are the record and the change is a view of them.
A change takes one of three shapes:
- Point: a moment, such as a configuration reload. It comes from an event posted without a correlation ref that says nothing about a lifecycle.
- Open: a change that has started and not yet ended. It has a start and no end.
- Closed: a change with an end, which may be the same second as its start.
A start event posted without a correlation ref makes an open change, and it stays open
until an event arrives with the correlation_ref Horopter returned for it. Give every event
of something that starts and ends the same correlation ref.
Lifecycle and Status
A change's status says where it is in its lifecycle:
| status | means |
|---|---|
occurred | a point that said nothing about a lifecycle |
in_progress | started, not yet ended |
completed | ended successfully |
failed | ended in failure |
rolled_back | ended by being rolled back |
cancelled | ended by being cancelled |
Producers never set the status. Horopter derives it from what each event says about the
change's lifecycle. An event says it in its lifecycle field, set to started, completed,
failed, rolled_back, cancelled, or none to say nothing. Without that field, the last
segment of the event's type decides:
| type ends in | the event |
|---|---|
.started, .begun | starts the change |
.completed, .succeeded, .finished, .done, .ended, .resolved, .closed | ends it as completed |
.failed, .errored, .timed_out | ends it as failed |
.rolled_back, .rolledback | ends it as rolled_back |
.cancelled, .canceled, .aborted | ends it as cancelled |
Any other ending says nothing about the lifecycle. So deployment.started followed by
deployment.completed on the same ref is a closed change with status completed.
A change starts at the earliest start event's occurred_at. With no start event, it starts
at the earliest occurred_at of any of its events. Events can arrive in any order and the
change's start comes out the same.
Refs
A ref names a change: every event with the same ref belongs to the same change. A ref is
a locus and a correlation ref, joined by a /:
| part | in the ref ci/deploy-4821 | set by |
|---|---|---|
| locus | ci | the credential the producer posts with |
| correlation ref | deploy-4821 | the producer, in the event's correlation_ref field |
The correlation ref is the producer's choice. To make several events one change, post
them all with the same correlation_ref. An event posted without one starts a change of its
own, whose correlation ref is the event's id.
When Horopter accepts an event it answers with both: ref, the whole ref, and
correlation_ref, the value to send on later events to add them to the same change. That is
the correlation ref you sent, or the event's id if you sent none. Send the correlation_ref,
not the ref: Horopter rejects a correlation ref that already starts with your locus.
Locus
A locus is a set of producers that can add events to each other's changes. It is the first part of every ref, and it is what keeps one producer's changes apart from another's.
A locus belongs to a credential, not to an event. Whoever issues the credential sets it, and
every event posted with that credential gets that locus at the front of its ref. If no locus
is given when the credential is issued, it is the credential's source: the name of the system
the credential was issued for, such as github. A locus cannot be empty or contain a /.
The locus decides which producers can share a change:
- Same locus: the producers can work on the same change. A deploy that CI starts and a
cluster controller completes is one change if both of their credentials have the locus
deploysand both post the correlation refapi-v2.5.0. - Different locus: their events never share a change, even when they post the same correlation ref. A producer cannot write into another's changes by guessing their refs.
Give credentials the same locus only when their producers need to share changes. Otherwise, the default keeps each source's changes apart.
The name comes from geometry, where a locus is a set of points defined by a rule. The horopter itself is a locus: the points in space that the two eyes see at corresponding places on their retinas.
Subject
The subject is what a change happened to, conventionally path-shaped: acme/prod, or
acme/prod/api for one service in it. Every event names one, and readers filter changes by
it, which is how a tool asks for only the changes to the system it watches.
The subject is the producer's claim, not something Horopter verifies. A credential can limit the subjects its producer may post to, and Horopter refuses an event outside that limit; within it, Horopter stores the subject as given.
Titles
A change's title is its label, chosen from its events' titles:
- The title of the earliest start event that has one. A start describes what changed, and later events describe how it went.
- Without a titled start event, the latest title to arrive on any of its events.
- With no titles at all, the type of the first of its events Horopter received, so every change has a label.
Give the start event the title you want to see, such as Deploy api v2.5.0 to prod.
Next
The tutorials put these words to work: you post events, then see the changes on a graph.