Development
동적 Prometheus 쿼리 만들기 with golang(레이블 삽입하기)
토마스.dev
2023. 12. 27. 07:27
반응형
그라파나를 통해서 사용자에게 메트릭을 제공하려고 할때 가끔가다가 사용자별 테넌트 분리를 해야하는 경우가 있다.
또는 동적으로 변하는 특정 타겟별로 각 메트릭을 얻어오는 사이드카를 만들려고 할때 고정된 쿼리를 사용할수 없는 경우도 있다.
이럴 때는 base prometheus 쿼리를 기반으로 동적으로 레이블을 넣어줄 수 있다. 여기서는 golang client를 이용하는 방법을 설명한다.
package main
import (
"fmt"
"github.com/prometheus/prometheus/promql/parser"
)
// addLabelToQuery는 주어진 PromQL 쿼리에 새로운 레이블을 추가합니다.
func addLabelToQuery(query, labelName, labelValue string) (string, error) {
expr, err := parser.ParseExpr(query)
if err != nil {
return "", err
}
parser.Inspect(expr, func(node parser.Node, path []parser.Node) error {
switch n := node.(type) {
case *parser.VectorSelector:
n.LabelMatchers = append(n.LabelMatchers, &parser.LabelMatcher{
Type: parser.MatchEqual,
Name: labelName,
Value: labelValue,
})
}
return nil
})
return expr.String(), nil
}
func main() {
originalQuery := `sum(rate(http_requests_total[5m])) by (service)`
labelToAdd := "region"
labelValue := "us-west"
newQuery, err := addLabelToQuery(originalQuery, labelToAdd, labelValue)
if err != nil {
fmt.Println("Error modifying query:", err)
return
}
fmt.Println("Modified Query:", newQuery)
}
client 에 포함된 parser pkg를 사용한다.
parser 는 문자열로 인입된 쿼리를 파싱하여. 셀렉터(레이블) 노드 지점에 새로운 셀렉터를 추가한다.
셀렉터 외에도 다른 노드도 처리할 수 있다.
https://pkg.go.dev/github.com/prometheus/prometheus/promql/parser
위 예시코드의 결과는 다음과 같다.
sum(rate(http_requests_total{region="us-west"}[5m])) by (service)
리전이 동적으로 변해서 미래에 추가되거나 삭제될수 있는데, 리전별로 메트릭을 추출해 운영 자동화를 하고자할때 유용하게 사용할 수 있다.
반응형