PromQL 에는 SQL 의 GROUP BY 에 해당하는 독립된 구문이 없다. 집계 연산자에 by 또는 without 절을 붙여 어떤 라벨을 남길지 정하는 방식이다. 결과 시계열의 라벨 집합이 곧 그룹 키가 되고, 그 라벨이 Grafana 범례에 그대로 쓰인다.
sum(node_cpu_seconds_total) by (instance)
by 에 적은 라벨만 남기고 나머지는 버린 뒤, 같은 라벨 조합끼리 합친다. 반대로 without 은 적은 라벨만 버리고 나머지를 모두 남긴다.
sum(rate(node_cpu_seconds_total[5m])) without (cpu)
by 와 without 은 함께 쓸 수 없다. 남길 라벨이 적으면 by, 버릴 라벨이 적으면 without 이 읽기 쉽다. without 은 나중에 새 라벨이 추가돼도 자동으로 살아남는다는 장점이 있다.
집계 연산자는 sum · avg · min · max · count · stddev · stdvar · topk · bottomk · count_values · quantile · group 이 있다.
카운터에는 반드시 rate 를 먼저 걸고 그 결과를 집계한다. 순서를 바꾸면 값이 틀린다.
sum(rate(http_requests_total[5m])) by (status)
rate(sum(...)) 는 잘못된 형태다. 카운터가 재시작하면 값이 0 으로 떨어지는데, 먼저 합쳐 버리면 그 하락을 개별 시계열의 재시작으로 인식하지 못해 음수나 이상한 값이 나온다. rate 는 개별 시계열마다 재시작을 보정하도록 만들어졌다.
CPU 사용률은 idle 시간을 빼서 구한다.
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
메모리 사용률.
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
상위 N 개만 보기.
topk(5, sum(rate(container_cpu_usage_seconds_total[5m])) by (pod))
topk 는 by 를 함께 쓰면 그룹마다 상위 N 개를 고른다. 전체에서 상위 N 개를 원하면 위처럼 집계를 먼저 끝낸 뒤 감싼다.
이항 연산은 라벨 집합이 완전히 같은 시계열끼리만 짝을 짓는다. 한쪽에만 있는 라벨 때문에 결과가 비는 일이 흔하다.
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
양쪽을 같은 by 로 맞추면 대부분 해결된다. 그래도 라벨이 어긋나면 on 과 ignoring 으로 짝짓기 기준을 지정한다.
sum(rate(a_total[5m])) by (instance, job)
/ on (instance) group_left
sum(rate(b_total[5m])) by (instance)
범례 형식(Legend format) 칸에 중괄호 두 겹으로 라벨을 넣으면 그 값이 치환된다.
{{namespace}} / {{pod}}
범례에 쓸 수 있는 것은 쿼리 결과에 남아 있는 라벨뿐이다. by 로 버린 라벨은 범례에 나오지 않는다. 범례에 보이고 싶은 라벨은 집계할 때 남겨야 한다.
대시보드 변수는 앞에 달러 기호를 붙여 참조하지만, 이것은 선택된 값 자체이지 시계열의 라벨이 아니다. 시계열마다 다른 값을 보이려면 반드시 중괄호 표기를 쓴다.
라벨 이름을 바꿔 보이고 싶으면 쿼리에서 만들어 둔다.
label_replace(
sum(rate(http_requests_total[5m])) by (instance),
"host", "$1", "instance", "([^:]+):.*"
)
by () 처럼 빈 괄호를 주면 모든 라벨을 버리고 하나의 시계열로 합친다. 의도한 것이 아니라면 라벨을 적는다.avg 로 노드별 평균을 내면 노드 수가 다를 때 오해하기 쉽다. 합계와 개수를 따로 보는 편이 안전한 경우가 많다.