Loki 데이터 소스 구성

Loki 데이터 소스 구성 (Configure the Loki data source)

이 문서는 Loki 데이터 소스를 구성하는 방법과 사용 가능한 구성 옵션을 설명해요. Grafana는 Loki를 내장 지원하므로 플러그인 설치가 필요 없어요.

출처: 문서

본문

데이터 소스 추가

Connections > Data sources에서 Add data source를 클릭하고 Loki를 선택하면 Grafana가 설정을 구성하는 Settings 탭으로 안내해요.

참고: Loki 작업 시 추가 보안 계층으로 TLS를 사용하세요.

UI에서 데이터 소스 구성

먼저 연결 이름을 정해요.

설정 설명
Name 데이터 소스 이름. 패널과 쿼리에서 참조하는 이름. 예: loki-1, loki_logs
Default 이 데이터 소스를 기본값으로 만드는 토글. 새 패널·쿼리에서 Grafana가 기본 선택

연결 (Connection)

설정 설명
URL Loki 서버의 기본 URL. 로컬이면 http://localhost:3100, 네트워크 서버면 http://loki.example.com:3100 같은 URL·포트 사용

참고: 기본 URL만 입력하세요. /loki/api/v1/push 같은 API 경로는 추가하지 마세요. 그 엔드포인트는 Grafana Alloy 같은 에이전트가 로그를 Loki로 보내는 데 쓰는 것이지, 데이터 소스에서 Loki를 쿼리하는 데 쓰는 게 아니에요. Grafana Cloud에서 실행 중이면 localhost나 프라이빗 네트워크 주소는 여러분의 네트워크가 아니라 Grafana 서버를 가리켜 자체 호스팅 Loki에 도달할 수 없어요. 프라이빗 네트워크의 Loki를 쿼리하려면 Private data source connect(PDC)를 사용하세요.

인증 (Authentication)

설정 설명
Basic authentication 가장 흔한 인증 방법. Loki 서버의 사용자 이름과 비밀번호 입력
Forward OAuth Identity 데이터 소스를 쿼리하는 사용자의 OAuth 액세스 토큰과 (가능하면) OIDC ID 토큰을 전달하는 토글
With credentials 쿠키나 인증 헤더 같은 자격 증명을 크로스 사이트 요청에 보내는 토글
TLS Client Auth 클라이언트 인증서로 인증하는 토글. Server name, Client cert, Client key 제공
With CA cert 자체 서명 TLS 인증서를 검증하는 토글. CA 지침에 따라 인증서 파일 확보
Skip TLS verify TLS 인증서 검증을 우회하는 토글. 꼭 필요한 경우나 테스트가 아니면 권장하지 않음

참고: Grafana Cloud 호스팅 Loki의 경우 사용자 이름을 Grafana Cloud 사용자 ID로, 비밀번호를 Cloud Access Policy 토큰으로 하는 Basic authentication을 사용하세요. 토큰의 접근 정책에 logs:read 스코프가 포함되어야 해요. 토큰은 Grafana Cloud Portal에서 만듭니다. 토큰 값은 한 번만 표시되므로 만들 때 복사해 두세요.

커스텀 HTTP 헤더

Loki 인스턴스가 요구하는 값을 전달하는 커스텀 HTTP 헤더를 추가할 수 있어요. Header는 커스텀 헤더 이름, Value는 헤더 값이에요. 멀티 테넌트 Loki(auth_enabled: true로 구성된 것)의 경우 X-Scope-OrgID 헤더를 테넌트 ID로 추가해 Loki가 어느 테넌트를 쿼리할지 알게 해야 해요. 이 헤더가 없으면 멀티 테넌트 Loki에 대한 쿼리가 인증 오류로 실패하거나 데이터를 반환하지 않아요.

추가 설정 (Additional settings)

Additional settings 섹션은 접히는 섹션으로, 데이터 소스에 대한 더 많은 제어를 주는 선택적 설정을 포함해요. 기본적으로 열려 있으며 고급 HTTP 설정, 알림, 쿼리, 파생 필드 옵션을 포함해요.

고급 HTTP 설정
설정 설명
Allowed cookies 데이터 소스로 전달해야 하는 쿠키를 이름으로 지정. 기본적으로 Grafana 프록시는 전달된 쿠키를 삭제
Timeout HTTP 요청 타임아웃(초). 기본값이 없으므로 쿼리에 맞는 값을 설정
Secure Socks Proxy

Secure Socks Proxy 설정은 Grafana 구성 파일에서 보안 SOCKS 데이터 소스 프록시가 활성화될 때만 나타나요. 활성화되면 보안 SOCKS 프록시를 통해 데이터 소스 요청을 라우팅할 수 있어요.

알림 (Alerting)
설정 설명
Manage alert rules in Alerting UI Loki 데이터 소스용 데이터 소스 관리 알림 규칙을 Grafana Alerting UI에서 관리하는 토글. 이 규칙은 Loki ruler가 저장·평가. 기본값은 Grafana 구성에 따라 결정

이 규칙이 생성하는 알림 같은 다른 알림 리소스를 관리하려면 Alertmanager 데이터 소스를 추가하세요.

쿼리 (Queries)
설정 설명
Maximum lines Loki가 반환하는 최대 로그 줄 수 설정. 임시 분석을 위해 더 큰 결과 집합을 원하면 증가시키고, 로그 결과 표시 시 브라우저가 느리면 감소. 기본값은 1000
파생 필드 (Derived fields)

파생 필드는 로그에서 새 필드를 추출하고 필드 값에서 링크를 만들기 위해 사용해요. 예를 들어 로그에서 트레이싱 백엔드로 직접 링크하거나, 로그 줄에 해당 userId가 포함될 때 사용자 프로필 페이지로 링크할 수 있어요. 이 링크들은 로그 상세(Log details)에 나타나요. 여러 파생 필드를 추가할 수 있어요.

설정 설명
Name 필드 이름. 로그 상세에서 라벨로 표시
Type 파생 필드 유형. Regex in log line은 로그 콘텐츠에서 값을 파싱, Label은 라벨 키 매칭
Regex 유형이 Regex in log line일 때 로그 메시지의 일부를 파싱하는 정규식. 캡처 그룹을 포함해야 하며, Grafana는 첫 번째 캡처 그룹을 필드 값으로 사용
Label 유형이 Label일 때 입력이 라벨 키에 대한 정규식으로 매칭. trace[_]?id 같은 패턴은 traceidtrace_id 변형과 일치. 인덱스·파싱·구조화 메타데이터 등 모든 라벨과 매칭
URL/query 외부 링크의 전체 링크 URL 또는 내부 링크의 대상 데이터 소스 쿼리. 필드 값을 ${__value.raw} 매크로로 보간
URL Label 선택. 링크의 커스텀 표시 라벨. 기본값(전체 외부 URL 또는 연결된 내부 데이터 소스 이름)을 재정의
Internal link 트레이싱 데이터 소스로의 내부 링크 정의 토글. 선택기에서 대상 데이터 소스 선택
Open in new tab 링크를 새 탭/창에서 열 토글
Show example log message 예제 로그 줄을 붙여넣어 파생 필드의 정규식 테스트

주의: 두 유형 모두 복잡한 정규식을 사용하면 대량 로그 처리 시 브라우저 성능에 영향을 줄 수 있어요. 가능하면 더 단순한 패턴을 사용하세요.

참고: 파생 필드는 로그 줄당 하나의 값을 생성하므로 여러 라벨이나 캡처 그룹을 하나의 필드나 링크로 결합할 수 없어요. 내부 링크의 경우 파생 필드는 추출된 값으로 대상 데이터 소스에만 링크를 만듭니다. 링크가 해석되려면 트레이스가 이미 Tempo 같은 대상 데이터 소스에 수집되어 있어야 해요. 일치하는 트레이스가 없으면 링크가 대상 데이터 소스를 열지만 트레이스를 반환하지 않아요.

연결 확인

설정 하단의 Save & test를 클릭하세요. Grafana가 Loki 서버에 연결해 라벨을 쿼리합니다. 성공하면 데이터 소스가 동작함을 확인하는 메시지가 표시돼요. 실패하면 오류 메시지를 검토하고 "Loki 문제 해결"을 참고하세요.

참고: 구성·기타 문제를 해결하려면 Unix 시스템에서는 /var/log/grafana/grafana.log, 다른 플랫폼/수동 설치에서는 <grafana_install_dir>/data/log의 로그 파일을 확인하세요.

데이터 소스 프로비저닝

데이터 소스를 Grafana 프로비저닝 시스템의 일부로 YAML 파일로 정의하고 구성할 수 있어요.

기본 Loki 데이터 소스 프로비저닝 예시:

apiVersion: 1

datasources:
  - name: Loki
    type: loki
    access: proxy
    url: http://localhost:3100
    jsonData:
      timeout: 60
      maxLines: 1000

기본 인증과 파생 필드를 사용하는 예시 (YAML 값에서 $ 문자는 환경 변수 보간에 쓰일 수 있으므로 이스케이프해야 해요):

apiVersion: 1

datasources:
  - name: Loki
    type: loki
    access: proxy
    url: http://localhost:3100
    basicAuth: true
    basicAuthUser: my_user
    jsonData:
      maxLines: 1000
      derivedFields:
        # Field with internal link pointing to data source in Grafana.
        # datasourceUid value can be anything, but it should be unique across all defined data source uids.
        - datasourceUid: my_jaeger_uid
          matcherRegex: "traceID=(\\w+)"
          name: TraceID
          # url will be interpreted as query for the datasource
          url: '$${__value.raw}'
          # optional for URL Label to set a custom display label for the link.
          urlDisplayLabel: 'View Trace'

        # Field with external link.
        - matcherRegex: "traceID=(\\w+)"
          name: TraceID
          url: 'http://localhost:16686/trace/$${__value.raw}'
    secureJsonData:
      basicAuthPassword: test_password

Jaeger 데이터 소스 사용 예시 (Jaeger 데이터 소스의 uid 값은 Loki 데이터 소스의 datasourceUid 값과 일치해야 해요):

datasources:
  - name: Jaeger
    type: jaeger
    url: http://jaeger-tracing-query:16686/
    access: proxy
    # UID should match the datasourceUid in derivedFields.
    uid: my_jaeger_uid

Terraform으로 구성

Grafana Terraform 프로바이더를 사용해 Loki 데이터 소스를 구성할 수 있어요.

최대 줄 수 한도가 있는 Loki 데이터 소스 프로비저닝 예시:

resource "grafana_data_source" "loki" {
  name = "Loki"
  type = "loki"
  url  = "http://localhost:3100"

  json_data_encoded = jsonencode({
    maxLines = 1000
  })
}

기본 인증과 Jaeger로 연결되는 파생 필드 정의 예시:

resource "grafana_data_source" "loki" {
  name           = "Loki"
  type           = "loki"
  url            = "http://localhost:3100"
  basic_auth_enabled  = true
  basic_auth_username = "my_user"

  json_data_encoded = jsonencode({
    maxLines = 1000
    derivedFields = [
      {
        datasourceUid   = "my_jaeger_uid"
        matcherRegex    = "traceID=(\\w+)"
        name            = "TraceID"
        url             = "$${__value.raw}"
        urlDisplayLabel = "View Trace"
      }
    ]
  })

  secure_json_data_encoded = jsonencode({
    basicAuthPassword = "<LOKI_PASSWORD>"
  })
}

더 알아보기 (Learn more)