메트릭 타입 수정자(Metric Type Modifiers)
메트릭 타입이란 메트릭이 무엇을 나타내려는지와 그것의 전송 소스를 가리키는 표식이에요. COUNT와 RATE 메트릭 타입은 시간에 따른 메트릭 값의 변화를 나타낸다는 점에서 서로 비슷하지만, 사용하는 로직이 달라요. 이 문서에서는 as_count()/as_rate() 같은 인앱 수정자를 활용해 메트릭 타입을 상황에 맞게 바꾸는 방법과, Datadog 내부에서 메트릭 타입을 변경하는 방법을 함께 살펴봐요.
출처: 문서
본문
메트릭 타입은 메트릭이 무엇을 나타내려는지와 그것의 전송 소스를 가리키는 표식이에요. COUNT와 RATE 메트릭 타입은 서로 상당히 비슷한데, 둘 다 시간에 따른 메트릭 값의 변화라는 같은 개념을 나타내기 때문이에요. 하지만 사용하는 로직은 달라요.
RATE: 시간에 따른 정규화된 값의 변화(초당).COUNT: 주어진 시간 간격에 따른 절대 값의 변화.
사용 사례와 제출 방법에 따라, 제출하기에 더 적합한 메트릭 타입이 달라질 수 있어요. 예를 들어:
| 제출할 메트릭 타입 | 사용 사례 |
|---|---|
RATE |
여러 호스트에 걸쳐 시간이 지남에 따라 수신된 요청 수를 모니터링하고 싶을 때. |
RATE |
소스들 간의 시간별 count 제출의 일관성을 제어할 수 없어서, 개별 간격별로 정규화해 상위 단계에서 비교할 수 있게 하고 싶을 때. |
COUNT |
함수가 호출된 횟수를 세고 싶을 때. |
COUNT |
주어진 시간 동안 발생한 매출액을 집계하고 싶을 때. |
RATE와 COUNT는 같은 메트릭 타입이 아니므로 Datadog 그래프와 모니터 안에서 동일한 동작이나 형태를 가지지 않아요. 그래프와 모니터 안에서 RATE와 COUNT 표현 사이를 즉석에서 바꾸려면 Datadog의 인앱 수정자(in-application modifier) 함수를 사용하면 돼요.
인앱 수정자
두 가지 주요 인앱 수정자는 as_count()와 as_rate()예요.
| 수정자 | 설명 |
|---|---|
as_count() |
주어진 메트릭을 COUNT 형태로 표시하는 데 필요한 연산을 설정해요. 롤업 간격 동안 메트릭 값의 절대 변화를 보여주죠. 참고: 롤업 간격에 의존하기 때문에, 더 긴 시간 간격을 그래프로 그리면 그래프 모양이 바뀔 수 있어요. |
as_rate() |
주어진 메트릭을 RATE 형태로 표시하는 데 필요한 연산을 설정해요. 초당 메트릭 값의 절대 변화를 보여주죠. |
적용한 메트릭 타입에 따라 동작이 달라져요.
{% tab title="COUNT" %}
as_count()의 효과:- 모든 보간(interpolation)을 비활성화해요.
- 시간 집계자를
SUM으로 설정해요.
as_rate()의 효과:- 모든 보간을 비활성화해요.
- 시간 집계자를
SUM으로 설정해요. - 정규화를 위해 집계 후 결과를 샘플링 간격으로 나눠요. 예를 들어 매 초 제출되는 다음 포인트
[1,1,1,1].as_rate()는 20초 롤업 간격에서[0.05, 0.05, 0.05, 0.05]를 만들어요.
참고: 아주 작은 간격(시간 집계가 발생하지 않을 때)에는 정규화가 없어서 원시 메트릭 값 count가 반환돼요. {% /tab %}
{% tab title="RATE" %}
-
as_count()의 효과:- 모든 보간을 비활성화해요.
- 시간 집계자를 SUM으로 설정해요.
- 집계 후 결과에 샘플링 간격을 곱해요. 예를 들어 매 초 제출되는 다음 포인트
[0.05, 0.05, 0.05, 0.05].as_count()는 20초 롤업 간격에서[1,1,1,1]을 만들어요.
-
as_rate()의 효과:- 모든 보간을 비활성화해요.
- 시간 집계자를
SUM으로 설정해요. - 쿼리 롤업 간격을 메트릭의 메타데이터 간격으로 내림(floor)해요. 메트릭의 제출 간격보다 작은 롤업 간격으로 요청된 쿼리는 메타데이터 간격과 일치하도록 자동으로 올려져요.
- 집계 후 각 완전한 버킷을
min(metadata_interval, rollup_interval) / rollup_interval로 재조정해요. 롤업 간격이 메타데이터 간격과 같으면 이 연산은 아무것도 하지 않고(no-op), 버킷 값은 집계 후SUM과 같아져요. 롤업 간격이 메타데이터 간격보다 크면 그 값은 해당 버킷의per-secondrate 샘플들의 시간 평균이 돼요. 예를 들어 매60초제출되는 메트릭을1800초롤업 간격으로 조회하면as_rate()는 각 완전한 버킷에 대해post_aggregation / 30을 반환해요. - (쿼리 종료 시간이 롤업 경계와 정렬되지 않을 때) 가장 오른쪽의 부분 버킷을 재조정해서, 인위적으로 낮은 값 대신 해당 부분 창에서 실제로 관찰된 샘플들의 평균을 나타내도록 해요.
참고: RATE 메트릭에 메타데이터 간격이 설정되어 있지 않으면 위의 재조정 단계가 하나도 적용되지 않고, 시간 집계자가 SUM 대신 AVG로 대체돼요.
참고: 예를 들어 이를 검증할 때 고급 그래프 작성에서 공식 (post_aggregation / rollup_interval) * min(metadata_interval, rollup_interval)을 사용하세요. 이 표현식은 활성 롤업 간격을 숫자 값으로 의존하므로 기본 타임시리즈 쿼리 위젯에서는 직접 그릴 수 없어요.
{% /tab %}
{% tab title="GAUGE" %}
GAUGE 메트릭 타입은 메트릭의 절대적이면서 최종적인 값을 나타내요. as_count()와 as_rate() 수정자는 gauge가 Metrics Explorer에서 저장되거나 표시되는 방식에 영향을 주지 않아요.
참고: 모니터에서 gauge 메트릭에 as_count()를 적용하면 pct_change() 같은 롤업 의존 함수의 평가 경로가 바뀌어요.
as_count()없이: 함수가 버킷별로 적용되고 그 값들이 평가 창에 걸쳐 합산돼요. 이로 인해 희소한(sparse) gauge에서 큰 음수 값이 생길 수 있어요.as_count()포함: 함수가 적용되기 전에 타임시리즈가 버킷화되고 집계되어, 의도한 창 수준 계산과 일치해요.
{% /tab %}
weighted() 수정자
pod name이나 container_name 같은 태그는 매우 높은 태그 변동(tag churn)을 유발해요. 특히 컨테이너화된 애플리케이션의 비용 관리, 용량 계획, 자동 확장용 쿼리를 만들 때 더 그렇죠. 태그 변동과 무관하게 gauge에 대한 쿼리의 수학적 정확성을 보장하려면 .weighted() 인앱 수정자를 사용할 수 있어요. .weighted() 수정자는 Datadog이 이렇게 자주 변동하는 태그의 수명을 기반으로 메트릭 값을 제대로 가중치 처리할 수 있게 해줘요.
.weighted() 수정자는 다음 두 조건이 모두 충족될 때만 gauge에 대한 쿼리에 자동으로 추가돼요.
- gauge 메트릭이 규칙적으로 제출되어 간격 사이에 보간이 없을 때.
- 제출 간격이 올바르게 정의되고 설정되어 있을 때.
Datadog Agent 또는 통합이 수집 시점에 메트릭의 제출 간격을 설정해요. Metrics Summary 페이지에서 제출 간격을 수정할 수 있어요.
Datadog 내부에서 메트릭 타입 수정하기
보통 필요하진 않지만, Metrics Summary 페이지에서 메트릭의 타입을 변경할 수는 있어요.
{% image source="https://docs.dd-static.net/images/metrics/custom_metrics/type_modifiers/metric_type.a5bd20e36e39f5ac9ccd26ec822dd315.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/metrics/custom_metrics/type_modifiers/metric_type.a5bd20e36e39f5ac9ccd26ec822dd315.png?auto=format&fit=max&w=850&dpr=2 2x" alt="Metric Type" /%}
연습용 사용 사례:
-
서비스된 요청 수를 세는 메트릭
app.requests.served가 있는데, 실수로 StatsD에서GAUGE로 제출했다고 가정해 볼게요. 그러면 이 메트릭의 Datadog 타입은GAUGE예요. -
app.requests.served를 시간 집계를 위해 StatsDCOUNT메트릭으로 제출하고 싶었다고 가정해 볼게요. 그러면sum:app.requests.served{*}같은 쿼리로 "지난 하루 동안 총 몇 개의 요청이 서비스되었나?" 같은 질문에 답할 수 있어요(GAUGE메트릭 타입에서는 말이 안 되는 쿼리죠). -
app.requests.served라는 이름이 마음에 든다면, 더 적절한COUNT타입으로 새 메트릭 이름을 제출하는 대신app.requests.served의 타입을 변경할 수 있어요.
- 제출 코드를 수정하고 N개의 요청이 서비스된 후
dogstatsd.increment('app.requests.served', N)을 호출하고, - 메트릭 요약 페이지에서 Datadog 인앱 타입을
RATE로 변경하세요.
이렇게 하면 app.requests.served의 타입 변경 전에 제출된 데이터는 잘못 동작해요. 인앱 GAUGE(RATE가 아닌)로 해석되도록 저장된 형식이기 때문이에요. 3단계 이후에 제출된 데이터는 올바르게 해석돼요.
GAUGE로 제출된 과거 데이터를 잃고 싶지 않다면, 새로운 타입으로 새 메트릭 이름을 만들고 app.requests.served의 타입은 그대로 두는 방식을 선택하세요.
참고: AgentCheck에서 self.increment는 단조 증가하는 카운터의 델타를 계산하지 않고, 체크 실행 시점에 전달된 값을 그대로 보고해요. 단조 증가하는 카운터의 델타 값을 보내려면 self.monotonic_count를 사용하세요.