Loki 쿼리 에디터

Loki 쿼리 에디터 (Loki query editor)

Loki 데이터 소스의 쿼리 에디터는 Loki 쿼리 언어인 LogQL을 사용하는 로그·메트릭 쿼리를 만드는 데 도움을 줘요.

출처: 문서

본문

쿼리 편집 모드 선택

Loki 쿼리 에디터에는 Builder와 Code 두 가지 모드가 있어요. 상단의 Builder/Code 탭으로 전환하고, Run queries를 선택해 쿼리를 실행해요(Explore에서는 Run query). 각 모드는 동기화되므로 작업을 잃지 않고 전환할 수 있지만 일부 제한이 있어요. Builder 모드는 일부 복잡한 쿼리를 지원하지 않아요. 그런 쿼리로 Code에서 Builder로 전환하면 에디터가 쿼리의 일부를 잃을 수 있다는 경고를 표시해요. 템플릿 변수로 쿼리를 보강할 수도 있어요.

Builder 모드

Builder 모드는 LogQL을 수동으로 입력하지 않고 시각적 인터페이스로 쿼리를 구성하게 해줘요. Loki와 LogQL 경험이 없거나 거의 없는 사용자에게 가장 좋아요.

라벨 필터 (Label filters)

드롭다운 목록에서 라벨과 값을 선택해요. 라벨을 선택하면 Grafana가 서버에서 사용 가능한 값을 가져와요. + 버튼으로 라벨을 추가하고 x 버튼으로 제거할 수 있으며, 여러 라벨을 추가할 수 있어요. 비교 연산자(equals, not equals, matches regex 등)를 선택하고, 선택한 라벨을 기반으로 가능한 모든 값을 표시하는 드롭다운으로 값을 선택해요.

연산 (Operations)

+ Operations 버튼으로 쿼리에 연산을 추가해요. 쿼리 에디터는 연산을 관련 섹션으로 그룹화하고, 연산 드롭다운이 열린 동안 타이핑해 목록을 검색·필터링할 수 있어요. 연산은 operations 섹션에 상자 형태로 표시되고, 헤더에 이름이 표시되며 호버하면 추가 동작 버튼이 나타나요(같은 유형의 다른 연산으로 교체, 설명 툴팁 열기, 제거). 일부 연산은 특정 순서에서만 의미가 있어요. 무의미한 쿼리가 되는 방식으로 연산을 추가하면 에디터가 올바른 위치에 배치해요. 연산을 수동으로 재정렬하려면 이름으로 상자를 드래그해 원하는 위치에 놓으면 돼요.

힌트 (Hints)

일부 경우 쿼리 에디터는 선택된 로그 스트림에 가장 적합한 연산을 감지할 수 있어요. 그럴 때 + Operations 버튼 옆에 힌트를 표시하고, 클릭하면 연산을 추가해요.

Builder 모드 예시

LogQL을 전혀 쓰지 않고 payments 앱의 오류 줄 속도를 계산하는 메트릭 쿼리를 만드는 단계입니다. 빌더는 다음 동등한 LogQL 쿼리를 생성해요:

sum(rate({app="payments"} |= `error` [5m]))

언제든 Code 모드로 전환해 생성된 쿼리를 보거나 다듬을 수 있어요.

Code 모드

Code 모드에서는 자동 완성, 구문 강조, 쿼리 검증이 있는 텍스트 에디터로 복잡한 쿼리를 작성할 수 있어요. 쿼리 작성을 돕는 라벨 브라우저도 제공해요.

자동 완성 사용

Code 모드의 자동 완성은 타이핑하는 동안 자동으로 동작해요. 정적 함수, 집계, 키워드와 라벨 같은 동적 항목을 자동 완성할 수 있어요. 자동 완성 드롭다운에는 사용 가능한 곳에서 제안 항목에 대한 문서가 포함돼요.

로그 쿼리 만들기

Loki 로그 쿼리는 로그 줄의 내용을 반환해요. Explore와 대시보드의 Logs 패널을 통해 Loki 로그 데이터를 쿼리하고 표시할 수 있어요.

로그 쿼리에는 두 부분이 있어요: 라벨로 로그 스트림을 선택하는 스트림 선택기와, 일치하는 줄을 필터링·파싱하는 선택적 파이프라인.

payments 앱의 모든 로그 줄 반환:

{app="payments"}

error라는 단어가 포함된 줄만 유지하고 health-check 노이즈를 제외:

{app="payments"} |= `error` != `healthcheck`

정규식으로 매칭(예: 4xx 또는 5xx 상태):

{app="nginx"} |~ `status=(4|5)..`

구조화된 로그를 파싱한 뒤 추출된 필드로 필터링. logfmt 로그를 파싱해 500ms보다 느린 요청만 유지:

{app="payments"} | logfmt | duration > 500ms

JSON 로그를 파싱하고 error 레벨 항목만 유지:

{namespace="prod", app="checkout"} | json | level=`error`

사용 사례: 실패하는 서비스 디버깅. 장애 중 하나의 서비스에 대한 오류를 분리하려면 네임스페이스·앱 선택기와 파서·라벨 필터 결합:

{namespace="prod", app="checkout"} |= `error` | logfmt | status >= 500

로그 컨텍스트 보기 (Show log context)

Explore에서 Show context 버튼을 클릭해 로그 결과 주변의 컨텍스트를 가져올 수 있어요. 관심 있는 로그 메시지 앞뒤의 같은 로그 스트림 로그를 조사할 수 있죠. 초기 로그 컨텍스트 쿼리는 선택한 로그 줄의 스트림을 정의하는 모든 라벨에서 만들어져요. 로그 컨텍스트 쿼리 에디터로 로그 스트림에서 라벨 필터 하나 이상을 제거해 검색을 넓힐 수 있어요. 원래 쿼리에서 파서를 사용했다면 추출된 라벨 필터로 검색을 다듬을 수도 있어요. 로그 컨텍스트가 로드하는 시간 창 크기도 조정할 수 있어요. Grafana는 선택한 라벨을 저장해 각 열린 컨텍스트 창에 적용하므로, 여러 컨텍스트 창을 탐색할 때 필터를 다시 적용할 필요가 없어요. Revert to initial query 버튼으로 필터를 리셋하고 초기 로그 컨텍스트 쿼리를 사용할 수 있어요.

실시간 로그 테일링 (Tail live logs)

Loki는 Explore에서 실시간 로그 테일링을 지원해요. 라이브 테일링은 두 개의 WebSocket 연결(브라우저-Grafana 서버, Grafana 서버-Loki 서버)에 의존해요. Explore 뷰 오른쪽 위의 Live 버튼을 클릭해 로그 테일링을 시작하세요.

프록시 예시

리버스 프록시를 사용한다면 라이브 테일링을 사용하도록 구성하세요.

Apache2로 브라우저와 Grafana 서버 사이를 프록시:

ProxyPassMatch "^/(api/datasources/proxy/\d+/loki/api/v1/tail)" "ws://127.0.0.1:3000/$1"

NGINX 사용 예시 — Grafana 서버가 http://localhost:3000/에 있고, Loki가 프록시 없이 로컬로 실행되며, 외부 사이트가 HTTPS를 사용한다고 가정. Loki도 NGINX 프록시 뒤에 있으면 그 구성도 반복하세요. NGINX http 섹션에 map 정의 추가:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
  }

server 섹션에 다음 구성 추가:

location ~ /(api/datasources/proxy/\d+/loki/api/v1/tail) {
      proxy_pass          http://localhost:3000$request_uri;
      proxy_set_header    Host              $host;
      proxy_set_header    X-Real-IP         $remote_addr;
      proxy_set_header    X-Forwarded-for   $proxy_add_x_forwarded_for;
      proxy_set_header    X-Forwarded-Proto "https";
      proxy_set_header    Connection        $connection_upgrade;
      proxy_set_header    Upgrade           $http_upgrade;
  }

  location / {
      proxy_pass          http://localhost:3000/;
      proxy_set_header    Host              $host;
      proxy_set_header    X-Real-IP         $remote_addr;
      proxy_set_header    X-Forwarded-for   $proxy_add_x_forwarded_for;
      proxy_set_header    X-Forwarded-Proto "https";
  }

메트릭 쿼리 만들기

LogQL로 로그 쿼리를 함수로 감싸 로그에서 메트릭을 만들 수 있어요. 메트릭 쿼리는 로그 쿼리와 선택적 범위(예: [5m])에 ratecount_over_time 같은 범위 집계를 적용해요. 그런 다음 결과를 sum이나 topk 같은 집계 연산자로 감싸 시리즈를 그룹화하거나 순위를 매길 수 있어요.

payments 앱 전체에서 초당 오류 줄 속도 계산:

sum(rate({app="payments"} |= `error` [5m]))

상태 코드별 요청 속도 분해:

sum by (status) (rate({app="nginx"} | logfmt [5m]))

지난 1시간 동안 발생한 타임아웃 횟수 계산:

count_over_time({app="payments"} |= `timeout` [1h])

경로별 95번째 백분위 요청 지속 시간 계산. logfmt 로그를 파싱하고 숫자 duration 필드를 unwrap:

quantile_over_time(0.95, {app="payments"} | logfmt | unwrap duration [5m]) by (route)

사용 사례: 가장 시끄러운 엔드포인트 찾기. 지난 1시간 동안 로그 볼륨 기준 상위 10개 요청 경로 순위:

topk(10, sum by (path) (count_over_time({app="nginx"} | logfmt [1h])))

쿼리 분할 (Query splitting)

큰 쿼리를 응답성 있게 유지하기 위해 Grafana는 긴 시간 범위를 다루는 Loki 쿼리를 자동으로 더 작은 하위 쿼리들로 분할해요. Grafana가 하위 쿼리를 실행하고 결과를 병합하며, 부분 결과가 도착하면 점진적으로 진행돼요. 쿼리 분할은 로그·메트릭 쿼리 모두에 적용되며 구성이 필요 없어요.

구조화 메타데이터 (Structured metadata)

Loki는 세 가지 유형의 라벨을 저장해요: 인덱스 라벨, 파싱된 필드, 구조화 메타데이터. 쿼리 에디터와 로그 상세는 이 세 가지 유형을 모두 필터링하고 파생 필드에서 사용할 수 있는 라벨로 취급해요.

애노테이션 적용

Loki 로그 쿼리를 대시보드 애노테이션의 소스로 사용할 수 있어요.

더 알아보기 (Learn more)