프로메테우스 공식 레퍼런스를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.
목차
Binary operators
프로메테우스의 쿼리 언어는 기본적인 논리 연산자와 산술 연산자를 지원한다. 두 개 instant 벡터를 연산할 땐 매칭 동작을 수정할 수 있다.
Arithmetic binary operators
프로메테우스에는 다음과 같은 이진 산술 연산자가 존재한다:
+
(더하기)-
(뻬기)*
(곱하기)/
(나누기)%
(나머지)^
(거듭제곱/지수)
이진 산술 연산자는 스칼라/스칼라, 벡터/스칼라, 벡터/벡터 값 사이에 정의한다.
두 스칼라 사이에 있을 때의 동작은 명확하다. 두 개의 스칼라 피연산자에 연산자를 적용한 결과는 또 다른 스칼라로 평가한다.
instant 벡터와 스칼라 사이에 있을 땐 벡터 안에 있는 모든 데이터 샘플 값에 연산자를 적용한다. 예를 들어서 시계열 instant 벡터에 2를 곱한 결과는, 기존 벡터에 있는 모든 샘플 값에 2를 곱한 값을 가지고 있는 또 다른 벡터다. 이때 메트릭 이름은 버려진다.
이진 산술 연산자가 두 개의 instant 벡터 사이에 있을 때는, 왼쪽에 있는 벡터의 각 항목을 기준으로 오른쪽 벡터에서 매칭되는 요소에 연산자를 적용한다. 연산 결과로는 배합한 레이블 셋을 가지는 벡터가 만들어진다. 메트릭 이름은 버려진다. 오른쪽에 있는 벡터에서 매칭되는 항목을 찾을 수 없는 항목은 결과에 포함되지 않는다.
Trigonometric binary operators
프로메테우스에는 다음과 같이 라디안으로 동작하는 삼각 이항 연산자가 존재한다:
atan2
(https://pkg.go.dev/math#Atan2 기반)
삼각 연산자를 사용하면 일반 함수에서는 사용할 수 없는 벡터 매칭을 사용해 두 벡터에서 삼각 함수를 실행할 수 있다. 동작 방식은 산술 연산자와 동일하다.
Comparison binary operators
프로메테우스에는 다음과 같은 이진 비교 연산자가 존재한다:
==
(equal)!=
(not-equal)>
(greater-than)<
(less-than)>=
(greater-or-equal)<=
(less-or-equal)
비교 연산자는 스칼라/스칼라, 벡터/스칼라, 벡터/벡터 값 사이에 정의한다. 기본적으로는 필터링으로 동작한다. 연산자 뒤에 bool
을 제공하면 값을 필터링하는 대신 0
이나 1
을 반환하는 식으로 연산자의 동작을 수정할 수 있다.
두 스칼라 사이에 사용할 땐 bool
modifier를 반드시 제공해야 하며, 이때 연산자는 비교 결과에 따라 0
(false
) 또는 1
(true
)을 값으로 가지는 다른 스칼라를 생성한다.
instant 벡터와 스칼라 사이에 있을 때는 벡터에 있는 모든 데이터 샘플 값에 연산자를 적용하며, 비교 결과가 false
인 벡터 요소는 결과 벡터에서 제거된다. bool
modifier를 제공하면 제거 대상인 벡터 요소는 삭제하는 대신에 0
을, 유지 대상인 벡터 요소는 1
을 값으로 갖는다. bool
modifier를 제공했을 땐 메트릭 이름은 버려진다.
이 연산자가 두 개의 instant 벡터 사이에 있을 때는, 기본적으론 일치하는 항목만 남기는 필터로 동작한다. 표현식이 true가 아니거나 양쪽에서 일치하는 항목을 찾지 못한 벡터 요소는 결과에서 제거되고, 그외 나머지 요소가 배합한 레이블 셋과 함께 결과 벡터에 담긴다. bool
modifier를 제공하면 제거 대상인 벡터 요소는 삭제하는 대신에 0
을, 유지 대상인 벡터 요소는 1
을 값으로 가지며, 이번에도 배합한 레이블 셋과 함께 담긴다. bool
modifier를 제공했을 땐 메트릭 이름은 버려진다.
Logical/set binary operators
아래 있는 논리/집합 이항 연산자들은 instant 벡터 사이에만 정의할 수 있다:
and
(교집합)or
(합집합)unless
(여집합)
vector1 and vector2
의 결과로 만들어지는 벡터는 vector1
요소 중에, vector2
에 정확히 일치하는 레이블 셋을 가진 요소들로만 구성된다. 그외 다른 요소들은 버려진다. 메트릭 이름과 값들은 왼쪽 벡터에서 넘어온다.
vector1 or vector2
의 결과로 만들어지는 벡터는 vector1
에 있는 기존 모든 요소들을 가지고 있으며 (레이블 셋 + 값), 여기에 추가로 vector1
의 레이블 셋과 일치하지 않는 vector2
의 모든 요소들도 포함시킨다.
vector1 unless vector2
의 결과로 만들어지는 벡터는 vector1
요소 중에, vector2
에 정확히 일치하는 레이블 셋을 가지고 있지 않은 요소들로만 구성된다. 두 벡터에서 일치하는 요소들은 전부 버려진다.
Vector matching
두 벡터를 연산할 땐 왼편에 있는 벡터를 기준으로 각 항목마다 오른쪽 벡터에서 일치하는 요소가 있는지 찾아본다. 매칭 동작에는 One-to-one과 many-to-one/one-to-many라는 두 가지 기본 타입이 있다.
One-to-one vector matches
One-to-one은 연산자 양 쪽에 있는 벡터에서 고유한 항목 쌍을 찾아본다. vector1 <operator> vector2
형식을 사용했을 때 디폴트로 실행되는 타입이다. 두 항목이 정확히 동일한 레이블 셋과 그에 따른 값을 가지고 있으면 일치한다고 판정한다. ignoring
키워드를 사용하면 특정 레이블을 비교 대상에서 제외할 수 있으며, on
키워드로 레이블 셋을 제공하면 비교할 대상을 한정시킬 수 있다.
<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>
데이터 예시:
method_code:http_errors:rate5m{method="get", code="500"} 24
method_code:http_errors:rate5m{method="get", code="404"} 30
method_code:http_errors:rate5m{method="put", code="501"} 3
method_code:http_errors:rate5m{method="post", code="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21
method:http_requests:rate5m{method="get"} 600
method:http_requests:rate5m{method="del"} 34
method:http_requests:rate5m{method="post"} 120
쿼리 예시:
method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
이 쿼리는 지난 5분 동안 측정한 HTTP 요청에서 각 메소드별로 상태 코드 500을 가지는 요청의 비율을 벡터로 반환한다. 두 메트릭은 가지고 있는 레이블 셋이 다르기 때문에 ignoring(code)
가 없었다면 일치하는 항목을 찾을 수 없다. put
과 del
메소드를 가지고 있는 항목들은 서로 일치하지 않기 때문에 결과에 표시되지 않는다:
{method="get"} 0.04 // 24 / 600
{method="post"} 0.05 // 6 / 120
Many-to-one and one-to-many vector matches
Many-to-one과 one-to-many 매칭에선 “one” 측에 있는 각 벡터 요소를 “many” 측의 여러 요소와 일치한다고 판정할 수 있다. 이때는 group_left
나 group_right
modifier를 명시해서 요청해야 하며, left/right는 어떤 벡터가 카디널리티가 더 높은지로 결정한다.
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
group modifier와 함께 제공하는 레이블 목록에는 결과 메트릭에 함께 포함시킬 “one” 쪽의 부가 레이블을 지정한다. on
키워드를 사용한다면 on 절이나 group절 중 하나에만 레이블 목록을 지정할 수 있다. 결과 벡터에 있는 모든 시계열은 반드시 고유하게 식별할 수 있어야 한다.
group modifier는 비교 연산자와 산술 연산자에만 사용할 수 있다. and
, unless
, or
연산에선 기본적으로 오른쪽 벡터에 있는 가능한 항목을 전부 매칭한다.
데이터 예시:
method_code:http_errors:rate5m{method="get", code="500"} 24
method_code:http_errors:rate5m{method="get", code="404"} 30
method_code:http_errors:rate5m{method="put", code="501"} 3
method_code:http_errors:rate5m{method="post", code="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21
method:http_requests:rate5m{method="get"} 600
method:http_requests:rate5m{method="del"} 34
method:http_requests:rate5m{method="post"} 120
쿼리 예시:
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
이 예시에서 왼쪽 벡터는 같은 method
레이블을 가지는 항목을 둘 이상 가지고 있다. 따라서 group_left
를 사용해 여러 항목을 다 매칭시키겠다는 것을 표현한다. 이제 오른쪽 벡터에 있는 요소는, 왼쪽 벡터와 같은 method
레이블을 가진 여러 요소와 일치한다고 판정한다:
{method="get", code="500"} 0.04 // 24 / 600
{method="get", code="404"} 0.05 // 30 / 600
{method="post", code="500"} 0.05 // 6 / 120
{method="post", code="404"} 0.175 // 21 / 120
Many-to-one과 one-to-many 매칭은 상급자용으로, 사용할 땐 신중하게 고려해봐야 한다. 보통은 ignoring(<labels>)
를 적절히 사용해주면 원하는 결과를 얻을 수 있을 거다.
Aggregation operators
프로메테우스는 다음과 같은 집계 연산자를 내장하고 있어서 단일 instant 벡터의 요소들을 집계할 수 있다. 결과로 만들어지는 새 벡터는 집계된 값을 가지기 때문에, 더 적은 요소들로 구성된다:
sum
(차원들의 합계를 계산한다)min
(차원들에서 최소값을 선택한다)max
(차원들에서 최대값을 선택한다)avg
(차원들의 평균을 계산한다)group
(모든 값을 1로 가지고 있는 벡터를 만든다)stddev
(차원들의 모표준편차를 계산한다)stdvar
(차원들의 모분산을 계산한다)count
(벡터에 있는 요수의 갯수를 센다)count_values
(같은 값을 가지고 있는 요소들의 갯수를 센다)bottomk
(샘플 값이 가장 작은 요소 k개)topk
(샘플 값이 가장 큰 요소 k개)quantile
(차원들의 φ-quantile (0 ≤ φ ≤ 1)을 계산한다)
이 연산자들을 사용하면 레이블 차원dimension을 전부 하나로 집계할 수도 있고, without
이나 by
절을 추가해서 특유의 차원을 보존할 수도 있다. without
, by
절은 표현식 앞이나 뒤에 사용할 수 있다.
<aggr-op> [without|by (<label list>)] ([parameter,] <vector expression>)
또는
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
label list
는 레이블 목록으로, 따옴표로 감싸지 않으며, 맨 뒤에 콤마가 있어도 된다. 즉, (label1, label2)
와 (label1, label2,)
는 모두 유효한 구문이다.
without
은 결과로 만드는 벡터에서 지정한 레이블들은 제외하고, 그외 다른 레이블은 모두 보존한다. by
는 정반대로, 나열하지 않은 레이블을 버린다. 벡터에 있는 모든 요소에서 레이블 값이 동일하더라도 마찬가지다.
parameter
는 count_values
, quantile
, topk
, bottomk
에서만 필요하다.
count_values
는 고유한 샘플 값마다 시계열을 하나씩 출력한다. 각 시계열마다 별도의 레이블을 가진다. 이 레이블의 이름은 집계 파라미터로 지정하며, 레이블 값이 바로 고유한 샘플 값이다. 각 시계열의 값에는 이 샘플 값이 몇 번 있었는지를 저장한다.
topk
와 bottomk
는 입력 샘플의 하위 셋을 원래 레이블과 함께 그대로 벡터로 반환한다는 점에서 다른 집계 연산자와는 다르다. by
와 without
은 입력 벡터를 버킷에 담는 용도로만 사용한다.
quantile
은 φ-quantile을 계산한다. φ-quantile은 차원들에서 집계한 N개의 메트릭 값 중에 φ*N번째 순위에 있는 값을 의미한다. φ는 집계 파라미터로 지정한다. 예를 들어 quantile(0.5, ...)
는 중앙값median을, quantile(0.95, ...)
는 95번째 백분위수percentile를 계산한다.
예시:
http_requests_total
메트릭에 있는 시계열들이 application
, instance
, group
레이블로 갈라진다면, 모든 인스턴스에서 애플리케이션과 그룹 단위로 들어온 총 HTTP 요청 수는 다음을 통해 계산할 수 있다:
sum without (instance) (http_requests_total)
아래 쿼리도 동일하다:
sum by (application, group) (http_requests_total)
모든 애플리케이션에 HTTP 요청이 총 몇 번 들어왔는지만 관심이 있다면, 간단하게 다음과 같이 작성하면 된다:
sum(http_requests_total)
각 빌드 버전마다 실행 중인 바이너리 수를 계산할 땐 다음과 같이 작성할 수 있다:
count_values("version", build_version)
모든 인스턴스에서 HTTP 요청 수가 가장 많은 5개를 조회할 땐 다음과 같이 작성할 수 있다:
topk(5, http_requests_total)
Binary operator precedence
다음은 프로메테우스의 이항 연산자를 우선 순위가 가장 높은 것부터 낮은 순으로 나타낸 목록이다:
^
*
,/
,%
,atan2
+
,-
==
,!=
,<=
,<
,>=
,>
and
,unless
or
연산자의 우선 순위가 같을 땐 왼쪽에 있는 연산을 먼저 실행한다. 예를 들어 2 * 3 % 2
는 (2 * 3) % 2
와 동일하다. 단, ^
은 오른쪽 연산을 먼저 실행하는데, 따라서 2 ^ 3 ^ 2
는 2 ^ (3 ^ 2)
와 동일하다.
Next :Functions
프로메테우스 함수 가이드
전체 목차는 여기에 있습니다.