[Документация Yandex Cloud](../../index.md) > [Monium](../index.md) > SLO > Обзор

# Обзор

_SLO (Service Level Objective)_ — целевой уровень качества сервиса, выраженный в определенных показателях за период времени. В отличие от SLA, SLO — это внутренняя цель, а не юридическое обязательство.

## Общие понятия {#basic-terms}

* _SLI (Service Level Indicator)_. Показатель уровня надежности сервиса за определенный период времени. Периодически рассчитываемый показатель, по значению которого делается вывод о состоянии надежности сервиса и возможности решения пользовательского сценария. Для event-based SLO рассчитывается по формуле *SLI = Good Events / Total Events \* 100%*. Выражается в процентах.

* _SLO (Service Level Objective)_. Целевое значение, с которым сравнивается рассчитанное значение SLI. Если значение SLI опускается ниже SLO и остается таковым в течение длительного времени, рекомендуется приостановить разработку новой функциональности и сосредоточиться на улучшении надежности сервиса. Выражается в процентах.

* _Error Budget_ — остаток бюджета ошибок. Бюджет ошибок — это количество _Bad Events_, которые могут произойти в сервисе за определенный период времени до того, как значение SLI опустится ниже SLO. Рассчитывается по формуле *Error Budget = (100% - SLI) \* Total Events*. Остаток бюджета ошибок выражается в процентах.

{% note info %}

_SLA (Service Level Agreement)_ — соглашение между поставщиком и потребителем сервиса, определяет уровень предоставляемого сервиса, его качество и ответственность сторон в случае нарушений. Его можно рассматривать как юридический документ, основанный на SLO. Но SLA — не замена SLO или SLI.

{% endnote %}

{% note warning %}

SLO — не замена алертам, которые отслеживают показатели здоровья сервиса.

Алерты могут более точечно следить за отдельными показателями сервиса и позволяют оперативно реагировать на проблемы — это инструмент для дежурного или разработчика.

SLO — аналитический инструмент, помогающий принимать управленческие решения и планировать разработку сервиса на основе показателей его надежности.

{% endnote %}

## Способы расчета {#calc-methods}

Есть несколько подходов для расчета показателей:

* *Event-based SLO* или *SLO на основе событий*. Основой расчета показателей является количество событий определенного типа, происходящих в сервисе, и формулируется в виде *99,9% запросов к сервису за 30 дней успешно обрабатываются* или *в 99,95% случаев сервис отвечает на запрос не более чем за 100 мс*. Источники данных для расчета показателей состоят из:
    * *Good Events* — события, которые трактуются как «хорошие», например, *HTTP Code 2xx в ответе сервиса* или *обработка запроса быстрее, чем за 100 мс*.
    * *Bad Events* — события, которые трактуются как «плохие», например, *HTTP Code 5xx в ответе сервиса* или *обработка запроса медленнее, чем за 100 мс*.
    * *Total Events* — общее количество валидных с точки зрения сервиса событий, например *общее количество запросов, обработанных сервисом*. Критерий валидности события определяется самим сервисом, например, *HTTP Code 500 в ответе сервиса* — это валидное событие, так как URL запроса был указан верно, но сервис не смог обработать запрос из-за внутренней ошибки или ошибки в данных. При этом, если URL был указан с ошибкой, то это однозначно невалидное событие, так как неизвестно, к какой части сервиса было обращение.
    
    В SLO можно выбрать метод расчета:
    
    * **Good Events / Total Events** — хорошие события и общие события, например, успешные ответы сервиса и общее количество запросов к сервису.
    * **Bad Events / Total Events** — плохие события и общие события, например, ответы сервиса с ошибкой и общее количество запросов к сервису.
    * **Good Events / Bad Events** — хорошие события и плохие события, например, успешные ответы сервиса и ответы сервиса с ошибкой.
    
    При выборе любого из методов расчета количество событий неуказанного типа высчитывается автоматически. Например, если указаны только хорошие и плохие события, то общее количество событий высчитывается как сумма плохих и хороших событий.
* *Time-based SLO* или *SLO на основе временного отрезка* — основой расчета показателей является отрезок времени работы сервиса (другими словами, его uptime) и формулируется в виде *за последние 30 дней 95% запросов к сервису в течение 1 минуты успешно обработаны* или *за последние 30 дней 99,95% времени в течение 1 минуты сервис отвечал на запросы не более чем за 100 мс*. Критерии uptime определяются сервисом самостоятельно.
* *Alert-based SLO* или *SLO на основе алертов*. Основой расчета показателей является статус вычисляемых алертов и формулируется в виде: *за последние 30 дней алерт HTTP 5xx rate находился в статусе ОК*. Алерты, на основе которых будут рассчитываться показатели, определяются сервисом самостоятельно.

В Monium используется способ **Event-based**.


## Окно вычисления {#calc-window}

Все показатели уровня надежности сервиса рассчитываются за определенный период времени — динамические показатели. На их основе можно отслеживать надежность сервиса с течением времени.

Не всем сервисам требуется отслеживать надежность на коротких промежутках времени, поскольку поддерживать высокий уровень надежности на коротких промежутках — достаточно сложная задача. Для таких сервисов диапазон значений уровня надежности может быть широким.

Например, пиковые нагрузки в течение рабочего дня могут приводить к высокому уровню ошибок в ответах сервиса, при этом ночью или в выходные дни все показатели будут в норме. Или обратный пример: когда ночью количество запросов к сервису значительно снижается, даже небольшое количество ошибок в ответах может привести к сильному падению SLI. Поэтому рекомендуется использовать достаточно большие окна вычисления, чтобы сгладить такие отклонения.

Существует два основных способа выбора окна вычисления:

* *Calendar-aligned time window* (*календарное окно*) — окно вычисления выбирается за определенный календарный период, например календарный месяц. Плюсом является то, что окно вычисления всегда точно соотносится с календарным периодом. В этом же заключается его минус: окно вычисления является плавающим, особенно если мы говорим о месяцах. В случае использования календарного окна бюджет ошибок обнуляется с началом нового периода, но крупный инцидент в начале периода может потратить весь бюджет ошибок, и ждать его восстановления придется до начала следующего периода. И выводы о надежности сервиса можно делать только по истечении периода.

* *Rolling time window* или *за предшествующий период* — окно вычисления выражается в фиксированной продолжительности временного отрезка, например, за последние 30 дней. Плюсом этого подхода является то, что мы не привязываемся к календарю и всегда точно уверены в том, что показатели рассчитываются на одном и том же промежутке. Минус этого подхода в том, что его сложнее привязать к какому-то календарному периоду, поскольку бюджет ошибок восстанавливается с каждым пересчетом показателей.

В Monium используется способ **rolling time window**.

## Общие рекомендации {#howto}

Для начала необходимо определиться с отслеживаемыми показателями и временным окном.
 
Рассмотрим несколько базовых показателей, на основе которых можно сделать выводы о надежности сервиса:

1. **Availability** или **Доступность**. Измеряется на основе количественных метрик обработки запросов сервисом. События считаются, например, на основе HTTP- или gRPC-кодов ответов сервиса при обращении к его API. Является эквивалентом сигнала Errors, одного из четырех [золотых сигналов][golden-sgnals] в Google SRE Book.

    {% cut "Пример метрик Good Events" %}
        
    * Метрики на основе количества успешных ответов gRPC API алертинга Monium
        ```
        series_sum({project = '<имя_проекта>', cluster = '<имя_кластера>', service = 'gateway', host = '<имя_хоста>', sensor = 'grpc.server.call.status', clientId = 'total', endpoint = 'alerting_api_total', code != 'UNKNOWN|INTERNAL|DATA_LOSS|UNAVAILABLE|CANCELLED|DEADLINE_EXCEEDED|UNIMPLEMENTED|RESOURCE_EXHAUSTED'})
        ```
    * Метрики на основе количества успешных ответов HTTP API алертинга Monium
        ```
        series_sum({project = '<имя_проекта>', cluster = '<имя_кластера>', service = 'gateway', host = '<имя_хоста>', sensor = 'http.server.call.status', client_id = 'total', endpoint = 'alerting_api_total', code != '5??|429'})
        ```
    
    {% endcut %}

    {% cut "Пример метрик Total Events" %}
        
    * Метрики на основе общего количества ответов gRPC API алертинга Monium
        ```
        series_sum({project = '<имя_проекта>', cluster = '<имя_кластера>', service = 'gateway', host = '<имя_хоста>', sensor = 'grpc.server.call.status', clientId = 'total', endpoint = 'alerting_api_total'})
        ```
    * Метрики на основе общего количества ответов HTTP API алертинга Monium
        ```
        series_sum({project = '<имя_проекта>', cluster = '<имя_кластера>', service = 'gateway', host = '<имя_хоста>', sensor = 'http.server.call.status', client_id = 'total', endpoint = 'alerting_api_total'})
        ```
    
    {% endcut %}

1. **Latency** или **Время отклика**. Измеряется на основе количественных метрик времени обработки определенной операции сервисом. Является эквивалентом сигнала Latency, одного из четырех [золотых сигналов][golden-sgnals] в Google SRE Book.

    {% cut "Пример метрик Good Events" %}
        
    * Latency записи метрик при поставке через Push API — не более 2000 мс
        ```
        histogram_count(0, 2000, series_sum("bin", {project = "<имя_проекта>", cluster = "<имя_кластера>", service = "gateway", host = "<имя_хоста>", sensor = "http.server.call.elapsedTimeMs", endpoint = "/api/v2/push|/monitoring/v2/data/write", client_id = "total"}))
        ```

    {% endcut %}

     {% cut "Пример метрик Total Events" %}
        
    * Общее latency записи метрик при поставке через Push API 
        ```
        histogram_count(series_sum("bin", {project = "<имя_проекта>", cluster = "<имя_кластера>", service = "gateway", host = "<имя_хоста>", sensor = "http.server.call.elapsedTimeMs", endpoint = "/api/v2/push|/monitoring/v2/data/write", client_id = "total"}))
        ```

    {% endcut %}

1. **Saturation** или **Насыщение**. Измеряется на основе количественных метрик утилизации ресурсов сервисом. Является эквивалентом сигнала Saturation, одного из четырех [золотых сигналов][golden-sgnals] в Google SRE Book.

    {% cut "Пример метрик Good Events" %}
        
    * Метрики количества потоков для выбранного Deploy Stage
        ```
        {project = "<имя_проекта>", service = "<имя_сервиса>", cluster = "<имя_кластера>", name = "cpu.thread_count", host = "cluster", deploy.unit = "total", deploy.stage = "monitoring-ui-prod", deploy.box = "total", deploy.workload = "total"}
        ```

    {% endcut %}

     {% cut "Пример метрик Total Events" %}
        
    * Метрики лимита количества потоков для выбранного Deploy Stage
        ```
        {project = "<имя_проекта>", service = "<имя_сервиса>", cluster = "<имя_кластера>", name = "cpu.thread_limit", host = "<имя_хоста>", deploy.unit = "total", deploy.stage = "monitoring-ui-prod", deploy.box = "total", deploy.workload = "total"}
        ```

    {% endcut %}

Рекомендуется выбирать достаточно большое окно, например, 30 дней, чтобы исключить влияние пиковых нагрузок и провалов за короткий период, так как показатели будут менее шумными.

При расчете *Total Events* учитывайте только валидные события (например, запросы с корректным URL). Невалидные события не должны влиять на SLI.

{% note warning %}

При выборе метрик для расчета SLI обратите внимание на [TTL](../concepts/ttl.md). Значение TTL-метрик не должно быть меньше, чем выбранное окно вычисления показателей. Иначе нужные метрики могут быть удалены из хранилища из-за прекращения их поставки.

{% endnote %}

[golden-sgnals]: https://sre.google/sre-book/monitoring-distributed-systems/#xref_monitoring_golden-signals