Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions docs/service-level-objectives-details.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
title: How our SLOs are built
sidebar_position: 12.5
---

# How our SLOs are built

This page is for those who want to know more about Packit's
[Service Level Objectives](./service-level-objectives.md) (SLOs): the Service
Level Indicators (SLIs) we use to track them, how we measure them and why we
picked them. Other teams can use it as a guide when defining their own SLOs.

## Job outcomes

The objectives talk about jobs (builds and tests) ending with a status. To make
them unambiguous, we distinguish these outcomes:

- **success**: the job finished and everything is awesome
- **failure**: the job finished and wasn't successful: the PR needs to be fixed
- **error**: infrastructure problems prevented the job from completing

Only _success_ and _failure_ count as good outcomes for our objectives. Both
give you a real answer about your change. An _error_ means Packit (or a service
it depends on) let you down.

## Indicators

To know how we are doing against the objectives, we measure these indicators:

| Objective | Indicators |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SLO1 | Time it takes Packit to set the first status on a PR or commit after receiving the event. Number of PRs or commits whose first status took longer than 25 seconds (a looser limit than the 15 seconds of SLO1). |
| SLO2 | Number of Copr builds queued, started and finished. Time from a Copr build finishing to Packit reporting the final status. Time from accepting a Copr build to it finishing. |
| SLO3 | Number of test runs queued, started and finished. Time from submitting a test run to Packit setting its final status. |

The counters tell us how many jobs entered and left the pipeline. If jobs are
queued or started but never finish, it shows up as a gap between the numbers.
The durations tell us how long our users wait.

Both SLO1 indicators are recorded only when Packit sets a first status. An event
that Packit drops completely, without setting any status, does not show up in
either of them.

## How we measure

All the other teams around us use the Prometheus + Grafana combo, so this is
our choice as well. Packit pushes the metrics to a Prometheus Pushgateway, and
the indicators are visualised in two Grafana dashboards: **Packit** and
**Fedora CI**.

Durations are recorded as Prometheus
[histograms](https://prometheus.io/docs/concepts/metric_types/#histogram). The
histogram buckets are aligned with the SLO time thresholds (for example 15
seconds for SLO1 and 12 hours for SLO3), so we can directly compute
[what percentage of the measured jobs](https://prometheus.io/docs/practices/histograms/)
finished within the threshold, instead of relying on averages.

The histograms record only the time, whatever the outcome of the job. This means

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] logic-error

The lead sentence "The histograms record only the time, whatever the outcome of the job" contradicts the bullets that follow it. Lines 65-67 say the build-reporting histogram is recorded only when Packit reports success or failure. Lines 71-73 say a failed build is not measured at all when its SRPM build already failed or a newer build exists for the same target. Readers may conclude that every finished build is in the SLO2 histogram, whatever its outcome.

Suggested fix: Reword line 58 so it does not say recording ignores the outcome. For example: "The histograms record only durations, not job outcomes, and some outcomes are not recorded at all. This means the current indicators approximate SLO2 and SLO3 rather than compute them exactly:"

the current indicators approximate SLO2 and SLO3 rather than compute them
exactly:

- The time to the final test status is recorded for every finished test run,
including runs that ended with an error or were canceled. A Testing Farm
error reported within 12 hours therefore counts as within the threshold.
- The time to the final build status is recorded only when Packit reports
success or failure. A build that ends with an error on Packit's side is
missing from the histogram completely.
- Packit reports every unsuccessful Copr build as a failure, including builds
that failed because of a Copr infrastructure problem. Such builds are
measured as failures, even though they are errors by the definitions above.
- A failed build is not reported, and so not measured, when its SRPM build has
already failed (Packit has reported that failure already) or when a newer
build for the same target exists.

Unfortunately, we cannot share our Grafana instance with you since it's hidden
behind a firewall.

## Why these objectives and indicators

Before defining the objectives, we asked the most active users of Packit
(projects such as anaconda, cockpit, systemd and others) what they expect from
the service in terms of latency, reliability and availability. The objectives
are derived from their answers.

### SLO1: A quick first status

The most consistent request was a quick "accepted" status: an indication that
Packit has seen the change and will deal with it. Users were fine with waiting
minutes or even hours for the results, as long as they knew the request had been
picked up. Their expectations for this status ranged from 5 seconds to a minute.
No status at all is frustrating, both for our users and for us, because it's
impossible to tell whether Packit is working or has dropped the event. Hence the
first objective is about the first status only, with a strict time limit and a
high percentage.

In late 2022, the SLO1 limit was raised from 15 to 30 seconds to cover setting
all statuses ([packit-service#1776](https://github.com/packit/packit-service/pull/1776)).
In March 2023, SLO1 was changed to the current definition: the first status
within 15 seconds.

### SLO2: Builds end with a real answer

Copr builds for pull requests are Packit's core functionality. What matters to
users is that a build ends with a real answer (success or failure) and is not
interrupted by an infrastructure error. Users told us an error rate of about 5
to 10% is something they would tolerate at the beginning.

Build duration is not something we control: some builds take minutes, others
take hours. An objective defined from the moment we accept the build would
therefore depend mostly on the project being built. That's why SLO2 measures
the part Packit is responsible for: reporting the final result once Copr has
finished the build.

### SLO3: Tests with a lower target

Tests are similar to builds, but they run in Testing Farm, which is outside of
our control and is a more complex system (provisioning machines, running tests,
collecting logs). That's why the percentage is lower and the time limit covers
the whole test run.

### Indicators follow the objectives

We did not start by collecting all the metrics we could get. We picked
indicators that answer the question "are we meeting the objective?" directly:
how long it takes to set a status, and how many jobs entered and left each stage.
This keeps the dashboards small and the alerts meaningful.

## Guidance for other teams

If you are defining SLOs for your own service, this is what worked for us:

- **Ask your users first.** Talk to the most frequent users of your service
and ask about latency, error rate, throughput and availability. Their answers
are more valuable than the current numbers in your dashboards.
- **Start small.** Some teams (for example
[CKI](https://cki-project.org/docs/hacking/rfcs/cki-004-slo/#created-slos-based-on-the-feedback))
have a comprehensive set of SLOs. Instead of taking the same route, we started
with three objectives and add more objectives and indicators over time.
- **Measure what you control.** If a part of the workflow is owned by
another service (Copr builds, Testing Farm), either measure only your part or
set a lower target.
- **Use distributions, not averages.** "99% of requests within 15 seconds" says
much more than "15 seconds on average", which can hide problems in the tail.
- **Avoid 100%.** Insisting on perfection slows down development. The error
budget gives you room to ship new features while keeping the service
reliable.
- **Revisit the targets.** Loose targets are fine at the beginning. Tighten
them, or drop objectives nobody talks about, as you learn more.

## Background

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] under-engineering

The PR closes #1094, and the page says it supersedes the error-budgets research. But the research is still imported from packit/research (make import, docusaurus.config.js) and stays published with no historical notice and no link to the new page, so the site still shows two SLO/SLI descriptions. The packit/research follow-up has no tracking issue. The research file lives in another repository and could not be checked here.

Suggested fix: Open a tracking issue or PR in packit/research to add a historical notice to research/monitoring/error-budgets/SLOs-SLIs.md that links to the official SLO pages, or change "Closes #1094" to a non-closing reference until that is done.

This page supersedes the original research on error budgets, which is kept

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] under-engineering

The research page (https://packit.dev/research/monitoring/error-budgets/SLOs-SLIs) is copied into the site from packit/research by make import, so it will keep being published without any notice that it has been superseded. Only the new details page says it supersedes the research. The PR says Closes #1094, so merging it closes the issue. The packit/research follow-up, which the PR description itself calls necessary, has no tracking issue.

Suggested fix: Before #1094 is closed, either open a follow-up in packit/research to mark SLOs-SLIs.md as historical and link it to the new page, or change Closes #1094 to Refs #1094 until the research page is updated.

only for historical reasons:
[github.com/packit/research/../error-budgets](https://github.com/packit/research/tree/main/research/monitoring/error-budgets).
It contains the full notes from Google's SRE book and the collected
[expectations of our users](https://github.com/packit/research/blob/main/research/monitoring/error-budgets/users-expectations.md).
5 changes: 3 additions & 2 deletions docs/service-level-objectives.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ system so we reduced the number here.

![SLO 3](img/slo/slo3.png)

If you are interested, here's the accompanying research:
[github.com/packit/research/../error-budgets](https://github.com/packit/research/tree/main/research/monitoring/error-budgets)
If you want to know more about how these objectives are built, how we measure
them and why we picked them, see
[How our SLOs are built](./service-level-objectives-details.md).

Unfortunately, we cannot share our Grafana instance with you since it's hidden
behind a firewall.
Loading