Horopter

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:

fieldholds
typewhat happened, dot-separated, such as deployment.started
subjectwhat it happened to, such as acme/prod
occurred_atwhen it happened

and these optional ones:

fieldholds
titlea human-readable name
correlation_refthe value that joins it to other events
lifecyclewhat it says about its change's lifecycle
actorwho or what performed it
attributesany further JSON the producer wants to keep
idempotency_keya 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:

statusmeans
occurreda point that said nothing about a lifecycle
in_progressstarted, not yet ended
completedended successfully
failedended in failure
rolled_backended by being rolled back
cancelledended 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 inthe event
.started, .begunstarts the change
.completed, .succeeded, .finished, .done, .ended, .resolved, .closedends it as completed
.failed, .errored, .timed_outends it as failed
.rolled_back, .rolledbackends it as rolled_back
.cancelled, .canceled, .abortedends 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 /:

partin the ref ci/deploy-4821set by
locuscithe credential the producer posts with
correlation refdeploy-4821the 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 deploys and both post the correlation ref api-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.

On this page