나의 잡다한 노트 및 메모
LogQL과 구성 요소 본문
LogQL은 Grafana Loki에서 로그를 검색하고 집계하기 위해 사용하는 쿼리 언어입니다. PromQL(Prometheus 쿼리 언어)과 유사한 구문 체계를 사용하되, 로그라는 특성에 맞춰 다양한 필터링 기능을 제공합니다. LogQL 쿼리는 크게 **로그 쿼리(Log Query)**와 **로그 기반 메트릭 쿼리(Metric Query)**로 나뉩니다.
1. 기본 구성 요소
1) 레이블 셀렉터(Label Selector)
{app="myapp", environment="production"}
- Loki에 저장된 로그 라인에는 여러 레이블(label)들이 있으며, app="myapp"과 같은 식으로 필수적으로 레이블 조건을 사용해야 합니다.
- 중괄호 {} 안에서 ,로 구분하여 여러 개의 레이블을 지정할 수 있습니다.
- 아래 연산자들을 사용합니다.
- =: 정확히 일치
- !=: 일치하지 않음
- =~: 정규식(Regex) 패턴 일치
- !~: 정규식(Regex) 패턴 불일치
2) 로그 라인 필터(Log Line Filter)
레이블 셀렉터 뒤에 |=, !=, |~, !~ 같은 연산자를 붙여서 로그 라인 내용을 필터링할 수 있습니다.
{app="myapp"} |= "ERROR"
{app="myapp"} != "INFO"
{app="myapp"} |~ "Exception.*timeout"
{app="myapp"} !~ "DEBUG|TRACE"
{app="myapp"} != "INFO"
{app="myapp"} |~ "Exception.*timeout"
{app="myapp"} !~ "DEBUG|TRACE"
- |=: 지정 문자열을 포함하는 로그 라인만 매칭
- !=: 지정 문자열을 포함하지 않는 로그 라인만 매칭
- |~: 지정 정규식(Regex)에 매칭되는 로그 라인만 매칭
- !~: 지정 정규식(Regex)에 매칭되지 않는 로그 라인만 매칭
2. 로그 쿼리(Log Query)
로그 쿼리는 주로 특정 문자열(또는 패턴)을 포함(또는 제외)하는 로그를 검색하기 위해 사용합니다.
- 결과가 “로그 라인” 형태로 반환됩니다.
- 예를 들어, 아래 쿼리는 app="myapp" 레이블을 가진 로그 중 ERROR 문자열을 포함하고, DEBUG 문자열은 포함하지 않는 로그만 필터링합니다.
{app="myapp"} |= "ERROR" != "DEBUG"
이런 쿼리는 Loki에서 단순 검색 용도로 활용할 수 있고, 검색 결과를 Grafana의 Explore 창에서 확인할 수 있습니다.
3. 로그 기반 메트릭 쿼리(Metric Query)
LogQL을 사용하면 로그에서 특정 패턴을 카운트하거나, 로그의 발생 빈도를 그래프로 시각화할 수 있습니다. 이를 로그 기반 메트릭 쿼리라고 합니다. 메트릭 쿼리는 파이프(|) 뒤에 여러 함수를 조합해 사용할 수 있습니다.
1) 범위 벡터(range vector) 함수
아래와 같은 함수들은 특정 시간 범위 내에서 로그 라인들을 집계(Count, Rate 등)합니다.
- count_over_time(): 주어진 기간 동안 일치하는 로그 라인 수를 세어줍니다.
- [] 안에 [5m]와 같이 범위를 지정해야 합니다(최근 5분 동안).
- count_over_time({app="myapp"} |= "ERROR" [5m])
- rate(): 시계열 형태(초당 발생 건수 등)를 구하려고 할 때 사용합니다.
- 최근 5분 동안 발생한 로그 라인의 초당 발생률을 반환합니다.
-
rate({app="myapp"} |= "ERROR" [5m])
- count_over_time() + by (label) 또는 sum by (label) 문법을 함께 사용해 레이블별, 필드별로 그룹화하여 집계할 수 있습니다.
- 예: app="myapp"로 묶여 있는 로그를 1분 단위로 집계한 뒤, level 레이블 별로 합산.
-
sum by (level)(
count_over_time({app="myapp"}[1m])
)
4. 실제 예시
- 오류 로그 발생 빈도(초당) 조회:
rate({job="nginx"} |= "ERROR" [5m])
- job="nginx" 레이블을 가진 로그 중 ERROR가 포함된 로그를 기준으로, 최근 5분 동안 초당 발생 빈도를 계산.
- 레벨별 로그 카운트:
sum by (level) (
count_over_time(
{app="myapp"}[5m]
)
)
count_over_time(
{app="myapp"}[5m]
)
)
- app="myapp"의 최근 5분간 로그 라인을 집계하고, level 레이블(예: INFO, ERROR 등) 별로 합산하여 시계열로 반환.
- 정규식을 이용한 특정 패턴 필터링:
{app=~"service.*"} |~ "user_id=(\\d+)"
- 레이블 app이 service로 시작하는 컨테이너에서, 로그 라인이 user_id=(숫자) 패턴을 포함하면 매칭.