트레이스 기반 알림 예제

트레이스 기반 알림 예제 (Examples of trace-based alerts)

메트릭은 대부분의 알림 시스템의 기반이지만, 항상 실패가 어디서·왜 발생하는지는 알려주지 못해요. 트레이스는 요청이 시스템을 통과하는 전체 경로를 보여줘 그 공백을 메워요. 서비스 전체의 워크플로를 매핑해 요청이 어디에서 느려지거나 실패하는지 나타내요. 이 안내서는 Grafana에서 트레이스 기반 알림을 설정하는 두 가지 주요 접근법(트레이스 데이터에서 생성된 메트릭 쿼리, 그리고 TraceQL)의 입문 예제를 제공해요.

출처: 문서

본문

트레이스는 지속 시간과 오류를 특정 서비스·스팬에 직접 보고해서 영향을 받은 컴포넌트와 서비스 범위를 찾는 데 도움을 줘요. 이 추가 맥락으로 트레이스 데이터에 알림을 걸면 근본 원인을 더 빨리 찾을 수 있어요. 트레이스 데이터는 흔히 OpenTelemetry(OTel) 계측으로 수집돼요.

스팬 메트릭에 알림 걸기 (Alerting on span metrics)

OpenTelemetry는 트레이스 데이터를 Prometheus 스타일 메트릭으로 변환하는 프로세서를 제공해요. service graph와 span metrics 프로세서는 Alloy와 Tempo에서 표준 옵션으로, 샘플링된 스팬에서 RED(rate, error, duration) 메트릭을 생성해요. 그런 다음 트레이스에서 파생된 메트릭을 쿼리하는 알림 규칙을 만들 수 있어요.

  • service graph 메트릭은 서비스 간 통신과 의존성 상태에 초점을 맞춰요. 서비스 사이의 호출을 측정해 Grafana가 서비스 토폴로지를 추론하게 해요. 하지만 두 서비스 간의 상호작용만 측정하고 클라이언트 서비스의 내부 처리 시간은 포함하지 않아요. 네트워크 저하나 서비스 메시 문제 같은 인프라 이슈를 감지하는 데 써요.
  • span 메트릭은 서비스 요청의 총 처리 시간을 측정해 서비스 내부에서 무슨 일이 일어나는지 잡아내요. 내부 처리 시간과 다운스트림 호출 대기 시간을 포함해 엔드투엔드 서비스 성능을 보여줘요. 트레이스 기반 알림에는 span 메트릭을 쓰세요.

span 메트릭 생성 방식에 따라 다음 span 메트릭이 생성돼요:

스팬 메트릭 생성기 메트릭 이름 Prometheus 메트릭 유형 설명
Alloy 및 OTEL span metrics connector traces_span_metrics_calls_total Counter 스팬의 총 개수
traces_span_metrics_duration_seconds Histogram (네이티브 또는 클래식) 스팬의 지속 시간
Tempo 및 Grafana Cloud Application Observability traces_spanmetrics_calls_total Counter 스팬의 총 개수
traces_spanmetrics_latency Histogram (네이티브 또는 클래식) 스팬의 지속 시간
traces_spanmetrics_size_total Counter 수집된 스팬의 총 크기

각 메트릭은 기본적으로 service, span_name, span_kind, status_code, status_message, job, instance 라벨을 포함해요. 메트릭 생성기에서 히스토그램, exemplar, 메트릭 차원 등 옵션을 구성해 트레이스가 메트릭으로 변환되는 방식을 커스터마이즈할 수 있어요.

느린 스팬 작업 감지

서비스가 처리하는 작업이 느려질 때 감지하는 알림 규칙을 정의하는 예제예요. 트레이스 요소 몇 가지를 먼저 알아두면 도움이 돼요: 스팬은 서비스 내 특정 작업을, 서버 스팬은 요청 받는 쪽에서 수행된 작업을, 클라이언트 스팬은 응답을 기다리는 아웃바운드 호출(부모 스팬)을 나타내요.

특정 서비스의 느린 인바운드 작업을 감지하려면 서버 스팬의 백분위 지연 시간이 임계값을 초과할 때 알리는 규칙을 정의할 수 있어요. 예: "오류를 제외한 요청의 95%가 2초 안에 완료되지 않을 때 감지".

네이티브 히스토그램 사용

다음 PromQL은 traces_span_metrics_duration_seconds 네이티브 히스토그램 메트릭으로 알림 규칙 쿼리를 정의해요:

histogram_quantile(0.95,
 sum by (span_name) (
   rate(traces_span_metrics_duration_seconds{
     service_name="<SERVICE_NAME>",
     span_kind="SPAN_KIND_SERVER",
     status_code!="STATUS_CODE_ERROR"
   }[10m])
 )
) > 2

쿼리 분석:

  • traces_span_metrics_duration_seconds : Alloy나 OTEL collector로 스팬에서 생성된 네이티브 히스토그램. service_name="<SERVICE_NAME>"으로 특정 서비스 대상, span_kind="SPAN_KIND_SERVER"로 인바운드 요청 처리 스팬 선택, status_code!="STATUS_CODE_ERROR"로 오류로 끝난 스팬 제외. 다른 스팬 메트릭 생성기를 쓰면 traces_spanmetrics_latency를 쿼리해야 해요.
  • rate(...[10m]) : 히스토그램을 지난 10분간 초당 히스토그램으로 변환. 시간 창을 명시하고 histogram_* 함수로 지난 10분의 지연 시간을 계산할 수 있게 해요.
  • sum by (span_name)( ... ) : 같은 span_name을 공유하는 모든 시리즈를 병합. 스팬 이름(작업)마다 알림 인스턴스 하나를 생성하는 다차원 알림을 만들어요.
  • histogram_quantile(0.95, ...) : rate 적용 후 히스토그램에서 p95 지연 시간 계산. 이 쿼리는 instant Prometheus 쿼리로 실행돼 10분 창에 대한 단일 값을 반환해요.
  • > 2 : 임계값 조건. p95 지연 시간이 2초를 초과하는 시리즈만 반환해요. 이 임계값은 UI에서 Grafana Alerting 표현식으로도 설정할 수 있어요.

클래식 히스토그램 사용

네이티브 히스토그램은 Prometheus v3.8.0부터 안정적이에요. 스팬 메트릭 생성기가 지연 시간 스팬 메트릭(traces_span_metrics_duration_seconds 또는 traces_spanmetrics_latency)에 클래식 히스토그램을 만들 수도 있어요. 클래식 히스토그램은 고정 버킷을 가진 히스토그램으로 세 가지 메트릭(_bucket, _sum, _count)을 노출해요. 특히 임계값(예: 2s)을 초과하는지 정확히 계산하려면 명시적 버킷으로 클래식 히스토그램을 구성해야 해요:

["100ms", "250ms", "1s", "2s", "5s"]

otelcol.connector.spanmetrics는 explicit 블록으로 버킷을 구성할 수 있고, Tempo의 metric-generator는 span_metrics.histogram_buckets 설정으로 구성할 수 있어요. 클래식 히스토그램의 동등한 PromQL:

histogram_quantile(0.95,
 sum by (span_name, le) (
   rate(traces_span_metrics_duration_seconds_bucket{
     service_name="<SERVICE_NAME>",
     span_kind="SPAN_KIND_SERVER",
     status_code!="STATUS_CODE_ERROR"
   }[10m])
 )
) > 2

네이티브 히스토그램 예제와의 핵심 차이: 임계값(예: 2s)과 일치하는 히스토그램 버킷을 구성하고, 기본 메트릭이 아니라 _bucket 메트릭을 쿼리하며, sum by (...) 그룹화에 le를 포함해야 해요. 나머지는 동일해요.

Note 이 예제의 알림 규칙은 다차원 알림을 만들어요 — 스팬 이름마다 알림 인스턴스 하나씩. /product/1234 같은 동적 스팬 라우트는 고유 스팬마다 별도 메트릭 차원과 알림을 만들어 대량 볼륨에서 메트릭 비용과 성능에 큰 영향을 줄 수 있어요. 높은 카디널리티 데이터를 막으려면 http.route, url.template 같은 시맨틱 속성으로 /product/{id}처럼 동적 라우트를 정규화하고, service_name, status_code, http_method 같은 저카디널리티 필드로 차원을 제한하세요.

높은 오류율 감지

어떤 작업의 오류율이 20%를 초과하는지 감지하는 알림 규칙을 정의하는 예제 (5xx 응답 같은 요청 오류 증가 식별용). 다음 쿼리는 서비스·작업별 실패한 서버 스팬의 비율을 계산해요:

(
  sum by (service, span_name) (
    rate(traces_span_metrics_calls_total{
      span_kind="SPAN_KIND_SERVER",
      status_code="STATUS_CODE_ERROR"
    }[10m])
  )
/
  sum by (service, span_name) (
    rate(traces_span_metrics_calls_total{
      span_kind="SPAN_KIND_SERVER"
    }[10m])
  )
) > 0.2

쿼리 분석:

  • traces_span_metrics_calls_total : 스팬에서 생성된 카운터 메트릭으로 완료된 스팬 작업 수 추적. span_kind="SPAN_KIND_SERVER"로 인바운드 요청 스팬 선택, status_code="STATUS_CODE_ERROR"로 오류로 끝난 스팬만 선택. 분모에서 status_code 필터를 생략하면 모든 스팬을 포함해 총 스팬 수를 반환해요. 메트릭 생성기가 traces_spanmetrics_calls_total 메트릭을 만드는지 확인하고 메트릭 이름을 조정해요.
  • rate(...[10m]) : 카운터를 지난 10분간 초당 히스토그램으로 변환.
  • sum by (service, span_name)( ... ) : 서비스·작업별 집계로 각 (service, span_name) 조합마다 알림 인스턴스 하나 생성. 모든 서비스에 적용되는 다차원 알림으로 어떤 서비스의 어떤 작업이 실패하는지 식별하는 데 도움.
  • sum by () (...) / sum by () (...) : 실패한 스팬을 총 스팬으로 나눠 작업별 오류율 계산. 결과는 0~1 사이 비율로 1이면 모든 작업 실패. 이 쿼리는 instant Prometheus 쿼리로 실행돼 10분 창에 대한 단일 값을 반환.
  • > 0.2 : 오류율이 스팬의 20%보다 높은 시리즈만 반환하는 임계값 조건. 임계값을 UI의 Grafana Alerting 표현식으로도 설정할 수 있음.

트래픽 가드레일 활성화 (Enable traffic guardrails)

트래픽이 매우 적으면 단일 느리거나 실패한 요청도 알림을 발화시킬 수 있어요. 저트래픽 기간의 이런 거짓 긍정을 피하려면 알림 규칙 쿼리에 최소 트래픽 조건을 포함할 수 있어요. 예를 들어:

sum by (service, span_name)(
  increase(traces_span_metrics_calls_total{
    span_kind="SPAN_KIND_SERVER"
  }[10m])
) > 300

이 쿼리는 10분 기간에 300개 이상의 요청을 처리한 스팬만 반환해요. 이 최소 트래픽 수준은 거짓 긍정을 막고, 알림이 발화하기 전에 상당한 수의 스팬을 평가하게 해요. 이 트래픽 조건을 오류율 쿼리와 결합해 두 조건이 모두 충족될 때만 알림이 발화하게 할 수 있어요:

((
  sum by (service, span_name) (
    rate(traces_span_metrics_calls_total{
      span_kind="SPAN_KIND_SERVER",
      status_code="STATUS_CODE_ERROR"
    }[10m])
  )
/
  sum by (service, span_name) (
    rate(traces_span_metrics_calls_total{
      span_kind="SPAN_KIND_SERVER"
    }[10m])
  )
) > 0.2)
and
(
    sum by (service, span_name)(
    increase(traces_span_metrics_calls_total{
      span_kind="SPAN_KIND_SERVER"
    }[10m])
) > 300 )

주어진 스팬에 대해 다음과 같을 때 알림이 발화해요: 지난 10분간 오류율이 20%를 초과하고, 스팬이 지난 10분간 최소 300개의 요청을 처리했을 때. 또는 알림을 별도 쿼리로 나누고 math 표현식을 임계값으로 결합할 수도 있어요 (예: $ErrorRateCondition, $TrafficCondition). 이 경우 두 쿼리가 같은 라벨로 그룹화되도록 해야 해요. 이 방식의 장점은 두 독립 쿼리의 결과를 $values 변수로 접근해 알림이나 커스텀 라벨에 표시할 수 있다는 점이에요. 단점은 각 쿼리가 따로 실행돼 백엔드 부하가 늘고, 활성 알림이 많은 환경에서 쿼리 성능에 영향을 줄 수 있다는 점이에요.

샘플링 고려 (Consider sampling)

샘플링은 비용 절감을 위해 수집되는 스팬 양을 줄이는 기법이에요. 두 가지 주요 전략을 결합할 수 있어요:

  • Head sampling : 트레이스가 시작될 때 스팬을 기록할지 버릴지 결정. 확률적으로(트레이스의 일정 비율) 또는 특정 작업을 필터링해 구성할 수 있어요.
  • Tail sampling : 트레이스가 완료된 후 결정. 느리거나 실패한 요청 같이 더 흥미로운 작업을 샘플링할 수 있어요.

head sampling에서는 span 메트릭이 전체 트레이스의 부분집합만 나타내므로 span 메트릭 알림에 주의해야 해요. tail sampling에서는 샘플링 결정 전에 span 메트릭을 생성하는 것이 중요해요. Grafana Cloud Adaptive Traces가 이를 자동 처리해요. Alloy나 OpenTelemetry Collector에서는 SpanMetrics connector가 필터링·tail sampling 프로세서보다 먼저 실행되도록 하세요.

TraceQL 사용

TraceQL은 Grafana Tempo에서 트레이스를 검색·필터링하는 쿼리 언어로, PromQL과 LogQL과 비슷한 문법을 써요. TraceQL로 트레이스 데이터를 span 메트릭으로 변환하지 않고 원시 트레이스 데이터를 직접 쿼리할 수 있어요. 트레이스 구조, 속성, 리소스 메타데이터를 기반으로 더 유연하게 필터링하며, 메트릭 생성을 기다리지 않아 문제를 더 빨리 감지할 수 있어요.

하지만 TraceQL은 모든 시나리오에 적합하지 않아요:

  • 장기 분석에 부적합: 트레이스 데이터는 메트릭보다 보존 기간이 훨씬 짧아요. 히스토리 모니터링에는 핵심 트레이스 데이터를 메트릭으로 변환해 중요한 데이터를 보존하는 것이 좋아요.
  • 샘플링 후 알림에 부적합: TraceQL은 실제로 Tempo에 저장된 트레이스만 쿼리할 수 있어요. 샘플링이 많은 트레이스를 버리면 TraceQL 기반 알림이 실제 문제를 놓칠 수 있어요.

Caution TraceQL 알림은 Grafana v12.1 이상에서 사용 가능하며, private preview 기능으로 지원돼요. 엔지니어링·온콜 지원이 없고 SLA도 제공되지 않아요. 생산 환경에서는 아직 쓰지 말고 테스트·실험에 사용하세요.

다음 예제는 느린 스팬 작업을 감지하는 이전 알림 규칙을 TraceQL로 재현하는 방법을 보여줘요.

  • TraceQL 알림 활성화: Grafana 구성에서 tempoAlerting 피처 플래그를 활성화해야 해요. Grafana Cloud는 Support에 문의해 TraceQL 알림을 활성화하세요.
  • 알림 쿼리 구성: 알림 규칙에서 Tempo 데이터 소스를 선택하고, 원래 PromQL 쿼리를 동등한 TraceQL 쿼리로 변환해요:
{status != error && kind = server && .service.name = "<SERVICE_NAME>"}
| quantile_over_time(duration, .95) by (name)

주어진 서비스에 대해 오류를 제외한 모든 서버 스팬의 p95 지연 시간을 계산하고 스팬 이름으로 그룹화해요.

  • 시간 범위 구성: 현재 TraceQL 알림은 범위 쿼리만 지원해요. 시간 창을 지난 10분으로 설정해요. From: now-10m, To: now.
  • reducer 표현식 추가: 범위 쿼리는 단일 값이 아닌 시계열 데이터를 반환해요. 규칙은 임계값과 비교하기 전에 시계열을 단일 수치 값으로 축소해야 해요. Reduce 표현식을 추가해 쿼리 결과를 단일 값으로 변환해요.
  • 임계값 조건 설정: p95 지연 시간이 2초를 초과할 때 발화하는 Threshold 표현식을 만들어요: $B > 2.

최종 알림은 특정 서비스의 (오류 제외) 서버 스팬 95%가 span 메트릭 대신 원시 트레이스 데이터로 2초 이상 걸릴 때 감지해요.

더 알아보기 (Learn more)