본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Loki 운영 문제 해결하기

원문 보기 위키 갱신

이 문서는 설정 문제, 스토리지 백엔드 장애, 클러스터 통신 실패, 서비스 컴포넌트 오류처럼 Loki를 운영하다가 만나는 오류들을 Troubleshooting하는 방법을 안내해요. 별도 문서에서 다루는 수집(쓰기 경로)·쿼리(읽기 경로) 오류와는 다른 범위예요.

출처: Loki Documentation

본문

이 가이드는 설정 문제, 스토리지 백엔드 장애, 클러스터 통신 실패, 서비스 컴포넌트 오류처럼 Loki 운영 중에 발생하는 오류를 Troubleshooting하는 데 도움을 줘요. 여기서 다루는 오류는 별도의 문제 해결 주제에서 다루는 수집(쓰기 경로) 오류와 쿼리(읽기 경로) 오류와는 구분돼요.

시작하기 전에 다음 항목을 준비했는지 확인하세요:

  • Loki 로그와 메트릭에 접근할 수 있어야 해요
  • Loki 설정을 조회하고 수정할 수 있는 권한이 있어야 해요
  • 배포 토폴로지(단일 바이너리/모놀리식, simple scalable, 마이크로서비스/분산)를 이해하고 있어야 해요

설정 오류

설정 오류는 Loki가 시작할 때나 런타임 설정을 로드할 때 발생해요. 이런 오류가 있으면 Loki가 제대로 시작하지 못하거나 동작하지 않아요.

오류: Multiple config errors found

오류 메시지:

MULTIPLE CONFIG ERRORS FOUND, PLEASE READ CAREFULLY
<list of configuration errors>

원인:

시작 과정에서 여러 개의 설정 검증 오류가 한꺼번에 발견됐어요. Loki는 첫 번째 오류에서 바로 멈추지 않고 모든 설정 오류를 모아서 보여줘요.

해결 방법:

  • 나열된 모든 오류를 꼼꼼히 확인하세요. 각 오류 메시지가 특정 설정 문제를 설명해 줘요.

  • 설정 파일에 문법 오류나 잘못된 값이 없는지 확인하세요.

  • 적용하기 전에 설정을 검증하세요:

    loki -config.file=/path/to/config.yaml -verify-config
    

속성:

  • 적용 위치: Loki 시작
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Too many storage configs

오류 메시지:

too many storage configs provided in the common config, please only define one storage backend

원인:

common 설정 섹션에 여러 스토리지 백엔드가 함께 설정돼 있어요. Loki는 common 설정에 스토리지 백엔드를 하나만 둘 것을 요구해요.

해결 방법:

  • common 설정에서는 스토리지 백엔드를 하나만 사용하세요:

    common:
      storage:
        # Choose only ONE of the following:
        s3:
          endpoint: s3.amazonaws.com
          bucketnames: loki-data
        # OR
        gcs:
          bucket_name: loki-data
        # OR
        azure:
          container_name: loki-data
    
  • 여러 스토리지 백엔드가 필요하다면, common 설정 대신 각 섹션에 명시적으로 설정하세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Persist tokens path prefix required

오류 메시지:

if persist_tokens is true, path_prefix MUST be defined

원인:

어떤 ring에서 persist_tokens 옵션이 켜져 있는데 path_prefix가 지정되지 않았어요. Loki는 토큰 파일을 저장할 경로가 필요해요.

해결 방법:

  • 경로 접두사를 지정하세요:

    common:
      path_prefix: /var/loki
      persist_tokens: true
    
    ingester:
      lifecycler:
        ring:
          kvstore:
            store: memberlist
        tokens_file_path: /var/loki/tokens
    
  • 토큰 영속화가 필요 없다면 persist_tokens를 끄세요:

    common:
      persist_tokens: false
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Conflicting gRPC client configs

오류 메시지:

both `grpc_client_config` and (`query_frontend_grpc_client` or `query_scheduler_grpc_client`) are set at the same time. Please use only `query_frontend_grpc_client` and `query_scheduler_grpc_client`

원인:

더 이상 권장되지 않는 grpc_client_config와 새로운 전용 gRPC 클라이언트 설정이 동시에 지정돼 있어요. 이 둘은 함께 쓸 수 없어요.

해결 방법:

  • 폐기된 설정을 제거하고 전용 gRPC 클라이언트 설정을 사용하세요:

    # Remove this:
    # grpc_client_config: ...
    
    # Use these instead:
    query_frontend_grpc_client:
      max_recv_msg_size: 104857600
    query_scheduler_grpc_client:
      max_recv_msg_size: 104857600
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Schema v13 required for structured metadata

오류 메시지:

CONFIG ERROR: schema v13 is required to store Structured Metadata and use native OTLP ingestion, your schema version is <version>. Set `allow_structured_metadata: false` in the `limits_config` section or set the command line argument `-validation.allow-structured-metadata=false` and restart Loki. Then proceed to update to schema v13 or newer before re-enabling this config, search for 'Storage Schema' in the docs for the schema update procedure

원인:

structured metadata가 활성화돼 있는데 현재 스키마 버전이 v13보다 낮아요. structured metadata를 쓰려면 스키마 v13 이상이 필요해요.

해결 방법:

  • structured metadata를 임시로 끄세요:

    limits_config:
      allow_structured_metadata: false
    
  • 스키마 설정을 v13 이상으로 업데이트하세요:

    schema_config:
      configs:
        - from: "2024-04-01"
          store: tsdb
          object_store: s3
          schema: v13
          index:
            prefix: index_
            period: 24h
    
  • 스키마 마이그레이션이 끝나면 structured metadata를 다시 켜세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: TSDB index type required for structured metadata

오류 메시지:

CONFIG ERROR: `tsdb` index type is required to store Structured Metadata and use native OTLP ingestion, your index type is `<type>` (defined in the `store` parameter of the schema_config). Set `allow_structured_metadata: false` in the `limits_config` section or set the command line argument `-validation.allow-structured-metadata=false` and restart Loki. Then proceed to update the schema to use index type `tsdb` before re-enabling this config, search for 'Storage Schema' in the docs for the schema update procedure

원인:

structured metadata가 활성화돼 있는데 현재 인덱스 타입이 TSDB가 아니에요. structured metadata에는 TSDB 인덱스 타입이 필요해요.

해결 방법:

  • structured metadata를 임시로 끄고 TSDB 인덱스 타입으로 마이그레이션하세요:

    limits_config:
      allow_structured_metadata: false
    
    schema_config:
      configs:
        - from: "2024-01-01"
          store: tsdb
          object_store: s3
          schema: v13
    
  • TSDB로 마이그레이션한 뒤 structured metadata를 다시 켜세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: TSDB directories not configured

오류 메시지:

CONFIG ERROR: `tsdb` index type is configured in at least one schema period, however, `storage_config`, `tsdb_shipper`, `active_index_directory` is not set, please set this directly or set `path_prefix:` in the `common:` section

또는:

CONFIG ERROR: `tsdb` index type is configured in at least one schema period, however, `storage_config`, `tsdb_shipper`, `cache_location` is not set, please set this directly or set `path_prefix:` in the `common:` section

원인:

스키마에 TSDB 인덱스 타입이 설정돼 있는데, 인덱스 파일에 필요한 로컬 디렉터리가 지정되지 않았어요.

해결 방법:

  • common 경로 접두사를 지정하세요 (가장 간단한 방법이에요):

    common:
      path_prefix: /var/loki
    
  • 또는 디렉터리를 명시적으로 설정하세요:

    storage_config:
      tsdb_shipper:
        active_index_directory: /var/loki/tsdb-index
        cache_location: /var/loki/tsdb-cache
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Compactor working directory empty

오류 메시지:

CONFIG ERROR: `compactor:` `working_directory:` is empty, please set a valid directory or set `path_prefix:` in the `common:` section

원인:

compactor가 인덱스 압축(compaction)에 쓸 작업 디렉터리를 필요로 하는데, 설정된 디렉터리가 없어요.

해결 방법:

  • common 경로 접두사를 지정하세요:

    common:
      path_prefix: /var/loki
    
  • 또는 compactor 작업 디렉터리를 명시적으로 지정하세요:

    compactor:
      working_directory: /var/loki/compactor
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Unrecognized index or store type

오류 메시지:

unrecognized `store` (index) type `<type>`, choose one of: <supported_types>

또는:

unrecognized `object_store` type `<type>`, which also does not match any named_stores. Choose one of: <supported_types>. Or choose a named_store

원인:

스키마 설정에서 Loki가 인식하지 못하는 인덱스 타입이나 오브젝트 스토어 타입을 참조하고 있어요.

해결 방법:

  • 지원되는 인덱스 타입을 사용하세요: tsdb

  • 지원되는 오브젝트 스토어 타입을 사용하세요: s3, gcs, azure, swift, filesystem, bos

  • 또는 설정에 정의된 유효한 named store를 참조하세요:

    storage_config:
      named_stores:
        aws:
          my-store:
            endpoint: s3.amazonaws.com
            bucketnames: my-bucket
    
    schema_config:
      configs:
        - from: 2024-01-01
          store: tsdb
          object_store: my-store  # References the named store
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Overrides exporter requires runtime configuration

오류 메시지:

overrides-exporter has been enabled, but no runtime configuration file was configured

원인:

overrides-exporter 대상이 활성화됐는데 런타임 설정 파일이 제공되지 않았어요. overrides-exporter는 테넌트별 limit 오버라이드를 메트릭으로 노출하려면 런타임 설정이 필요해요.

해결 방법:

  • 런타임 설정 파일을 지정하세요:

    runtime_config:
      file: /etc/loki/runtime-config.yaml
    
  • 필요 없다면 대상 목록에서 제거해서 overrides-exporter를 비활성화하세요.

속성:

  • 적용 위치: 모듈 초기화
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid override for tenant

오류 메시지:

invalid override for tenant <tenant>: <details>

원인:

런타임 설정 파일에 특정 테넌트에 대한 잘못된 오버라이드가 들어 있어요. 해당 오버라이드가 검증을 통과하지 못했어요.

해결 방법:

  • 지정된 테넌트 항목을 기준으로 런타임 설정 파일을 검토하세요.
  • limits 설정 스키마를 기준으로 오버라이드 값을 검증하세요.
  • 음수 duration, 잘못된 label matcher, 범위를 벗어난 설정 같은 잘못된 값을 고치세요.

속성:

  • 적용 위치: 런타임 설정 로더
  • 재시도 가능 여부: 아니요 (런타임 설정을 고쳐야 해요)
  • HTTP 상태: N/A (런타임 설정 리로드 실패)
  • 테넌트별 설정: 예

오류: Retention period too short

오류 메시지:

retention period must be >= 24h was <duration>

원인:

스트림 단위 retention 규칙이 최소 허용치인 24시간보다 짧은 보존 기간을 지정하고 있어요.

해결 방법:

  • 보존 기간을 최소 24시간 이상으로 설정하세요:

    limits_config:
      retention_stream:
        - selector: '{namespace="dev"}'
          priority: 1
          period: 24h  # Must be >= 24h
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 예

오류: Invalid query store max look back period

오류 메시지:

it is an error to specify a non zero `query_store_max_look_back_period` value when using any object store other than `filesystem`

원인:

filesystem이 아닌 다른 스토리지 백엔드를 쓰는데 query_store_max_look_back_period가 0이 아닌 값으로 설정돼 있어요. 이 설정은 로컬 파일시스템 스토리지에만 적용돼요.

해결 방법:

  • 오브젝트 스토리지를 사용 중이라면 이 설정을 제거하세요:

    # Remove or set to 0:
    query_store_max_look_back_period: 0
    
  • 로컬 개발 환경에서 이 설정이 필요하다면 filesystem 스토리지를 사용하세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

인증 및 테넌트 오류

인증 및 테넌트 오류는 요청에 필수 테넌트 식별 정보가 빠졌거나 테넌트 ID가 잘못됐을 때 발생해요. 멀티 테넌트 모드에서는 모든 요청에 유효한 테넌트 ID가 포함돼야 해요.

오류: No org ID

오류 메시지:

no org id

원인:

필수 X-Scope-OrgID 헤더 없이 Loki에 요청이 들어왔어요. 멀티 테넌트 모드에서는 모든 요청이 테넌트를 식별해야 해요.

해결 방법:

  • 요청에 X-Scope-OrgID 헤더를 추가하세요:

    curl -H "X-Scope-OrgID: my-tenant" http://loki:3100/loki/api/v1/push ...
    
  • Grafana에서는 Loki 데이터 소스 설정의 "HTTP Headers"에서 테넌트 ID를 설정하세요.

  • Alloy에서는 loki.write 컴포넌트에 테넌트 ID를 지정하세요:

    loki.write "default" {
      endpoint {
        url       = "http://loki:3100/loki/api/v1/push"
        tenant_id = "my-tenant"
      }
    }
    
  • 단일 테넌트 배포라면 멀티 테넌시를 비활성화하세요:

    auth_enabled: false
    

속성:

  • 적용 위치: 인증 미들웨어
  • 재시도 가능 여부: 예 (테넌트 ID를 넣으면)
  • HTTP 상태: 401 Unauthorized
  • 테넌트별 설정: 아니요

오류: Multiple org IDs present

오류 메시지:

multiple org IDs present

원인:

요청에 서로 다른 여러 테넌트 ID가 담겨 있지만, 이 작업에는 테넌트가 하나만 허용돼요. 요청이 여러 프록시를 거치면서 각 프록시가 테넌트 ID를 주입할 때 이런 일이 생길 수 있어요.

해결 방법:

  • X-Scope-OrgID 헤더에 테넌트 ID가 하나만 설정돼 있는지 확인하세요.

  • 테넌트 ID 주입이 충돌하는 프록시 설정을 점검하세요.

  • 교차 테넌트 쿼리는 지원되는 위치에서만 파이프로 구분된 테넌트 ID를 사용하세요:

    curl -H "X-Scope-OrgID: tenant1|tenant2" http://loki:3100/loki/api/v1/query ...
    

속성:

  • 적용 위치: 테넌트 리졸버
  • 재시도 가능 여부: 예 (올바른 테넌트 ID를 넣으면)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Tenant ID too long

오류 메시지:

tenant ID is too long: max 150 characters

원인:

테넌트 ID가 최대 허용 길이인 150자를 초과했어요.

해결 방법:

  • 더 짧은 테넌트 ID를 사용하세요 (최대 150자).

속성:

  • 적용 위치: 테넌트 검증
  • 재시도 가능 여부: 예 (유효한 테넌트 ID를 넣으면)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Unsafe tenant ID

오류 메시지:

tenant ID is '.' or '..'

원인:

테넌트 ID가 . 또는 ..로 설정돼 있어요. 이 값들은 파일시스템 경로 구성 요소로 예약돼 있어서 경로 탐색(path traversal) 문제를 일으킬 수 있어요.

해결 방법:

  • .이나 ..가 아닌 다른 테넌트 ID를 선택하세요.

속성:

  • 적용 위치: 테넌트 검증
  • 재시도 가능 여부: 예 (유효한 테넌트 ID를 넣으면)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Tenant ID contains unsupported character

오류 메시지:

tenant ID '<id>' contains unsupported character '<char>'

원인:

테넌트 ID에 허용되지 않는 문자가 포함돼 있어요. 테넌트 ID는 영숫자, 하이픈, 언더스코어, 마침표로만 구성돼야 해요.

해결 방법:

  • 테넌트 ID에는 지원되는 문자만 사용하세요: 영문자, 숫자, 하이픈(-), 언더스코어(_), 마침표(.).

속성:

  • 적용 위치: 테넌트 검증
  • 재시도 가능 여부: 예 (유효한 테넌트 ID를 넣으면)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Deletion not available for tenant

오류 메시지:

deletion is not available for this tenant

원인:

어떤 테넌트에 삭제 요청이 제출됐지만 삭제 API 엔드포인트에 접근할 수 없어요. 이런 일은 compactor 설정에서 retention_enabled가 false(기본값)일 때, 또는 해당 테넌트의 deletion_mode 오버라이드가 명시적으로 disabled로 설정됐을 때 발생해요.

해결 방법:

  • 삭제 API 엔드포인트의 게이트 역할을 하는 compactor에서 retention을 켜세요:

    compactor:
      retention_enabled: true
    
  • 필요하다면 런타임 설정에서 해당 테넌트의 deletion 모드를 오버라이드하세요:

    overrides:
      my-tenant:
        deletion_mode: filter-and-delete  # Or "filter-only"
    

    유효한 deletion 모드:

    • disabled - 삭제가 허용되지 않아요
    • filter-only - 삭제 요청과 일치하는 라인이 쿼리 시점에 필터링되지만 실제로는 삭제되지 않아요
    • filter-and-delete - 라인이 쿼리 시점에 필터링되고 compaction 중에 물리적으로 삭제돼요 (기본값)
  • compactor가 retention을 위해 제대로 설정돼 있는지 확인하세요:

    compactor:
      retention_enabled: true
      delete_request_store: s3
    

속성:

  • 적용 위치: Compactor 삭제 핸들러
  • 재시도 가능 여부: 아니요 (설정을 바꿔야 해요)
  • HTTP 상태: 403 Forbidden
  • 테넌트별 설정: 예

스토리지 백엔드 오류

스토리지 백엔드 오류는 Loki가 오브젝트 스토리지(Amazon S3, Google Cloud Services, Microsoft Azure, Swift, filesystem)와 통신하거나 제대로 설정하지 못할 때 발생해요.

오류: Unsupported storage backend

오류 메시지:

unsupported storage backend

원인:

지정된 스토리지 백엔드 타입이 인식되지 않아요. 보통 스토리지 타입 설정에 오타가 있을 때 발생해요.

해결 방법:

  • 유효한 스토리지 백엔드 타입을 사용하세요:

    • s3 - Amazon S3 또는 S3 호환 스토리지
    • gcs - Google Cloud Storage (구글 클라우드 스토리지)
    • azure - Azure Blob Storage (애저 블롭 스토리지)
    • swift - OpenStack Swift
    • filesystem - 로컬 파일시스템
    • bos - Baidu Object Storage (바이두 오브젝트 스토리지)
    storage_config:
      tsdb_shipper:
        shared_store: s3  # Must be one of the valid types
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid characters in storage prefix

오류 메시지:

storage prefix contains invalid characters, it may only contain digits, English alphabet letters and dashes

원인:

스토리지 경로 접두사에 허용되지 않는 문자가 포함돼 있어요. 영숫자와 대시만 사용할 수 있어요.

해결 방법:

  • 스토리지 접두사에 유효한 문자만 사용하세요:

    storage_config:
      # Invalid: prefix_with_underscore_or/special chars
      # Valid: my-loki-data or lokilogs123
      aws:
        s3: s3://my-bucket/my-loki-data
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Unsupported S3 SSE type

오류 메시지:

unsupported S3 SSE type

원인:

S3 서버 사이드 암호화(SSE) 타입이 지원되지 않아요. Loki는 특정 SSE 타입만 지원해요.

해결 방법:

  • 지원되는 SSE 타입을 사용하세요:

    storage_config:
      aws:
        sse:
          type: SSE-S3    # Or SSE-KMS
    

    지원되는 타입:

    • SSE-S3 - Amazon S3가 관리하는 키를 사용하는 서버 사이드 암호화
    • SSE-KMS - AWS KMS가 관리하는 키를 사용하는 서버 사이드 암호화

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid S3 SSE encryption context

오류 메시지:

invalid S3 SSE encryption context

원인:

SSE-KMS 암호화 컨텍스트가 잘못된 형태라서 유효한 JSON으로 파싱할 수 없어요.

해결 방법:

  • 암호화 컨텍스트에 유효한 JSON을 제공하세요:

    storage_config:
      aws:
        sse:
          type: SSE-KMS
          kms_key_id: alias/my-key
          kms_encryption_context: '{"key": "value"}'  # Valid JSON
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid S3 endpoint prefix

오류 메시지:

the endpoint must not prefixed with the bucket name

원인:

S3 엔드포인트에 버킷 이름이 접두사로 잘못 포함돼 있어요. 이러면 path-style과 virtual-hosted-style URL 사이에 문제가 생길 수 있어요.

해결 방법:

  • 엔드포인트에서 버킷 이름을 제거하고 별도로 설정하세요:

    storage_config:
      aws:
        # Incorrect:
        # endpoint: my-bucket.s3.amazonaws.com
    
        # Correct:
        endpoint: s3.amazonaws.com
        bucketnames: my-bucket
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid STS endpoint

오류 메시지:

sts-endpoint must be a valid url

원인:

AWS STS(Security Token Service) 엔드포인트 URL이 잘못된 형식이거나 유효하지 않아요.

해결 방법:

  • STS 엔드포인트에 유효한 URL을 제공하세요:

    storage_config:
      aws:
        sts_endpoint: https://sts.us-east-1.amazonaws.com
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Azure connection string malformed

오류 메시지:

connection string is either blank or malformed. The expected connection string should contain key value pairs separated by semicolons. For example 'DefaultEndpointsProtocol=https;AccountName=<accountName>;AccountKey=<accountKey>;EndpointSuffix=core.windows.net'

원인:

Azure 스토리지 연결 문자열이 없거나 기대하는 형식을 따르지 않아요.

해결 방법:

  • 유효한 연결 문자열 형식을 사용하세요:

    storage_config:
      azure:
        # Use account credentials:
        account_name: myaccount
        account_key: mykey
    
        # Or connection string:
        connection_string: "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;EndpointSuffix=core.windows.net"
    
  • Azure Portal의 Storage Account > Access Keys에서 연결 문자열을 확인하세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Unrecognized named storage config

오류 메시지:

unrecognized named storage config <name>

특정 백엔드라면:

unrecognized named s3 storage config <name>
unrecognized named gcs storage config <name>
unrecognized named azure storage config <name>
unrecognized named filesystem storage config <name>
unrecognized named swift storage config <name>

인식되지 않는 스토어 타입이라면:

unrecognized named storage type: <storeType>

원인:

스키마 설정에서 참조하는 named storage 설정이 named stores 설정에 존재하지 않아요.

해결 방법:

  • 설정에 named store를 정의하세요:

    storage_config:
      named_stores:
        aws:
          my-s3-store:  # This name must match the reference
            endpoint: s3.amazonaws.com
            bucketnames: my-bucket
    
    schema_config:
      configs:
        - from: 2024-01-01
          store: tsdb
          object_store: my-s3-store  # References the named store above
    
  • 정의와 참조 양쪽에서 스토어 이름 철자를 확인하세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

캐시 오류

캐시 오류는 Loki가 캐시 백엔드(Memcached, Redis)에 연결하거나 통신하지 못할 때 발생해요.

오류: Redis client setup failed

오류 메시지:

redis client setup failed: <details>

원인:

Loki가 Redis 서버와의 연결을 맺지 못해요. 흔한 원인은 다음과 같아요:

  • 잘못된 Redis 엔드포인트
  • 네트워크 연결 문제
  • 인증 실패
  • TLS 설정 문제

해결 방법:

  • Loki 호스트에서 Redis 연결을 확인하세요:

    redis-cli -h <REDIS-HOST> -p <REDIS-PORT> ping
    
  • Redis 엔드포인트 설정을 점검하세요:

    chunk_store_config:
      chunk_cache_config:
        redis:
          endpoint: redis:6379
          timeout: 500ms
    
  • 필요하다면 인증을 설정하세요:

    chunk_store_config:
      chunk_cache_config:
        redis:
          endpoint: redis:6379
          password: ${REDIS_PASSWORD}
    

속성:

  • 적용 위치: 캐시 클라이언트 초기화
  • 재시도 가능 여부: 예 (설정을 바로잡으면)
  • HTTP 상태: N/A (시작 실패 또는 성능 저하)
  • 테넌트별 설정: 아니요

오류: Could not lookup Redis host

오류 메시지:

could not lookup host: <hostname>

원인:

Redis 호스트 이름의 DNS 조회가 실패했어요.

해결 방법:

  • DNS 조회를 확인하세요:

    nslookup redis-host
    
  • DNS를 쓸 수 없다면 IP 주소를 사용하세요:

    chunk_store_config:
      chunk_cache_config:
        redis:
          endpoint: 10.0.0.100:6379
    
  • DNS 설정과 네트워크 설정을 점검하세요.

속성:

  • 적용 위치: DNS 조회
  • 재시도 가능 여부: 예
  • HTTP 상태: N/A
  • 테넌트별 설정: 아니요

오류: Unexpected Redis PING response

오류 메시지:

redis: Unexpected PING response "<response>"

원인:

Redis 서버가 PING 명령에 예상 밖의 응답을 돌려줬어요. 다음 가능성이 있어요:

  • 해당 엔드포인트가 Redis 서버가 아니에요
  • 프록시나 로드 밸런서가 방해하고 있어요
  • Redis가 오류 상태에 있어요

해결 방법:

  • 해당 엔드포인트가 실제 Redis 서버인지 확인하세요.

  • Redis 상태를 확인하세요:

    redis-cli -h <HOST> -p <PORT> INFO
    
  • Redis 앞에 로드 밸런서를 두고 있다면 프록시 설정을 검토하세요.

속성:

  • 적용 위치: Redis 헬스 체크
  • 재시도 가능 여부: 예
  • HTTP 상태: N/A
  • 테넌트별 설정: 아니요

오류: Multiple cache systems not supported

오류 메시지:

use of multiple cache storage systems is not supported

원인:

같은 캐시 타입에 Memcached와 Redis 캐시 백엔드가 둘 다 설정돼 있어요. 캐시 타입마다 캐싱 백엔드는 하나만 지원돼요.

해결 방법:

  • 캐시 타입마다 캐시 백엔드를 하나만 선택하세요:

    chunk_store_config:
      chunk_cache_config:
        # Use either memcached OR redis, not both
        redis:
          endpoint: redis:6379
        memcached: {}  # Remove this
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: No cache configured

오류 메시지:

no cache configured

원인:

query frontend에 결과 캐시가 필요한데 캐시 설정이 제공되지 않았어요.

해결 방법:

  • 캐시 백엔드를 설정하세요:

    query_range:
      results_cache:
        cache:
          memcached:
            expiration: 1h
          memcached_client:
            addresses: memcached:11211
    
  • 필요 없다면 결과 캐싱을 비활성화하세요:

    query_range:
      cache_results: false
    

속성:

  • 적용 위치: Query frontend 초기화
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Error loading cache generation numbers

오류 메시지:

msg="error loading cache generation numbers" err="unexpected status code: 403"

compactor HTTP 클라이언트에서는:

msg="error getting cache gen numbers from the store" err="unexpected status code: 403"

메트릭: loki_delete_cache_gen_load_failures_total

원인:

Loki는 로그 삭제 요청이 처리될 때 쿼리 캐시를 무효화하기 위해 캐시 세대 번호(cache generation numbers)를 사용해요. 캐시 세대 번호 로더는 이 번호들을 주기적으로 compactor에서 가져오는데, compactor가 HTTP 403을 돌려주면 해당 테넌트에 삭제 API가 활성화되지 않았다는 뜻이에요. 로더는 이 오류를 기록하고 loki_delete_cache_gen_load_failures_total 메트릭을 증가시켜요.

403이 아닌 다른 원인으로는 다음이 있어요:

  • compactor에 접근할 수 없어요 (네트워크 또는 DNS 문제)
  • compactor가 실행 중이 아니거나 준비되지 않았어요
  • querier와 compactor 사이의 TLS 또는 인증 설정이 잘못됐어요

해결 방법:

  • 삭제가 의도적으로 비활성화된 건 아닌지 확인하세요. 이 테넌트에서 로그 삭제를 쓰지 않는다면 이 오류는 무해하지만 시끄러워요. compactor의 캐시 세대 번호 엔드포인트로 GET 요청을 보내 확인할 수 있어요:

    curl -s -H "X-Scope-OrgID: <tenant>" http://compactor:3100/loki/api/v1/cache/generation_numbers
    

    응답이 "deletion is not available for this tenant"라면 해당 테넌트에 삭제 API가 활성화되지 않은 거예요.

  • 로그 삭제가 필요하다면 해당 테넌트에 삭제를 활성화하세요:

    overrides:
      <tenant>:
        deletion_mode: filter-and-delete
    
  • 오류에 403이 아닌 상태 코드나 연결 오류가 포함돼 있다면 compactor 연결을 점검하세요:

    curl -s http://compactor:3100/ready
    
  • 캐시 세대 번호 로더를 사용하는 querier와 다른 컴포넌트가 compactor에 도달할 수 있도록 compactor 주소가 올바르게 설정돼 있는지 확인하세요:

    compactor:
      compactor_address: http://compactor:3100
    

속성:

  • 적용 위치: 캐시 세대 번호 로더 (GenNumberLoader)
  • 재시도 가능 여부: 예 (로더가 5분마다 자동으로 재시도해요)
  • HTTP 상태: N/A (백그라운드 프로세스, 요청 시점 오류가 아니에요)
  • 테넌트별 설정: 예 (테넌트 오버라이드의 deletion_mode로 설정)

Ring 및 클러스터 통신 오류

Ring 오류는 Loki 컴포넌트들이 작업을 인스턴스들에 분산하는 데 쓰이는 해시 ring을 통해 제대로 통신하지 못할 때 발생해요. Ring은 Loki의 분산 동작에 필수적인 요소예요.

오류: Too many unhealthy instances in the ring

오류 메시지:

too many unhealthy instances in the ring

원인:

Ring에 비정상 인스턴스가 너무 많아서 복제 계수를 충족할 수 없어요. 예를 들어 복제 계수가 3이면 최소 3개의 정상 인스턴스가 사용 가능해야 해요.

해결 방법:

  • ring 멤버들의 상태를 확인하세요:

    curl -s http://loki:3100/ring | jq '.shards[] | select(.state != "ACTIVE")'
    
  • 나쁜 상태에 멈춰 있는 비정상 인스턴스를 재시작하세요.

  • 정상 멤버가 부족하다면 인스턴스를 스케일 업하세요.

  • 비정상 인스턴스의 리소스 제약(CPU, 메모리, 디스크)을 확인하세요.

속성:

  • 적용 위치: Ring 복제
  • 재시도 가능 여부: 예 (인스턴스가 회복되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Empty ring

오류 메시지:

empty ring

원인:

Ring에 등록된 인스턴스가 하나도 없어요. 보통 클러스터 초기 시작 중에 발생하는데, 예를 들어 ingester가 OOM 크래시를 일으키는 경우나 설정이 잘못된 경우에 생겨요.

해결 방법:

  • 초기 시작 중에는 인스턴스들이 등록될 때까지 기다리세요.

  • ingester가 실행 중인지 확인하세요.

  • 모든 인스턴스가 설정된 포트로 통신할 수 있는지 확인하세요.

  • 모든 컴포넌트에서 ring 설정을 검증하세요. 특히 memberlist 설정이 중요해요:

    ingester:
      lifecycler:
        ring:
          kvstore:
            store: memberlist
          replication_factor: 3
    
  • KV 스토어 상태를 확인하세요 (Consul, etcd, memberlist):

    # For memberlist
    curl -s http://loki:3100/memberlist
    

속성:

  • 적용 위치: Ring 연산
  • 재시도 가능 여부: 예 (인스턴스가 등록되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Instance not found in the ring

오류 메시지:

instance <id> not found in the ring

원인:

Ring에 있어야 할 특정 인스턴스가 등록되어 있지 않아요. 재시작 후 인스턴스가 아직 ring에 다시 합류하지 못했을 때 발생할 수 있어요.

해결 방법:

  • 인스턴스가 ring에 다시 등록될 때까지 기다리세요.
  • ring 합류 실패가 있는지 인스턴스 로그를 확인하세요.
  • 해당 인스턴스에서 KV 스토어 연결을 검증하세요.

속성:

  • 적용 위치: Ring 연산
  • 재시도 가능 여부: 예 (인스턴스가 등록되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Instance owns no tokens

오류 메시지:

this instance owns no tokens

원인:

인스턴스가 ring에는 합류했지만 아직 토큰을 하나도 확보하지 못했어요. 토큰이 없으면 인스턴스는 아무 작업도 받을 수 없어요. 다음 경우에 발생할 수 있어요:

  • 인스턴스가 아직 시작 중이에요
  • 토큰 클레임이 실패했어요
  • KV 스토어 업데이트가 전파되지 않았어요

해결 방법:

  • 시작 중에는 토큰 할당을 기다리세요.

  • 인스턴스의 ring 상태를 확인하세요: 브라우저를 열고 http://localhost:3100/ring으로 이동하세요. Loki Ring Status 페이지가 보여야 해요.

    또는

    curl -s http://loki:3100/ring
    
  • 시작이 끝난 뒤에도 토큰이 할당되지 않는다면 인스턴스를 재시작하세요.

  • KV 스토어 연결과 상태를 확인하세요.

속성:

  • 적용 위치: Lifecycler 준비 상태 검사
  • 재시도 가능 여부: 예 (토큰이 할당되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Error talking to the KV store

오류 메시지:

error talking to the KV store

원인:

인스턴스가 ring 상태에 사용되는 키-값 스토어와 통신하지 못해요. KV 스토어(Consul, etcd, memberlist)는 ring 조정에 필수예요.

해결 방법:

  • KV 스토어의 상태와 연결을 확인하세요:

    # For Consul
    curl http://consul:8500/v1/status/leader
    
    # For etcd
    etcdctl endpoint health
    
  • Loki 인스턴스들과 KV 스토어 사이의 네트워크 연결을 검증하세요.

  • KV 스토어 포트의 트래픽을 방화벽 규칙이 허용하는지 확인하세요.

  • memberlist라면 모든 인스턴스 사이에서 gossip 포트에 접근 가능한지 확인하세요:

    memberlist:
      bind_port: 7946
      join_members:
        - loki-memberlist:7946
    

속성:

  • 적용 위치: Ring lifecycler
  • 재시도 가능 여부: 예 (KV 스토어가 회복되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: No ring returned from the KV store

오류 메시지:

no ring returned from the KV store

원인:

KV 스토어가 응답했지만 비어 있거나 잘못된 ring 디스크립터를 돌려줬어요. KV 스토어가 최근에 초기화됐거나 데이터가 지워진 경우에 생길 수 있어요.

해결 방법:

  • 첫 시작 중에는 ring 초기화를 기다리세요.
  • KV 스토어 데이터가 실수로 지워지지 않았는지 확인하세요.
  • KV 스토어가 초기화됐다면 ring에 다시 등록하도록 모든 ring 멤버를 재시작하세요.

속성:

  • 적용 위치: Ring lifecycler
  • 재시도 가능 여부: 예 (ring이 초기화되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Failed to join memberlist cluster

오류 메시지:

failed to join memberlist cluster on startup

또는:

joining memberlist cluster failed

원인:

인스턴스가 memberlist gossip 클러스터에 합류하지 못했어요. 흔한 원인:

  • 시드 노드에 도달할 수 없어요
  • join 주소의 DNS 조회가 실패했어요
  • 방화벽이 gossip 포트를 막고 있어요
  • 기존 멤버가 모두 내려가 있어요

해결 방법:

  • join 멤버에 도달 가능한지 확인하세요:

    # Test connectivity to seed nodes
    nc -zv loki-memberlist 7946
    
  • join 주소의 DNS 조회를 검증하세요:

    nslookup loki-memberlist
    
  • memberlist 설정을 점검하세요:

    memberlist:
      bind_port: 7946
      join_members:
        - loki-gossip-ring.loki.svc.cluster.local:7946
    
  • 방화벽 규칙이 gossip 포트(기본값 7946)의 UDP와 TCP 트래픽을 허용하는지 확인하세요.

  • Kubernetes라면 memberlist용 headless service가 올바르게 설정돼 있는지 검증하세요.

속성:

  • 적용 위치: Memberlist KV 클라이언트
  • 재시도 가능 여부: 예 (백오프를 두고 자동 재시도)
  • HTTP 상태: N/A (시작 실패 또는 성능 저하)
  • 테넌트별 설정: 아니요

오류: Re-joining memberlist cluster failed

오류 메시지:

re-joining memberlist cluster failed

원인:

memberlist 클러스터에서 연결이 끊긴 후 인스턴스가 다시 합류하지 못했어요. 네트워크 파티션이나 긴 네트워크 문제 이후에 발생할 수 있어요.

해결 방법:

  • 클러스터 멤버들 사이의 네트워크 연결을 확인하세요.
  • 다른 클러스터 멤버들이 정상인지 검증하세요.
  • 자동 재합류가 계속 실패하면 영향을 받은 인스턴스를 재시작하세요.
  • 네트워크 안정성을 검토하세요. 잦은 재합류는 근본적인 네트워크 문제를 의미해요.

속성:

  • 적용 위치: Memberlist KV 클라이언트
  • 재시도 가능 여부: 예 (자동 재시도)
  • HTTP 상태: N/A (성능 저하)
  • 테넌트별 설정: 아니요

컴포넌트 준비 상태 오류

준비 상태 오류는 Loki 컴포넌트가 요청을 처리할 준비가 되지 않았을 때 발생해요. 이런 오류는 /ready 헬스 체크 엔드포인트가 돌려주며, 로드 밸런서가 준비되지 않은 인스턴스로 트래픽을 보내지 않도록 막아줘요.

오류: Application is stopping

오류 메시지:

Application is stopping

원인:

Loki가 종료 중이라 새 요청을 더 이상 받지 않아요. 우아한 종료(graceful shutdown) 과정에서는 정상적인 현상이에요.

해결 방법:

  • 롤링 업데이트 중이라면 인스턴스가 재시작되길 기다리세요.
  • 종료가 예상된 것인지 확인하세요 (유지보수, 스케일 다운).
  • 종료가 예상 밖이라면 오케스트레이터 로그를 검토하세요 (Kubernetes, systemd).

속성:

  • 적용 위치: Loki 준비 상태 핸들러
  • 재시도 가능 여부: 예 (재시작 후)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Some services are not running

오류 메시지:

Some services are not Running:
<state>: <count>
<state>: <count>

예를 들면:

Some services are not Running:
Starting: 1
Failed: 2

원인:

하나 이상의 Loki 내부 서비스가 시작에 실패했거나 예기치 않게 멈췄어요. 오류 메시지는 각 서비스 상태와 해당 상태의 서비스 개수를 나열해요.

해결 방법:

  • 나열된 서비스의 오류가 있는지 Loki 로그를 확인하세요.
  • 영향을 받은 서비스의 설정을 검증하세요.
  • 리소스 가용성을 확인하세요 (메모리, 디스크, CPU).
  • 서비스가 멈춰 있다면 인스턴스를 재시작하세요.

속성:

  • 적용 위치: Loki 서비스 매니저
  • 재시도 가능 여부: 예 (서비스가 회복되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Ingester not ready

오류 메시지:

Ingester not ready: <details>

ingester 자신의 상태 검사가 실패하면 <details>에 ingester 상태가 담겨서 전체 메시지는 이렇게 돼요:

Ingester not ready: ingester not ready: <state>

여기서 <state>는 서비스 상태예요. 예를 들어 Starting, Stopping, Failed 같은 값이에요.

원인:

ingester가 쓰기를 받거나 읽기를 처리할 준비 상태가 아니에요. 상세 메시지가 구체적인 이유를 알려줘요. 예를 들면:

  • ingester가 아직 시작 중이고 ring에 합류하는 중이에요 (Starting)
  • lifecycler가 준비되지 않았어요 (lifecycler 오류 텍스트)
  • ingester가 ring 합류 후 최소 준비 시간을 기다리고 있어요

해결 방법:

  • 시작이 끝나길 기다리세요 - ingester가 ring에 합류하고 준비되려면 시간이 걸려요.

  • ring 멤버십을 확인하세요: 브라우저를 열고 http://localhost:3100/ring으로 이동하세요. Loki Ring Status 페이지가 보여야 해요.

    또는

    curl -s http://ingester:3100/ring
    
  • 시작 오류가 있는지 로그를 검토하세요.

  • 시작이 너무 느리다면 최소 준비 시간을 조정하세요:

    ingester:
      lifecycler:
        min_ready_duration: 15s
    

속성:

  • 적용 위치: Ingester 준비 상태 검사
  • 재시도 가능 여부: 예 (ingester가 준비되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: No queriers connected to query frontend

오류 메시지:

Query Frontend not ready: not ready: number of queriers connected to query-frontend is 0

원인:

query frontend에 연결된 querier 워커가 없어요. querier가 없으면 frontend는 어떤 쿼리도 처리할 수 없어요. 보통 다음 경우에 발생해요:

  • querier가 아직 시작되지 않았어요
  • querier가 frontend에 도달하지 못해요
  • querier와 frontend 사이에 gRPC 연결 문제가 있어요

해결 방법:

  • querier가 실행 중이고 정상인지 확인하세요.

  • querier 설정이 올바른 frontend 주소를 가리키는지 검증하세요:

    frontend_worker:
      frontend_address: query-frontend:9095
    
  • querier와 frontend 사이의 gRPC 연결을 확인하세요:

    # Test gRPC port connectivity
    nc -zv query-frontend 9095
    
  • 연결 오류가 있는지 querier 로그를 검토하세요.

속성:

  • 적용 위치: Query frontend (v1) 준비 상태 검사
  • 재시도 가능 여부: 예 (querier가 연결되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: No schedulers connected to frontend worker

오류 메시지:

Query Frontend not ready: not ready: number of schedulers this worker is connected to is 0

원인:

query frontend 워커가 어떤 query scheduler에도 활성 연결을 갖고 있지 않아요. 이러면 frontend가 쿼리를 디스패치할 수 없어요.

해결 방법:

  • query scheduler가 실행 중이고 정상인지 확인하세요.

  • scheduler 주소 설정을 검증하세요:

    frontend_worker:
      scheduler_address: query-scheduler:9095
    
  • frontend와 scheduler 사이의 gRPC 연결을 확인하세요.

  • 오류가 있는지 query scheduler 로그를 검토하세요.

속성:

  • 적용 위치: Query frontend (v2) 준비 상태 검사
  • 재시도 가능 여부: 예 (scheduler가 연결되면)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

gRPC 및 메시지 크기 오류

gRPC 오류는 컴포넌트 간 통신 중에 발생해요. Loki 컴포넌트들은 ring 조정, 쿼리 실행, 데이터 전송에 gRPC를 사용해요.

오류: Message size too large

오류 메시지:

message size too large than max (<size> vs <max>)

압축 해제된 본문이라면:

decompressed message size too large than max (<size> vs <max>)

원인:

distributor로 향하는 HTTP push 요청의 압축 본문 또는 압축 해제된 본문이 설정된 한도를 초과했어요.

기본 설정:

  • distributor.max_recv_msg_size: 100MB (압축된 요청 본문 한도)
  • distributor.max_decompressed_size: 5000MB (압축 해제된 본문 한도, 기본값은 max_recv_msg_size의 50배)

해결 방법:

  • distributor 수신 메시지 크기 한도를 늘리세요:

    distributor:
      max_recv_msg_size: 209715200      # 200MB compressed
      max_decompressed_size: 10737418240  # 10GB decompressed
    
  • 로그 수집 클라이언트(Alloy 등)에서 push 배치 크기를 줄여서 개별 요청을 더 작게 보내세요.

  • 클라이언트의 배치 크기나 flush 간격을 낮춰서 요청당 데이터 양을 줄이세요.

속성:

  • 적용 위치: Distributor push 핸들러
  • 재시도 가능 여부: 아니요 (요청을 줄이거나 한도를 늘려야 해요)
  • HTTP 상태: 413 Request Entity Too Large (압축), 400 Bad Request (압축 해제)
  • 테넌트별 설정: 아니요

오류: Response larger than max message size

오류 메시지:

response larger than the max message size (<size> vs <max>)

원인:

querier에서 frontend로 가는 쿼리 결과가 허용된 최대 gRPC 응답 크기를 초과했어요. 아주 큰 결과 집합을 돌려주는 쿼리에서 주로 발생해요.

기본 설정:

  • server.grpc_server_max_send_msg_size: 4MB (querier의 gRPC 서버 송신 한도)
  • querier.query_frontend_grpc_client.max_recv_msg_size: 100MB (querier 워커의 gRPC 클라이언트 수신 한도)

해결 방법:

  • 결과가 더 적게 나오도록 쿼리 범위를 줄이세요:

    • 더 구체적인 label matcher를 추가하세요
    • 시간 범위를 줄이세요
    • entries limit을 낮추세요
  • 필요하다면 gRPC 메시지 크기 한도를 늘리세요. 이 설정은 querier 노드에 적용하세요:

    server:
      grpc_server_max_send_msg_size: 209715200   # 200MB
    
    querier:
      query_frontend_grpc_client:
        max_recv_msg_size: 209715200             # 200MB
    

속성:

  • 적용 위치: Querier 워커
  • 재시도 가능 여부: 아니요 (쿼리 범위나 한도를 바꿔야 해요)
  • HTTP 상태: 413 Request Entity Too Large
  • 테넌트별 설정: 아니요

오류: Compressed message size exceeds limit

오류 메시지:

compressed message size <size> exceeds limit <limit>

원인:

HTTP push 요청의 압축 본문이 distributor의 설정 한도를 초과했어요. 이 검사는 요청 본문을 전부 읽은 후에 실행되고, 압축된 전체 크기를 설정된 최댓값과 비교해요.

기본 설정:

  • distributor.max_recv_msg_size: 100MB

해결 방법:

  • 로그 수집 클라이언트에서 배치 크기를 줄이세요.

  • 큰 배치를 더 작고 자주 보내는 요청으로 분할하세요.

  • 필요하다면 한도를 늘리세요:

    distributor:
      max_recv_msg_size: 209715200   # 200MB
    

속성:

  • 적용 위치: Distributor push 핸들러
  • 재시도 가능 여부: 아니요 (요청을 줄여야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

TLS 및 인증서 오류

TLS 오류는 인증서 문제로 Loki나 그 클라이언트가 보안 연결을 맺지 못할 때 발생해요.

오류: TLS certificate loading failed

오류 메시지:

error loading ca cert: <path>

또는:

error loading client cert: <path>

또는:

error loading client key: <path>

또는:

failed to load TLS certificate <cert_path>,<key_path>

원인:

Loki가 지정된 경로에서 TLS 인증서를 로드하지 못해요. 흔한 원인:

  • 설정된 경로에 인증서 파일이 존재하지 않아요
  • 권한 문제로 파일을 읽을 수 없어요
  • 인증서나 키 형식이 잘못됐어요
  • 인증서와 키가 서로 맞지 않아요

해결 방법:

  • 인증서 파일이 존재하고 읽을 수 있는지 검증하세요:

    ls -la /path/to/cert.pem /path/to/key.pem /path/to/ca.pem
    
  • 파일 권한을 확인하세요 (Loki 프로세스가 읽을 수 있어야 해요).

  • 인증서 형식을 검증하세요:

    openssl x509 -in /path/to/cert.pem -noout -text
    openssl rsa -in /path/to/key.pem -check
    
  • 인증서와 키가 서로 맞는지 확인하세요:

    openssl x509 -noout -modulus -in cert.pem | md5sum
    openssl rsa -noout -modulus -in key.pem | md5sum
    # Both should produce the same hash
    
  • TLS 설정을 확인하세요:

    server:
      http_tls_config:
        cert_file: /path/to/cert.pem
        key_file: /path/to/key.pem
        client_ca_file: /path/to/ca.pem
      grpc_tls_config:
        cert_file: /path/to/cert.pem
        key_file: /path/to/key.pem
        client_ca_file: /path/to/ca.pem
    

속성:

  • 적용 위치: TLS 설정
  • 재시도 가능 여부: 아니요 (인증서를 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: TLS configuration error

오류 메시지:

error generating http tls config: <details>

또는:

error generating grpc tls config: <details>

<details>에는 TLS version %q not recognized, cipher suite %q not recognized, unknown TLS version: <version> 같은 메시지가 포함될 수 있어요.

원인:

TLS 설정이 유효하지 않아요. 다음 경우에 발생할 수 있어요:

  • 지원되지 않는 TLS 버전 문자열이 들어왔어요
  • cipher suite 설정이 잘못됐어요
  • client auth 타입이 인식되지 않아요

해결 방법:

  • 호환성 문제가 있는지 TLS 설정을 검토하세요.

  • server 블록의 최상위에 tls_min_version을 지정해서 지원되는 TLS 버전을 사용하세요:

    server:
      tls_min_version: VersionTLS12
    

    유효한 값은 VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13이에요. max_version 설정은 없고, tls_min_version이 유일한 버전 제약이에요.

  • 커스터마이즈했다면 cipher suite 설정을 확인하세요.

속성:

  • 적용 위치: TLS 초기화
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

DNS 조회 오류

DNS 오류는 Loki가 서비스 디스커버리나 백엔드 연결을 위해 호스트 이름을 조회하지 못할 때 발생해요.

오류: DNS lookup timeout

오류 메시지:

msg="failed to resolve server addresses" err="... DNS lookup timeout: [<address>] ..."

원인:

Loki의 서비스 디스커버리나 백엔드 연결을 위한 주소를 조회하려다 DNS 조회가 5초 제한 시간을 초과했어요. 이 오류는 index gateway와 bloom gateway의 DNS 디스커버리 루프에서 발생해요. DNS lookup timeout: [<address>] 문자열은 err 필드 안에 포함된 context cause예요. 전체 주소 목록은 Go 슬라이스 형식으로 표현돼요 (예: [dns+loki-index-gateway.loki.svc.cluster.local:9095]).

해결 방법:

  • DNS 서버 가용성과 설정을 확인하세요.

  • 호스트 이름 조회를 검증하세요:

    nslookup <hostname>
    dig <hostname>
    
  • DNS가 불안정하다면 임시 방편으로 IP 주소를 사용하세요:

    # Instead of dns+hostname:port
    memberlist:
      join_members:
        - 10.0.0.1:7946
        - 10.0.0.2:7946
    
  • Kubernetes라면 CoreDNS가 정상이고 headless service가 올바르게 설정돼 있는지 확인하세요.

속성:

  • 적용 위치: Index gateway 클라이언트, bloom gateway 클라이언트 DNS 디스커버리 루프
  • 재시도 가능 여부: 예 (DNS가 회복될 수 있어요)
  • HTTP 상태: N/A (연결 실패)
  • 테넌트별 설정: 아니요

Scheduler 및 frontend 오류

이 오류들은 쿼리 스케줄링, frontend 워커, 큐 관리와 관련돼 있어요.

오류: Scheduler is not running

오류 메시지:

scheduler is not running

원인:

query scheduler 서비스가 실행 상태가 아니에요. 다음 경우에 발생할 수 있어요:

  • scheduler가 시작 중이에요
  • scheduler가 치명적인 오류를 만났어요
  • scheduler가 종료 중이에요

해결 방법:

  • 시작 오류나 크래시가 있는지 scheduler 로그를 확인하세요.

  • scheduler 상태를 검증하세요:

    curl -s http://scheduler:3100/ready
    
  • ring 기반 스케줄링을 사용한다면 scheduler ring 멤버십을 확인하세요:

    curl -s http://scheduler:3100/ring | jq
    

속성:

  • 적용 위치: Scheduler 서비스
  • 재시도 가능 여부: 예 (scheduler가 준비되기를 기다리세요)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

오류: Too many outstanding requests

오류 메시지:

too many outstanding requests

원인:

쿼리 큐가 최대 용량에 도달했어요. 시스템이 쿼리로 과부하 상태라는 뜻이에요.

해결 방법:

  • 쿼리를 더 빨리 처리하도록 querier를 스케일 아웃하세요:

    querier:
      max_concurrent: 10
    
  • 큐 용량을 늘리세요 (신중하게). 기본값은 32000이고, 시스템이 추가 부하를 감당할 수 있음을 확인한 경우에만 그 이상으로 늘리세요. tsdb_max_query_parallelism을 크게 잡으면 생성되는 서브쿼리 수가 많아지기 때문에 큐를 늘려야 하는 경우가 흔해요. 일반적으로 querier를 더 추가하고 이 설정은 그대로 두는 편이 좋아요.

    query_scheduler:
      max_outstanding_requests_per_tenant: 64000
    
  • 클라이언트나 로드 밸런서 수준에서 쿼리에 rate limit을 적용하세요.

  • 큐 대기 시간을 줄이도록 느린 쿼리를 최적화하세요.

속성:

  • 적용 위치: Query scheduler/frontend
  • 재시도 가능 여부: 예
  • HTTP 상태: 429 Too Many Requests
  • 테넌트별 설정: 아니요

오류: Querying is disabled

오류 메시지:

querying is disabled, please contact your Loki operator

원인:

쿼리 병렬도가 0으로 설정돼서 모든 쿼리가 사실상 비활성화됐어요. 보통 유지보수 중 의도적으로 이렇게 하는 거예요.

해결 방법:

  • 인덱스 타입에 맞는 병렬도 설정을 확인하세요. TSDB 인덱스(현재 기본값)에서는 tsdb_max_query_parallelism이 max_query_parallelism을 대체해요. 어느 값이든 0이면 이 오류가 발생해요. 둘 다 0보다 큰지 확인하세요:

    limits_config:
      max_query_parallelism: 32          # default; applies to non-TSDB schemas
      tsdb_max_query_parallelism: 128    # default; applies to TSDB schemas
    
  • tsdb_max_query_parallelism을 수집 볼륨에 맞게 조정하세요. 프로덕션에서 흔한 값은 하루 수집되는 로그 볼륨에 비례해서 128–2048 범위예요:

    하루 수집 볼륨 일반적인 값
    낮음–중간 128–256
    높음 512
    하루 수십 TB 1024–2048
  • 이에 필요한 querier 용량을 고려하세요. 병렬도 단위 하나가 querier 워커 슬롯 하나를 소비해요. 기본값 querier.max_concurrent가 4일 때 하나의 쿼리를 완전히 병렬화하는 데 필요한 querier 수는:

    queriers needed = tsdb_max_query_parallelism / max_concurrent
    

    예를 들어 tsdb_max_query_parallelism: 2048에 max_concurrent: 4라면 하나의 쿼리를 완전히 병렬로 돌리는 데 512개의 querier가 필요해요. 여러 테넌트가 동시에 큰 쿼리를 돌리는 프로덕션 배포는 흔히 수천 개의 querier를 운영해요.

  • 이 설정을 바꿀 권한이 없다면 관리자에게 문의하세요.

속성:

  • 적용 위치: Query frontend
  • 재시도 가능 여부: 아니요 (설정을 바꿔야 해요)
  • HTTP 상태: 429 Too Many Requests
  • 테넌트별 설정: 예

오류: No frontend address

오류 메시지:

no frontend address

원인:

scheduler가 frontend로부터 요청을 받았지만 응답을 돌려보낼 frontend 주소가 제공되지 않았어요.

해결 방법:

  • 주소가 설정돼 있는지 frontend 설정을 확인하세요:

    frontend:
      address: query-frontend:9095
    
  • frontend와 scheduler 사이의 gRPC 연결을 검증하세요.

속성:

  • 적용 위치: Scheduler
  • 재시도 가능 여부: 아니요 (설정 문제)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Scheduler shutting down

오류 메시지:

scheduler is shutting down

원인:

frontend scheduler 워커가 scheduler가 종료 모드에 들어가서 새 요청을 받을 수 없음을 감지했어요.

해결 방법:

  • 종료가 끝나고 scheduler가 재시작되길 기다리세요.
  • 예상된 것인지 확인하세요 (롤링 업데이트, 유지보수).
  • scheduler가 정상화된 뒤 요청을 재시도하세요.

속성:

  • 적용 위치: Scheduler
  • 재시도 가능 여부: 예 (scheduler 재시작 후)
  • HTTP 상태: 503 Service Unavailable
  • 테넌트별 설정: 아니요

Index gateway 오류

Index gateway 오류는 querier가 인덱스 조회를 위해 index gateway와 통신하지 못할 때 발생해요.

오류: Index gateway unhealthy in ring

오류 메시지:

index-gateway is unhealthy in the ring

원인:

index gateway 인스턴스가 ring에서 자신을 비정상으로 판단하고 쿼리 처리를 거부했어요. 이건 자기 점검이에요. 테넌트 요청을 처리하기 전에 게이트웨이는 자신이 정상 ring 멤버 집합에 포함돼 있는지 확인해요.

해결 방법:

  • index gateway 상태를 확인하세요:

    curl -s http://index-gateway:3100/ready
    
  • ring 상태를 확인하세요: 브라우저를 열고 http://localhost:3100/ring으로 이동하세요. Loki Ring Status 페이지가 보여야 해요.

    또는

    curl -s http://index-gateway:3100/ring
    
  • 게이트웨이가 정상 상태가 되지 못하게 하는 오류가 있는지 로그를 확인하세요.

  • 비정상 상태에 멈춰 있다면 index gateway를 재시작하세요.

속성:

  • 적용 위치: Index gateway ring
  • 재시도 가능 여부: 예 (게이트웨이가 정상되기를 기다리세요)
  • HTTP 상태: 500 Internal Server Error
  • 테넌트별 설정: 아니요

오류: No index gateway instances found

오류 메시지:

no index gateway instances found for tenant <tenant>

원인:

해당 테넌트의 요청을 처리할 수 있는 index gateway 인스턴스가 ring에 없어요. 다음 가능성이 있어요:

  • 모든 index gateway가 비정상이에요
  • shuffle sharding이 이 테넌트를 제외했어요
  • ring이 비어 있어요

해결 방법:

  • 실행 중인 index gateway가 있는지 확인하세요:

    curl -s http://index-gateway:3100/ring | jq '.shards | length'
    
  • shuffle sharding을 사용한다면 ring 모드가 설정돼 있는지 검증하세요. index gateway는 ring 모드로 실행되어야 하고 테넌트별 shard size가 설정되어야 해요:

    index_gateway:
      mode: ring
    
    limits_config:
      index_gateway_shard_size: 3  # default = 0 (use all instances)
    
  • 필요하다면 index gateway를 스케일 업하세요.

속성:

  • 적용 위치: Index gateway 클라이언트
  • 재시도 가능 여부: 예
  • HTTP 상태: 500 Internal Server Error
  • 테넌트별 설정: 예 (limits_config의 index_gateway_shard_size로 설정)

Compactor 및 retention 오류

Compactor 오류는 인덱스 compaction이나 retention 적용 중에 발생해요.

오류: No chunks found in table

오류 메시지:

no chunks found in table, please check if there are really no chunks and manually drop the table or see if there is a bug causing us to drop whole index table

원인:

compactor가 retention 처리 중에 비어 있는 인덱스 테이블을 발견했어요. 다음 가능성이 있어요:

  • 테이블의 모든 청크가 만료됐어요
  • 테이블이 한 번도 채워지지 않았어요
  • 데이터 손상이 있어요

해결 방법:

  • 테이블이 비어 있어야 하는 게 맞는지 검증하세요:

    # Check if data exists for the time period
    logcli query '{job=~".+"}' --from="<table-start-time>" --to="<table-end-time>" --limit=1
    
  • 테이블이 정당하게 비어 있다면 오브젝트 스토리지에서 수동으로 삭제하세요.

  • 데이터가 있어야 한다면 잠재적인 데이터 손실을 조사하세요.

속성:

  • 적용 위치: Compactor retention
  • 재시도 가능 여부: 아니요 (수동 개입이 필요해요)
  • HTTP 상태: N/A (백그라운드 프로세스)
  • 테넌트별 설정: 아니요

오류: Delete request store not configured

오류 메시지:

compactor.delete-request-store should be configured when retention is enabled

원인:

retention이 활성화됐는데 삭제 요청을 추적할 스토어가 설정되지 않았어요.

해결 방법:

  • 삭제 요청 스토어를 설정하세요:

    compactor:
      retention_enabled: true
      delete_request_store: s3
    
  • 필요 없다면 retention을 비활성화하세요:

    compactor:
      retention_enabled: false
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Max compaction parallelism invalid

오류 메시지:

max compaction parallelism must be >= 1

원인:

compactor의 병렬도 설정이 0이나 음수로 되어 있어요.

해결 방법:

  • 유효한 병렬도 값을 설정하세요:

    compactor:
      max_compaction_parallelism: 1  # Must be >= 1
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Delete request not found

오류 메시지:

could not find delete request with given id

원인:

삭제 요청을 취소하려고 시도했지만 일치하는 요청이 존재하지 않아요.

해결 방법:

  • 기존 삭제 요청을 나열해 보세요:

    curl -s http://compactor:3100/loki/api/v1/delete | jq
    
  • 삭제 요청 ID가 올바른지 확인하세요.

  • 요청이 이미 처리되고 제거됐는지 확인하세요.

속성:

  • 적용 위치: Compactor API
  • 재시도 가능 여부: 아니요
  • HTTP 상태: 404 Not Found
  • 테넌트별 설정: 아니요

오류: Retention is not enabled

오류 메시지:

Retention is not enabled

원인:

삭제 요청이 제출됐지만 compactor 설정에서 retention이 활성화되지 않았어요. 삭제 요청에는 retention이 활성화되어야 해요.

해결 방법:

  • compactor에서 retention을 활성화하세요:

    compactor:
      retention_enabled: true
      delete_request_store: s3
    
  • 설정을 바꾼 뒤 compactor를 재시작하세요.

속성:

  • 적용 위치: Compactor 삭제 요청 핸들러
  • 재시도 가능 여부: 아니요 (설정을 바꿔야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Invalid delete request time format

오류 메시지:

invalid start time: require unix seconds or RFC3339 format

또는:

invalid end time: require unix seconds or RFC3339 format

원인:

삭제 요청의 시작 또는 종료 시간이 유효한 형식이 아니에요.

해결 방법:

  • Unix 초 또는 RFC3339 형식을 사용하세요:

    # Unix seconds
    curl -X POST http://compactor:3100/loki/api/v1/delete \
      -H "X-Scope-OrgID: my-tenant" \
      -d "query={app=\"foo\"}" \
      -d "start=1704067200" \
      -d "end=1704153600"
    
    # RFC3339
    curl -X POST http://compactor:3100/loki/api/v1/delete \
      -H "X-Scope-OrgID: my-tenant" \
      -d "query={app=\"foo\"}" \
      -d "start=2024-01-01T00:00:00Z" \
      -d "end=2024-01-02T00:00:00Z"
    

속성:

  • 적용 위치: Compactor 삭제 요청 핸들러
  • 재시도 가능 여부: 아니요 (요청을 고쳐야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Delete request already processed

오류 메시지:

deletion of request which is in process or already processed is not allowed

원인:

이미 처리 중이거나 처리가 완료된 삭제 요청을 취소하려고 시도했어요.

해결 방법:

  • 삭제 요청의 상태를 확인하세요:

    curl -s http://compactor:3100/loki/api/v1/delete \
      -H "X-Scope-OrgID: my-tenant" | jq
    
  • 추가 데이터를 삭제해야 한다면 새 삭제 요청을 제출하세요.

속성:

  • 적용 위치: Compactor 삭제 요청 핸들러
  • 재시도 가능 여부: 아니요
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Invalid max_interval for delete request

오류 메시지:

invalid max_interval: valid time units are 's', 'm', 'h'

또는:

max_interval can't be greater than <configured-limit>

또는:

max_interval can't be greater than the interval to be deleted (<duration>)

원인:

삭제 요청의 max_interval 파라미터가 잘못된 값을 갖고 있거나, 설정된 delete_max_interval 한도를 초과하거나, 삭제 요청 자체의 시간 범위를 초과해요.

해결 방법:

  • 지원되는 단위(s, m, h)를 사용해서 유효한 시간 형식을 사용하세요:

    curl -X POST http://compactor:3100/loki/api/v1/delete \
      -H "X-Scope-OrgID: my-tenant" \
      -d "query={app=\"foo\"}" \
      -d "start=1704067200" \
      -d "end=1704153600" \
      -d "max_interval=1h"
    

속성:

  • 적용 위치: Compactor 삭제 요청 핸들러
  • 재시도 가능 여부: 아니요 (요청을 고쳐야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

Ruler 오류

Ruler 오류는 알림 규칙이나 기록 규칙을 평가할 때 발생해요.

오류: Invalid ruler evaluation config

오류 메시지:

invalid ruler evaluation config: <details>

원인:

ruler 평가 모드 설정이 잘못됐어요.

해결 방법:

  • 유효한 평가 모드를 사용하세요:

    ruler:
      evaluation:
        mode: local  # Or "remote"
    

속성:

  • 적용 위치: Ruler 모듈 초기화 (initRuleEvaluator)
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Ruler remote write config conflict

오류 메시지:

ruler remote write config: both 'client' and 'clients' options are defined; 'client' is deprecated, please only use 'clients'

원인:

ruler remote write에서 폐기된 client 옵션과 새로운 clients 옵션이 동시에 설정돼 있어요.

해결 방법:

  • 폐기된 설정을 제거하고 clients를 사용하세요:

    ruler:
      remote_write:
        # Remove this:
        # client: {}
    
        # Use this instead:
        clients:
          primary:
            url: http://prometheus:9090/api/v1/write
    

속성:

  • 적용 위치: Ruler 초기화 (NewRuler)
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Remote write enabled but no URL configured

오류 메시지:

remote-write enabled but no clients URL are configured

clients 맵에 여러 클라이언트가 설정돼 있고 그중 하나에 URL이 없다면:

remote-write enabled but client '<name>' URL for tenant <client-id> is not configured

원인:

ruler에 remote write가 활성화됐는데 대상 URL이 설정되지 않았어요. 첫 번째 변형은 clients 맵이 비어 있을 때 발생해요. 두 번째 변형은 clients 맵의 이름 붙은 항목에 url이 설정되지 않았을 때 발생하고, <client-id>는 테넌트 ID가 아니라 해당 항목의 맵 키예요.

해결 방법:

  • remote write URL을 설정하세요:

    ruler:
      remote_write:
        enabled: true
        clients:
          primary:
            url: http://prometheus:9090/api/v1/write
    
  • 또는 remote write를 비활성화하세요:

    ruler:
      remote_write:
        enabled: false
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Rule result is not a vector or scalar

오류 메시지:

rule result is not a vector or scalar

원인:

규칙 평가가 예상 밖의 결과 타입을 돌려줬어요. 기록 규칙과 알림 규칙은 모두 vector나 scalar 결과를 만들어야 해요. 로그 라인을 돌려주는(숫자 메트릭이 아닌) 일반 로그 스트림 표현식은 어느 규칙 타입에서든 이 오류를 유발해요.

해결 방법:

  • 규칙 표현식이 vector나 scalar를 돌려주는지 확인하세요:

    # Valid - returns vector:
    record: my_metric
    expr: sum(rate({job="app"}[5m] | json | level="error"))
    
    # Invalid - returns logs (triggers error for both recording and alerting rules):
    # record: my_metric
    # expr: '{job="app"}'
    
  • 로그 쿼리에서 숫자 결과를 만들어내도록 집계 함수를 사용하세요.

속성:

  • 적용 위치: Ruler 평가
  • 재시도 가능 여부: 아니요 (규칙을 고쳐야 해요)
  • HTTP 상태: N/A (백그라운드 프로세스)
  • 테넌트별 설정: 아니요

오류: Ruler WAL closed

오류 메시지:

WAL storage closed

원인:

ruler의 write-ahead log(WAL)가 닫힌 후에 그에 대한 연산이 시도됐어요. 보통 종료 과정에서 발생해요.

해결 방법:

  • ruler가 재시작 중이라면 재시작되길 기다리세요.
  • 예상 밖의 WAL 종료를 일으킨 오류가 있는지 ruler 로그를 확인하세요.
  • WAL 연산에 필요한 디스크 여유 공간을 확인하세요.

속성:

  • 적용 위치: Ruler WAL
  • 재시도 가능 여부: 예 (ruler 재시작 후)
  • HTTP 상태: N/A
  • 테넌트별 설정: 아니요

Kafka 통합 오류

이 오류들은 Loki가 수집에 Kafka를 사용하도록 설정됐을 때 발생해요.

오류: Missing Kafka address

오류 메시지:

the Kafka address has not been configured

원인:

Kafka 수집이 활성화됐는데 Kafka 브로커 주소가 설정되지 않았어요.

해결 방법:

  • Kafka 주소를 설정하세요:

    kafka_config:
      topic: loki-logs
      reader_config:
        address: kafka:9092
      writer_config:
        address: kafka:9092
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Missing Kafka topic

오류 메시지:

the Kafka topic has not been configured

원인:

Kafka 수집이 활성화됐는데 토픽 이름이 설정되지 않았어요.

해결 방법:

  • Kafka 토픽을 설정하세요:

    kafka_config:
      topic: loki-logs
      reader_config:
        address: kafka:9092
      writer_config:
        address: kafka:9092
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Inconsistent SASL username and password

오류 메시지:

both sasl username and password must be set

원인:

SASL(Simple Authentication and Security Layer) 사용자 이름과 비밀번호 중 하나만 설정돼 있어요. 둘은 함께 설정해야 해요.

해결 방법:

  • 사용자 이름과 비밀번호를 모두 설정하세요:

    kafka_config:
      sasl_username: my-user
      sasl_password: ${KAFKA_PASSWORD}
    
  • SASL 인증이 필요 없다면 둘 다 제거하세요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Kafka enabled in distributor but not in ingester

오류 메시지:

kafka is enabled in distributor but not in ingester

원인:

Kafka가 distributor에는 설정됐지만 ingester는 Kafka에서 읽도록 설정되지 않았어요. 둘은 함께 설정해야 해요.

해결 방법:

  • distributor와 ingester 둘 다 Kafka를 활성화하세요:

    distributor:
      kafka_writes_enabled: true
    
    ingester:
      kafka_ingestion:
        enabled: true
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid producer max record size bytes

오류 메시지:

the configured producer max record size bytes must be a value between 1048576 and 15983616

원인:

kafka_config.producer_max_record_size_bytes 값이 허용 범위를 벗어났어요.

해결 방법:

  • producer_max_record_size_bytes를 허용 범위 안으로 설정하세요:

    kafka_config:
      producer_max_record_size_bytes: 15983616
    
  • 개발 환경에서 테스트하는 게 아니라면 이 값은 기본값으로 두는 걸 강력히 권장해요.

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid producer max inflight requests per broker

오류 메시지:

the configured producer max inflight requests per broker must be greater than or equal to 1

원인:

kafka_config.producer_max_inflight_requests_per_broker 값이 1보다 작아요.

해결 방법:

  • producer_max_inflight_requests_per_broker를 1 이상으로 설정하세요:

    kafka_config:
      producer_max_inflight_requests_per_broker: 20
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid producer linger

오류 메시지:

the configured producer linger must be greater than or equal to 0

원인:

kafka_config.producer_linger 값이 음수예요.

해결 방법:

  • producer_linger를 0 또는 양수 duration으로 설정하세요:

    kafka_config:
      producer_linger: 50ms
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Partition ring required for Kafka writes

오류 메시지:

partition ring is required for kafka writes

원인:

distributor.kafka_writes_enabled가 true인데 distributor가 partition ring 없이 시작됐어요. 보통 partition ring 키-값 스토어가 distributor와 ingester 간에 일관되게 설정되지 않았다는 뜻이에요.

해결 방법:

  • distributor와 ingester 양쪽에 partition ring 키-값 스토어를 설정하세요:

    ingester:
      kafka_ingestion:
        enabled: true
        partition_ring:
          kvstore:
            store: memberlist
    
  • Kafka 기반 수집에 참여하는 모든 컴포넌트(distributor, ingester, querier, ruler)가 동일한 키-값 스토어 설정을 사용하도록 확인하세요.

속성:

  • 적용 위치: Distributor 시작
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Single entry size exceeds maximum

오류 메시지:

single entry size (%d) exceeds maximum allowed size (%d)

원인:

단일 로그 라인이 설정된 kafka_config.producer_max_record_size_bytes보다 커요. Loki는 큰 쓰기 요청을 여러 Kafka 레코드로 분할하지만, 단일 로그 라인은 여러 레코드에 걸쳐 분할할 수 없어요.

해결 방법:

  • Loki로 보내기 전에 소스에서 로그 라인 크기를 줄이세요.

  • limits_config.max_line_size(기본값: 256KB)로 최대 로그 라인 크기를 강제하세요. 이 한도를 초과하는 라인은 Kafka producer에 도달하기 전에 폐기돼요. 폐기 대신 넘치는 라인을 잘라내려면 limits_config.max_line_size_truncate: true로 설정하세요:

    limits_config:
      max_line_size: 256KB
      max_line_size_truncate: true
    
  • Kafka 클러스터가 더 큰 레코드를 지원한다면 허용 범위 안에서 producer_max_record_size_bytes를 늘리세요:

    kafka_config:
      producer_max_record_size_bytes: 15983616
    

속성:

  • 적용 위치: Kafka 레코드 인코딩
  • 재시도 가능 여부: 아니요
  • HTTP 상태: 400 (Bad Request)
  • 테넌트별 설정: 아니요 (limits_config.max_line_size와 limits_config.max_line_size_truncate는 테넌트별 설정 가능)

오류: Dataobj builder topic required

오류 메시지:

topic is required

원인:

컬럼형 스토리지에 사용되는 실험적 data object builder가 활성화됐는데 이를 위한 Kafka 토픽이 설정되지 않았어요.

해결 방법:

  • data object builder의 토픽을 설정하세요:

    dataobj:
      builder:
        topic: loki-logs
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Ingest-limits configuration errors

오류 메시지:

num partitions must be greater than 0
consumer group must be set
topic must be set

원인:

선택 기능인 ingest-limits 서비스가 활성화됐는데(ingest_limits.enabled: true) 필요한 Kafka 설정 중 하나 이상이 빠졌거나 잘못됐어요.

해결 방법:

  • 필요한 ingest-limits Kafka 설정을 모두 구성하세요:

    ingest_limits:
      enabled: true
      num_partitions: 64
      consumer_group: ingest-limits
      topic: loki-ingest-limits
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Ingest-limits readiness errors

오류 메시지:

waiting to be assigned some partitions
partitions are not ready

원인:

ingest-limits 서비스가 partition ring 합류를 아직 끝내지 못했거나, 할당된 파티션 중 하나 이상이 준비되지 않았어요. 보통 시작 중이나 롤링 재시작 동안의 일시적인 상태예요.

해결 방법:

  • 서비스가 시작을 끝내길 기다리세요. partition ring이 안정되면 이 오류들은 저절로 사라져요.
  • 오류가 계속되면 ingest-limits 서비스와 Kafka 브로커 사이의 연결을 확인하고, 설정된 partition ring 키-값 스토어에 접근 가능한지 확인하세요.

속성:

  • 적용 위치: Ingest-limits 서비스 준비 상태 검사
  • 재시도 가능 여부: 예 (시작 중 일시적)
  • HTTP 상태: 503 (Service Unavailable)
  • 테넌트별 설정: 아니요

오류: Generic Kafka protocol errors

오류 메시지:

unexpected response type
malformed response

원인:

Kafka 클라이언트가 브로커로부터 예상하지 못한 응답을 받았거나 파싱할 수 없었어요. 보통 Loki의 Kafka 클라이언트(franz-go)가 완전히 지원하지 않는 프로토콜 버전을 쓰는 Kafka(또는 Kafka 프로토콜 호환 브로커)를 가리키거나, 응답을 손상시킨 네트워크 문제를 가리켜요.

해결 방법:

  • Kafka 브로커 버전을 Loki의 Kafka 클라이언트(franz-go)가 지원하는 버전과 비교해 보세요.
  • Loki와 Kafka 브로커 사이에 패킷 손실이나 잘림이 있는지 네트워크 연결을 확인하세요.

속성:

  • 적용 위치: Kafka 클라이언트 (오프셋 매니저)
  • 재시도 가능 여부: 예
  • HTTP 상태: N/A
  • 테넌트별 설정: 아니요

Bloom gateway 오류

Bloom gateway 오류는 쿼리 가속을 위해 bloom filter를 사용할 때 발생해요.

오류: Invalid bloom gateway addresses

오류 메시지:

addresses requires a list of comma separated strings in DNS service discovery format with at least one item

원인:

bloom_gateway.client.addresses 설정 필드가 비어 있거나 설정되지 않았어요.

해결 방법:

  • 유효한 주소를 설정하세요:

    bloom_gateway:
      client:
        addresses: dns+bloom-gateway:9095
    

    유효한 형식:

    • dns+hostname:port - DNS 기반 디스커버리
    • host1:port,host2:port - 정적 목록

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Request time range must span exactly one day

오류 메시지:

request time range must span exactly one day

원인:

bloom 블록이 구성되는 방식 때문에 bloom gateway 요청은 정확히 하루치 데이터에 대한 것이어야 해요.

해결 방법:

  • 보통 bloom querier가 여러 날짜에 걸친 쿼리를 게이트웨이로 보내기 전에 하루 단위 요청으로 분할해서 자동으로 처리해요. 이 오류가 보인다면:
    • querier가 제대로 설정돼 있는지 확인하세요
    • 쿼리가 querier를 통해 라우팅되는지 확인하세요

속성:

  • 적용 위치: Bloom gateway
  • 재시도 가능 여부: 아니요
  • HTTP 상태: 500 Internal Server Error
  • 테넌트별 설정: 아니요

오류: From time must not be after through time

오류 메시지:

from time must not be after through time

원인:

bloom gateway가 시작 시간(from)이 종료 시간(through)보다 뒤인 요청을 받았어요.

해결 방법:

  • 잘못된 형태의 요청이 bloom gateway에 도달했다는 뜻이에요. 요청을 보내는 클라이언트가 from ≤ through로 시간 범위를 올바르게 구성하는지 검증하세요.

속성:

  • 적용 위치: Bloom gateway
  • 재시도 가능 여부: 아니요
  • HTTP 상태: 500 Internal Server Error
  • 테넌트별 설정: 아니요

Write-ahead log(WAL) 오류

WAL 오류는 ingester가 자신의 write-ahead log를 제대로 관리하지 못할 때 발생해요.

오류: WAL is stopped

오류 메시지:

wal is stopped

원인:

WAL이 중지된 후에 그에 대한 연산이 시도됐어요. 보통 종료 과정이나 치명적인 오류 이후에 발생해요.

해결 방법:

  • 오류가 있는지 ingester 상태와 로그를 확인하세요.
  • 디스크 여유 공간을 확인하세요.
  • 나쁜 상태에 있다면 ingester를 재시작하세요.

속성:

  • 적용 위치: Ingester WAL
  • 재시도 가능 여부: 예 (ingester 재시작 후)
  • HTTP 상태: 500 Internal Server Error
  • 테넌트별 설정: 아니요

오류: Invalid checkpoint duration

오류 메시지:

invalid checkpoint duration: <duration>

원인:

WAL checkpoint duration이 잘못된 값(아마 0이나 음수)으로 설정돼 있어요.

해결 방법:

  • 유효한 checkpoint duration을 설정하세요:

    ingester:
      wal:
        checkpoint_duration: 5m
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Invalid disk full threshold

{{< admonition type="note" >}} disk_full_threshold 설정 옵션은 Loki 3.7에서 도입됐어요. 이 오류는 이전 릴리스에서는 발생하지 않아요. {{< /admonition >}}

오류 메시지:

invalid disk full threshold: <value> (must be between 0 and 1)

원인:

WAL 디스크 가득 임계값이 유효 범위를 벗어난 값으로 설정돼 있어요. 유효한 값은 0과 1 사이(양 끝 포함)예요. 0은 스로틀링을 비활성화하고, 0보다 큰 값은 쓰기가 스로틀되는 디스크 용량 비율을 의미해요.

해결 방법:

  • 유효한 임계값을 설정하세요:

    ingester:
      wal:
        disk_full_threshold: 0.9  # 90%
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

Ingester 생명주기 오류

Ingester 생명주기 오류는 ingester 시작, 종료, 상태 전환 중에 발생해요.

오류: Ingester is shutting down

오류 메시지:

Ingester is shutting down

원인:

ingester가 종료 과정에 있어서 더 이상 쓰기를 받지 않아요. 이 오류(ErrReadOnly로도 알려져 있어요)는 우아한 종료 중에 push 요청이 도착하면 돌려줘요. 이 기간 동안 ingester는 메모리에 들고 있는 데이터에 대한 읽기는 계속 처리할 수 있어요.

해결 방법:

  • 백오프를 두고 재시도하도록 클라이언트를 설정하세요. distributor는 다른 정상 ingester로 라우팅해요.
  • 종료가 끝나고 새 인스턴스가 시작되길 기다리세요.
  • 종료가 예상된 것인지 확인하세요 (롤링 업데이트, 스케일링 이벤트).
  • 예상 밖이라면 OOM kill이나 헬스 체크 실패가 있는지 오케스트레이터 로그를 확인하세요.

속성:

  • 적용 위치: Ingester
  • 재시도 가능 여부: 부분적으로. distributor는 복제 집합의 모든 ingester에 병렬로 쓰기를 보내고 쿼럼 모델을 사용해요. 남은 ingester가 최소 성공 임계값을 충족하면 종료 중인 ingester의 이 오류에도 불구하고 전체 쓰기는 성공해요.
  • HTTP 상태: 500 Internal Server Error
  • 테넌트별 설정: 아니요

오류: Ingester is stopping or already stopped

오류 메시지:

Ingester is stopping or already stopped.

원인:

ingester의 종료 관리 엔드포인트(POST /loki/api/v1/ingester/shutdown)가 ingester가 Running 상태가 아닐 때 호출됐어요. 진행 중인 종료 도중에 두 번째로 호출되거나 ingester가 이미 멈춘 뒤에 호출될 때 발생해요. 이 오류는 로그 쓰기나 쿼리 경로가 아니라 종료 엔드포인트가 돌려주는 거예요.

해결 방법:

  • 종료가 이미 진행 중이라면 종료 엔드포인트를 다시 호출하지 마세요.
  • 중복 종료 신호나 재시작 정책이 있는지 오케스트레이터를 확인하세요.
  • 중지가 예상 밖이라면 (pod 축출, OOM, 크래시) 조사하세요.

속성:

  • 적용 위치: Ingester 종료 엔드포인트
  • 재시도 가능 여부: 아니요 (종료 엔드포인트 호출 자체는 재시도할 수 없어요. 새 쓰기를 보내기 전에 ingester가 재시작되기를 기다리세요)
  • HTTP 상태: 503 Service Unavailable (종료 엔드포인트의 응답)
  • 테넌트별 설정: 아니요

오류: Failed to start partition reader

오류 메시지:

failed to start partition reader: <details>

원인:

ingester가 Kafka partition reader를 시작하지 못했어요. Kafka 수집이 활성화됐는데 partition reader 초기화에 실패할 때 발생해요.

해결 방법:

  • ingester에서 Kafka 연결을 확인하세요.

  • Kafka 토픽이 존재하고 ingester에 적절한 권한이 있는지 검증하세요.

  • Kafka 설정을 검토하세요:

    kafka:
      address: kafka:9092
      topic: loki-logs
    
  • Kafka 브로커 상태를 확인하세요.

속성:

  • 적용 위치: Ingester 시작
  • 재시도 가능 여부: 아니요 (설정이나 인프라를 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Failed to start partition ring lifecycler

오류 메시지:

failed to start partition ring lifecycler: <details>

원인:

ingester가 시작 중에 Kafka partition ring lifecycler를 시작하지 못했어요. 이건 partition reader와 별개의 컴포넌트로, partition ring에서 ingester의 멤버십을 관리해요. Kafka 수집이 활성화된 경우에만 발생해요.

해결 방법:

  • ingester에서 Kafka 연결을 확인하세요.
  • partition ring에 쓰이는 KV 스토어가 도달 가능한지 검증하세요.
  • <details>에 감싸인 오류가 있는지 ingester 로그를 검토하세요.
  • Kafka 브로커 상태와 파티션 가용성을 확인하세요.

속성:

  • 적용 위치: Ingester 시작
  • 재시도 가능 여부: 아니요 (설정이나 인프라를 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Lifecycler failed

오류 메시지:

lifecycler failed: <details>

원인:

ingester의 lifecycler(ring 멤버십을 관리해요)가 치명적인 오류를 만났어요. 이러면 ingester가 ring에 참여할 수 없어요.

해결 방법:

  • KV 스토어 연결을 확인하세요 (Consul, etcd, memberlist).
  • 구체적인 lifecycler 오류가 있는지 ingester 로그를 검토하세요.
  • 모든 ingester에서 ring 설정이 일관된지 검증하세요.
  • 근본 문제를 고친 뒤 ingester를 재시작하세요.

속성:

  • 적용 위치: Ingester lifecycler
  • 재시도 가능 여부: 예 (수정과 재시작 후)
  • HTTP 상태: N/A (내부 실패)
  • 테넌트별 설정: 아니요

Pattern ingester 오류

Pattern ingester 오류는 자동 로그 패턴 탐지에 pattern ingester를 사용할 때 발생해요.

오류: Pattern ingester replication factor must be 1

오류 메시지:

pattern ingester replication factor must be 1

원인:

pattern ingester가 1이 아닌 복제 계수로 설정돼 있어요. 현재 pattern ingester는 복제 계수 1만 지원해요.

해결 방법:

  • 복제 계수를 1로 설정하세요:

    pattern_ingester:
      lifecycler:
        ring:
          replication_factor: 1
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Pattern ingester retain-for too short

오류 메시지:

retain-for (<duration>) must be greater than or equal to chunk-duration (<duration>)

원인:

pattern ingester의 retain_for duration이 max_chunk_age보다 짧아서 데이터 손실이 생길 수 있어요.

해결 방법:

  • max_chunk_age만큼 길거나 더 길도록 retain-for duration을 늘리세요:

    pattern_ingester:
      retain_for: 15m   # Must be >= max_chunk_age
      max_chunk_age: 5m
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Pattern ingester chunk-duration too short

오류 메시지:

chunk-duration (<duration>) must be greater than or equal to sample-interval (<duration>)

원인:

pattern ingester의 max_chunk_age가 pattern_sample_interval보다 짧아요. 청크가 최소 하나의 샘플 간격을 포함해야 데이터를 담을 수 있어요.

해결 방법:

  • pattern_sample_interval만큼 길거나 더 길도록 max_chunk_age를 늘리세요:

    pattern_ingester:
      max_chunk_age: 1h     # Must be >= pattern_sample_interval (default: 1h)
      pattern_sample_interval: 10s  # default: 10s
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

오류: Pattern ingester volume threshold out of range

오류 메시지:

volume_threshold (<value>) must be between 0 and 1

원인:

volume_threshold 값이 0과 1 사이의 유효 범위를 벗어났어요. 이 설정은 pattern ingester가 추적할 로그 볼륨의 비율을 조절해요. 로그 볼륨 상위 X%를 차지하는 패턴만 영속화돼요.

해결 방법:

  • volume_threshold를 0과 1 사이 값으로 설정하세요 (기본값은 0.99):

    pattern_ingester:
      volume_threshold: 0.99
    

속성:

  • 적용 위치: 설정 검증
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

API 파라미터 오류

이 오류들은 API 요청에 잘못된 파라미터가 있을 때 발생해요.

오류: Invalid direction

오류 메시지:

invalid direction '<value>'

원인:

direction 쿼리 파라미터에 잘못된 값이 들어 있어요.

해결 방법:

  • 유효한 direction 값을 사용하세요:

    • forward - 오래된 것부터 최신 순
    • backward - 최신 것부터 오래된 순 (기본값)
    curl "http://loki:3100/loki/api/v1/query_range?query={job=\"app\"}&direction=forward"
    

속성:

  • 적용 위치: API 핸들러
  • 재시도 가능 여부: 아니요 (요청을 고쳐야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Limit must be a positive value

오류 메시지:

limit must be a positive value

원인:

limit 파라미터가 0이거나 음수예요.

해결 방법:

  • 양수 limit을 제공하세요:

    curl "http://loki:3100/loki/api/v1/query_range?query={job=\"app\"}&limit=100"
    

속성:

  • 적용 위치: API 핸들러
  • 재시도 가능 여부: 아니요 (요청을 고쳐야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: End timestamp must not be before start time

오류 메시지:

end timestamp must not be before or equal to start time

원인:

쿼리의 end 시간이 start 시간과 같거나 그보다 앞이에요.

해결 방법:

  • 종료 시간이 시작 시간보다 뒤가 되도록 확인하세요:

    curl "http://loki:3100/loki/api/v1/query_range?\
    query={job=\"app\"}&\
    start=2024-01-01T00:00:00Z&\
    end=2024-01-02T00:00:00Z"
    

속성:

  • 적용 위치: API 핸들러
  • 재시도 가능 여부: 아니요 (요청을 고쳐야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Delay for tailing too large

오류 메시지:

delay_for can't be greater than <max>

원인:

tailing 쿼리의 delay_for 파라미터가 최대 허용 값을 초과했어요.

해결 방법:

  • delay_for 값을 줄이세요:

    curl "http://loki:3100/loki/api/v1/tail?query={job=\"app\"}&delay_for=5"
    

    최댓값은 보통 5초예요.

속성:

  • 적용 위치: API 핸들러
  • 재시도 가능 여부: 아니요 (요청을 고쳐야 해요)
  • HTTP 상태: 400 Bad Request
  • 테넌트별 설정: 아니요

오류: Query filtering requires compactor address

오류 메시지:

query filtering for deletes requires 'compactor_grpc_address' or 'compactor_address' to be configured

원인:

삭제 요청에 대한 쿼리 시점 필터링이 활성화됐지만 Loki가 활성 삭제 요청을 가져오려고 compactor에 도달하는 방법을 모르는 상태예요.

해결 방법:

  • compactor 주소를 설정하세요:

    compactor:
      compactor_grpc_address: compactor:9095
    
  • 또는 HTTP 주소를 사용하세요:

    compactor:
      compactor_address: http://compactor:3100
    

속성:

  • 적용 위치: 모듈 초기화
  • 재시도 가능 여부: 아니요 (설정을 고쳐야 해요)
  • HTTP 상태: N/A (시작 실패)
  • 테넌트별 설정: 아니요

더 알아보기 (Learn more)