eventstats 명령

eventstats 명령

eventstats 명령은 계산된 요약 통계로 이벤트 데이터를 풍부하게 만들어요. 이벤트 내 지정된 필드를 분석하고 다양한 통계 측정을 계산한 다음, 이 결과를 각 원본 이벤트에 새 필드로 추가해요. eventstats 명령은 전체 검색 결과 또는 정의된 그룹 내에서 계산을 수행하고, 원본 이벤트를 유지한 채 새 필드를 추가해요. 특히 비교 분석, 이상치 식별, 개별 이벤트에 추가 컨텍스트 제공에 유용해요.

출처: 문서

본문

stats 명령 비교하기

stats, eventstats, streamstats 명령의 변환 동작, 출력 형식, 집계 범위, 사용 사례 차이를 포괄적으로 비교하려면 Comparing stats, eventstats, and streamstats를 참조해요.

구문(Syntax)

eventstats 명령은 다음과 같은 구문을 가져요.

eventstats [bucket_nullable=bool] <function>... [by-clause]

eventstats 명령 구문의 예시는 다음과 같아요.

source = table | eventstats avg(a)
source = table | where a < 50 | eventstats count(c)
source = table | eventstats min(c), max(c) by b
source = table | eventstats count(c) as count_by by b | where count_by > 1000
source = table | eventstats dc(field) as distinct_count
source = table | eventstats distinct_count(category) by region

매개변수(Parameters)

eventstats 명령은 다음 매개변수를 지원해요.

Parameter Required/Optional Description
<function> Required 집계 함수 또는 창 함수.
bucket_nullable Optional eventstats 명령이 group-by 집계에서 null 버킷을 유효한 그룹으로 간주할지 제어해요. false로 설정하면 집계 중에 null group-by 값을 별개의 그룹으로 취급하지 않아요. 기본값은 plugins.ppl.syntax.legacy.preferred에 의해 결정돼요.
<by-clause> Optional 지정된 필드나 표현식으로 결과를 그룹화해요. 구문: by [span-expression,] [field,]... 기본값은 전체 검색 결과에 대해 집계해요.
<span-expression> Optional 필드를 간격으로 버킷으로 분할해요(최대 하나). 구문: span(field_expr, interval_expr). 예를 들어 span(age, 10)은 10년 단위 나이 버킷을 만들고, span(timestamp, 1h)는 시간 단위 버킷을 만들어요.

시간 단위(Time units)

span 표현식에는 다음과 같은 시간 단위를 사용할 수 있어요.

  • 밀리초(ms)
  • 초(s)
  • 분(m, 대소문자 구분)
  • 시간(h)
  • 일(d)
  • 주(w)
  • 월(M, 대소문자 구분)
  • 분기(q)
  • 년(y)

집계 함수(Aggregation functions)

eventstats 명령은 다음 집계 함수를 지원해요.

  • COUNT – 값 개수
  • SUM – 숫자 값의 합
  • AVG – 숫자 값의 평균
  • MAX – 최댓값
  • MIN – 최솟값
  • VAR_SAMP – 표본 분산
  • VAR_POP – 모집단 분산
  • STDDEV_SAMP – 표본 표준 편차
  • STDDEV_POP – 모집단 표준 편차
  • DISTINCT_COUNT/DC – 고유 값 개수
  • EARLIEST – 타임스탬프로 가장 이른 값
  • LATEST – 타임스탬프로 가장 최신 값

각 함수의 자세한 문서는 Functions를 참조해요.

예시 1: 서비스별 개수로 로그 풍부하게 만들기

다음 쿼리는 각 서비스의 총 로그 수를 모든 로그 항목에 추가하여, 개별 로그 상세와 함께 각 서비스가 얼마나 활발한지 보여줘요.

source=otellogs
| eventstats count() as service_total by `resource.attributes.service.name`
| where severityText = 'ERROR'
| sort `resource.attributes.service.name`
| fields severityText, `resource.attributes.service.name`, service_total, body
| head 3

이 쿼리는 다음과 같은 결과를 반환해요.

severityText resource.attributes.service.name service_total body
ERROR checkout 3 NullPointerException in CheckoutService.placeOrder at line 142
ERROR checkout 3 Kafka producer delivery failed: message too large for topic order-events (max 1048576 bytes)
ERROR frontend-proxy 3 [2024-02-01T09:20:00.456Z] “POST /api/checkout HTTP/1.1” 503 - 0 30000 checkout-8d4f7b-mk2p9

예시 2: 그룹별 심각도 통계 계산하기

다음 쿼리는 각 로그 항목에 서비스별 평균 심각도와 오류 수를 추가해요.

source=otellogs
| where severityText = 'ERROR'
| eventstats avg(severityNumber) as avg_sev, count() as error_count by `resource.attributes.service.name`
| sort `resource.attributes.service.name`
| fields `resource.attributes.service.name`, severityNumber, avg_sev, error_count

이 쿼리는 다음과 같은 결과를 반환해요.

resource.attributes.service.name severityNumber avg_sev error_count
checkout 17 17.0 2
checkout 17 17.0 2
frontend-proxy 17 17.0 1
payment 17 17.0 2
payment 17 17.0 2
product-catalog 17 17.0 1
recommendation 17 17.0 1

예시 3: Null 버킷 처리

다음 쿼리는 bucket_nullable=false를 사용해 group-by 집계에서 null 값을 제외해요.

source=otellogs
| eventstats bucket_nullable=false count() as scope_count by instrumentationScope.name
| where severityText = 'ERROR'
| sort `resource.attributes.service.name`
| fields `resource.attributes.service.name`, `instrumentationScope.name`, scope_count

이 쿼리는 다음과 같은 결과를 반환해요.

resource.attributes.service.name instrumentationScope.name scope_count
checkout null null
checkout null null
frontend-proxy null null
payment null null
payment @opentelemetry/instrumentation-http 2
product-catalog null null
recommendation null null

더 알아보기 (Learn more)