Grafana 알림 설정 방법
목차
apiVersion: 1 # Grafana Alerting 설정 파일의 API 버전 (현재는 1이 표준)
groups: # 알림 규칙 그룹 목록
- orgId: 1 # 이 그룹이 속한 조직 ID (일반적으로 1)
name: 10s Evaluation Group # 알림 규칙 그룹 이름 (식별 용이성을 위해 설정 주기를 포함)
folder: alert # 규칙이 저장될 Grafana 폴더 이름 (대시보드 폴더와 연동됨)
interval: 10s # 이 그룹 내의 모든 규칙을 평가(Evaluation)하는 주기 (매우 짧은 주기로 설정)
rules: # 이 그룹에 포함된 개별 알림 규칙 목록
- uid: c72cd04e-d8f9-46d5-96f2-f8d908453338 # 규칙의 고유 ID (Grafana에서 자동 생성 또는 수동 지정)
title: CPU # 알림 규칙의 제목 (알림 발생 시 표시됨)
condition: C # 경보 상태를 결정하는 최종 데이터 쿼리/표현식의 RefID (여기서는 임계값 검증인 C)
data: # 규칙 평가에 사용되는 데이터 소스 쿼리 및 표현식 목록 (쿼리 A -> 표현식 B -> 임계값 C 순으로 처리)
# 1. ClickHouse 쿼리 (RefId: A)
- refId: A # 쿼리의 참조 ID
queryType: timeseries # 쿼리 유형 (시계열 데이터)
relativeTimeRange: # 쿼리할 데이터의 시간 범위 (현재 평가 시간 기준 상대적)
from: 300 # 현재 시간으로부터 300초(5분) 전
to: 0 # 현재 시간까지
datasourceUid: clickhouse # 데이터 소스 UID (ClickHouse 플러그인)
model: # 데이터 소스 쿼리 모델 상세 설정
datasource:
type: grafana-clickhouse-datasource
uid: clickhouse
editorType: sql # 쿼리 편집기 유형 (SQL)
format: 0
intervalMs: 300000 # 시계열 데이터의 최소 간격 (5분, 쿼리 내 bucket_s=10s와 다름, ClickHouse 쿼리 자체는 10초 버킷 사용)
maxDataPoints: 43200
meta:
builderOptions:
columns: []
database: ""
limit: 1000
mode: list
queryType: table
table: ""
pluginVersion: 4.7.0
queryType: timeseries
# ClickHouse SQL 쿼리 (Raw Query)
rawSql: "/* host.name 별 CPU 사용률(%) 시계열\r\n - value: (1 - avg(idle)) * 100\r\n - 그룹화: (t, host)\r\n*/\r\nWITH\r\n toDateTime($__fromTime) AS t_from,\r\n toDateTime($__toTime) AS t_to,\r\n 10 AS bucket_s,\r\n raw AS (\r\n SELECT\r\n toStartOfInterval(TimeUnix, toIntervalSecond(bucket_s)) AS t,\r\n TimeUnix AS ts,\r\n toString(multiIf(mapContains(ResourceAttributes, 'host.name'), ResourceAttributes['host.name'], mapContains(Attributes, 'host.name'), Attributes['host.name'], '')) AS host,\r\n toString(multiIf(mapContains(Attributes, 'state'), Attributes['state'], mapContains(ResourceAttributes, 'state'), ResourceAttributes['state'], '')) AS state,\r\n toFloat64(Value) AS v\r\n FROM otel_metrics_gauge\r\n PREWHERE TimeUnix BETWEEN t_from AND t_to\r\n WHERE MetricName = 'system.cpu.utilization'\r\n )\r\nSELECT\r\n t AS time,\r\n host,\r\n round((1 - avgIf(v, state = 'idle')) * 100, 1) AS cpu,\r\n formatDateTime(max(ts), '%Y-%m-%d %H:%i:%S', 'Asia/Seoul') AS occ_time\r\nFROM raw\r\nWHERE host != '' AND state != ''\r\nGROUP BY t, host\r\nORDER BY time ASC, host ASC;"
refId: A
# 2. 표현식 (RefId: B) - 쿼리 A의 결과를 집계
- refId: B # 표현식의 참조 ID
relativeTimeRange:
from: 300
to: 0
datasourceUid: __expr__ # Grafana 내장 표현식 엔진 사용
model:
conditions: # 이 표현식에서는 사용하지 않음 (대신 C에서 사용)
- evaluator:
params: []
type: gt
operator:
type: and
query:
params:
- B
reducer:
params: []
type: last
type: query
datasource:
type: __expr__
uid: __expr__
expression: A # 입력은 쿼리 A의 결과
intervalMs: 1000
maxDataPoints: 43200
reducer: last # A의 시계열 데이터 중 '가장 최근' 값만 가져옴 (호스트별 최신 CPU 사용률)
refId: B
settings:
mode: replaceNN # No-Data 처리 방식 (Null/NaN 값을 대체)
replaceWithValue: 0 # 대체 값 (0으로 설정하여 데이터가 없으면 0%로 간주)
type: reduce # 데이터 포인트를 단일 값으로 줄이는(Reduce) 표현식
# 3. 임계값 검증 (RefId: C) - 표현식 B의 결과에 임계값 적용
- refId: C # 임계값 표현식의 참조 ID (최종 경보 조건)
relativeTimeRange:
from: 300
to: 0
datasourceUid: __expr__
model:
conditions:
- evaluator: # 평가 조건
params:
- 70 # 임계값 (70%)
type: gt # Greater Than (초과)
operator:
type: and
query:
params:
- C
reducer:
params: []
type: last
type: query
datasource:
type: __expr__
uid: __expr__
expression: B # 입력은 표현식 B의 결과 (최신 CPU 사용률 값)
intervalMs: 1000
maxDataPoints: 43200
refId: C
type: threshold # 임계값을 적용하여 상태를 OK/Alerting으로 변경하는 표현식
dashboardUid: server-overview-tenant # 이 규칙이 참조하는 대시보드 UID
panelId: 112 # 이 규칙이 참조하는 대시보드 내 패널 ID
noDataState: OK # 쿼리 A에서 데이터가 없을 때의 상태 (OK로 설정하여 False Positive 방지)
execErrState: OK # 쿼리 실행 중 오류가 발생했을 때의 상태 (OK로 설정하여 False Positive 방지)
for: 0s # 경보 상태가 유지되어야 하는 최소 시간 (0s는 조건 충족 즉시 경보 발생)
annotations: # 알림 메시지에 포함될 추가 정보 (템플릿 변수 사용 가능)
__dashboardUid__: server-overview-tenant
__panelId__: "112"
description: |- # 알림 본문 (Markdown 형식)
---------------------------------------
서버 CPU 사용률이 임계치를 초과했습니다.
- 호스트: {{ $labels.host }} # 쿼리 A에서 추출된 레이블 (host)
- 발생 시간: {{ $labels.occ_time }} # 쿼리 A에서 추출된 레이블 (occ_time)
- 현재 CPU 사용률(%): {{ printf "%.1f" $values.B.Value }} % # 표현식 B의 최신 값
- 임계값(%): 70 %
---------------------------------------
labels: # Prometheus 스타일 레이블 (라우팅 및 필터링에 사용됨)
site: NIPA
isPaused: false # 규칙 활성화 여부 (false는 활성화 상태)