PROMQL: как добавить значения, когда данные не возвращаются?

#prometheus #promql

#prometheus #promql

Вопрос:

У меня есть модель данных, в которой некоторые показатели распределяются по именам по имени клиента, среды и развертывания. Я заинтересован в создании сводки по каждому развертыванию, где эта сводка основана на количестве предупреждений, которые присутствуют для каждого развертывания.

Я могу получить развертывания в dev средах , uat , и prod , используя этот запрос:

 group by(tenant, environment, deployment)(up{environment=~"dev|uat|prod"}) - 1

# returns the following by way of example:
{deployment="default",environment="dev",tenant="tenant1"}   0
{deployment="default",environment="prod",tenant="tenant3"}  0
{deployment="default",environment="prod",tenant="tenant2"}  0
{deployment="default",environment="uat",tenant="tenant1"}   0
  

Итак, мы видим, что у клиента 1 есть 2 развертывания в 2 разных средах, тогда как у других 2 есть только одно. group by возвращает значение 1, поэтому мы вычитаем 1, чтобы получить 0 для каждого развертывания, и теперь я хочу добавить к этому количество предупреждений, применимых к каждому развертыванию.

Чтобы получать оповещения, я делаю это:

 ALERTS{severity="warning"}
# returns something like this when there is an alert, the details in the alert will vary, but will always have the `tenant`, `environment` and `deployment` labels
ALERTS{alertname="HostSystemdServiceCrashed",alertstate="firing",instance="example",job="node",deployment="default",environment="dev",tenant="tenant1",name="example.service",severity="warning",state="failed",type="oneshot"} 1

# however, when there are no alerts, I get "no data" returned
  

Я не могу понять, как добавлять оповещения к развертываниям, сохраняя при этом развертывания, для которых не было возвращено оповещений:

 (group by(tenant, environment, deployment)(up{environment=~"dev|uat|prod"}) -1)    on(tenant, environment, deployment) (ALERTS{severity="warning"})

# returns only data for the deployment for which there is an alert
{deployment="default",environment="dev",tenant="tenant1"} 1

# if there are no alerts, I get no data returned at all
  

В качестве вывода я хочу следующее:

 {deployment="default",environment="dev",tenant="tenant1"} 1
{deployment="default",environment="uat",tenant="tenant1"} 0
{deployment="default",environment="prod",tenant="tenant2"} 0
{deployment="default",environment="prod",tenant="tenant3"} 0
  

Как я могу этого добиться?

ПРИМЕЧАНИЕ:

Если я использую sum with or , то я получаю это, в зависимости от порядка аргументов в or :

 (group by(tenant, environment, deployment)(up{environment=~"dev|uat|prod"}) -1)  or sum by (tenant, environment, deployment) (ALERTS{severity="warning"} )

# returns this, note the value in `tenant1|dev|default`
{deployment="default",environment="dev",tenant="tenant1"} 0
{deployment="default",environment="uat",tenant="tenant1"} 0
{deployment="default",environment="prod",tenant="tenant2"} 0
{deployment="default",environment="prod",tenant="tenant3"} 0
  

Если я поменяю порядок параметров на or , я получу то, что мне нужно:

 {deployment="default",environment="dev",tenant="tenant1"} 1
{deployment="default",environment="uat",tenant="tenant1"} 0
{deployment="default",environment="prod",tenant="tenant2"} 0
{deployment="default",environment="prod",tenant="tenant3"} 0
  

Но теперь я застрял, если хочу сделать что-то вроде применения веса к предупреждениям другого уровня серьезности, например (псевдокод):

 summary = 0   sum(warning alerts)   2*sum(alerts(critical alerts))
  

Это дает тот же ряд с одним значением или нет данных, если нет предупреждений.

Ответ №1:

Я уверен, что есть правильный способ сделать это, но в конце концов я label_replace добавлял произвольную метку ключ-значение к каждому вложенному запросу, который я хотел добавить к исходным значениям, а затем применял or к каждому. Это привело к объединению рядов без перезаписи каких-либо значений. Затем я смог выполнить окончательную sum by обработку результирующего ряда, чтобы свести результаты к одному результату, отбросив в процессе специальные метки.

 sum(
  (group by(tenant, environment, deployment) (up{environment=~"dev|uat|prod"} ) -1) 

  or label_replace((sum (ALERTS{severity="warning"} ) by (tenant, environment, deployment)), "severity", "warning", "", "") or 

  2 * label_replace((sum (ALERTS{severity="critical"} )  by (tenant, environment, deployment)), "severity", "critical", "", "")
) by (tenant, environment, deployment)