Skip to content

로그 모니터링 시스템 구축

나경호(Na Gyeongho) edited this page May 27, 2025 · 1 revision

로그 모니터링 시스템 구축 가이드

Loki, Promtail, Grafana를 이용한 로그 모니터링 시스템 구축 방법을 정리하겠습니다.

1. 각 구성 요소의 역할과 필요성

Loki의 역할과 필요성

Loki는 로그 집계 시스템으로, 다음과 같은 역할을 담당합니다:

  1. 로그 저장:
    • Promtail 등에서 수집한 로그 데이터를 효율적으로 저장합니다.
    • 텍스트 로그를 압축하여 저장 공간을 최소화합니다.
  2. 인덱싱:
    • 로그 내용 자체가 아닌 라벨(메타데이터)을 기반으로 인덱싱합니다.
    • 이를 통해 저장 공간과 처리 리소스를 절약합니다.
  3. 쿼리 처리:
    • LogQL이라는 쿼리 언어를 통해 저장된 로그를 검색할 수 있는 API를 제공합니다.
    • 라벨 기반 필터링과 텍스트 검색을 지원합니다.

Loki가 필요한 이유:

  • 경량 설계: Prometheus와 유사한 라벨 기반 접근 방식으로 리소스 효율성이 높습니다.
  • 비용 효율성: 전체 텍스트 인덱싱을 하지 않아 스토리지 비용이 저렴합니다.
  • 통합성: Grafana와 원활하게 통합되어 로그와 메트릭을 함께 확인할 수 있습니다.

Promtail의 역할과 필요성

Promtail은 로그 수집 에이전트로서 다음과 같은 역할을 수행합니다:

  1. 로그 수집:
    • 로컬 파일 시스템이나 컨테이너의 로그 파일을 실시간으로 읽고 변화를 감지합니다.
    • 여러 로그 파일을 동시에 모니터링할 수 있습니다.
  2. 로그 전처리:
    • 수집된 로그에 라벨(job, app, level 등)을 추가하여 구조화합니다.
    • 이러한 라벨은 나중에 Grafana에서 필터링과 검색을 용이하게 합니다.
  3. Loki 전송:
    • 처리된 로그를 Loki 서버로 전송합니다.
    • 인증 정보를 관리하고 안전한 연결을 유지합니다.

Promtail이 필요한 이유:

  • 분산 시스템 지원: 여러 서버에서 생성되는 로그를 중앙 집중식으로 수집할 수 있습니다.
  • 중복 방지: 로그 파일 위치를 추적하여 시스템 재시작 후에도 중복 없이 로그를 수집합니다.
  • 자원 효율성: 로그 수집에 필요한 리소스를 최소화하도록 설계되었습니다.

Grafana의 역할과 필요성

Grafana는 데이터 시각화 및 모니터링 플랫폼으로 다음과 같은 역할을 담당합니다:

  1. 데이터 시각화:
    • 다양한 데이터 소스(Loki, Prometheus 등)의 정보를 그래프, 차트, 테이블 등으로 시각화합니다.
    • 로그 데이터를 보기 쉽게 표시하고 검색할 수 있는 인터페이스를 제공합니다.
  2. 대시보드 관리:
    • 커스터마이즈 가능한 대시보드를 통해 여러 데이터를 한 화면에서 모니터링할 수 있습니다.
    • 템플릿 변수를 사용하여 동적 대시보드를 구성할 수 있습니다.
  3. 알림 설정:
    • 특정 조건이 충족될 때 알림을 발생시키는 규칙을 설정할 수 있습니다.
    • 이메일, Slack 등 다양한 채널로 알림을 전송할 수 있습니다.

Grafana가 필요한 이유:

  • 통합 모니터링: 로그, 메트릭, 트레이스 데이터를 하나의 인터페이스에서 확인할 수 있습니다.
  • 사용자 친화적 UI: 기술적 지식이 적은 사용자도 쉽게 데이터를 탐색할 수 있습니다.
  • 확장성: 다양한 플러그인과 데이터 소스 연결을 지원해 확장 가능한 모니터링 환경을 구축할 수 있습니다.

2. 모니터링 시스템 구축 방법

네트워크 설정

먼저 Docker 컨테이너 간 통신을 위한 네트워크를 생성합니다:

docker network create loki-monitoring

Loki 설정 및 실행

설정 파일 (/home/ubuntu/loki/config/loki-config.yml):

auth_enabled: true

server:
  http_listen_port: 3100

common:
  path_prefix: /loki

ingester:
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 5m
  chunk_retain_period: 30s

schema_config:
  configs:
    - from: 2023-12-01
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: loki_index_
        period: 24h

storage_config:
  boltdb_shipper:
    active_index_directory: /loki/index
    cache_location: /loki/cache
  filesystem:
    directory: /loki/chunks

limits_config:
  max_global_streams_per_user: 10000
  allow_structured_metadata: false

compactor:
  working_directory: /loki/compactor

# 인증 설정 추가
auth:
  type: basic
  basic:
    username: depromeet_loki_prod
    password: depromeet_loki_pw03241

실행 명령어:

docker run -d \
  --name loki \
  --network monitoring \
  -p 3100:3100 \
  -v /home/ubuntu/loki/config/loki-config.yml:/etc/loki/local-config.yml \
  -v loki-data:/loki \
  grafana/loki:2.9.2 -config.file=/etc/loki/local-config.yaml

Loki 설정 파일 설명

파일 경로: /home/ubuntu/loki/config/loki-config.yml

auth_enabled: true
  • 인증 기능을 활성화합니다. true로 설정하면 인증된 요청만 Loki API에 접근할 수 있습니다.
server:
  http_listen_port: 3100
  • Loki 서버가 HTTP 요청을 수신하는 포트를 3100으로 설정합니다.
common:
  path_prefix: /loki
  • Loki가 데이터를 저장하는 기본 디렉토리 경로를 /loki로 설정합니다.
ingester:
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 5m
  chunk_retain_period: 30s
  • ingester: 로그 데이터 수집 및 저장 담당 컴포넌트 설정
  • store: inmemory: 인제스터 상태 정보를 메모리에 저장 (단일 인스턴스에 적합)
  • replication_factor: 1: 로그 데이터 복제본 수를 1로 설정 (복제 없음)
  • chunk_idle_period: 5m: 5분 동안 비활성 상태인 청크(로그 묶음)를 디스크로 내보냄
  • chunk_retain_period: 30s: 청크가 디스크로 내보내진 후 30초 동안 메모리에 유지
schema_config:
  configs:
    - from: 2023-12-01
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: loki_index_
        period: 24h
  • schema_config: 로그 데이터 저장 방식 설정
  • from: 2023-12-01: 이 스키마 설정을 2023년 12월 1일부터 적용
  • store: boltdb-shipper: BoltDB를 인덱스 저장소로 사용
  • object_store: filesystem: 실제 로그 데이터는 파일시스템에 저장
  • schema: v11: 스키마 버전 11 사용
  • index.period: 24h: 24시간마다 새 인덱스 파일 생성
storage_config:
  boltdb_shipper:
    active_index_directory: /loki/index
    cache_location: /loki/cache
  filesystem:
    directory: /loki/chunks
  • storage_config: 스토리지 상세 설정
  • active_index_directory: 활성 인덱스 파일 저장 위치
  • cache_location: 인덱스 캐시 저장 위치
  • directory: 로그 데이터 청크 저장 위치
limits_config:
  max_global_streams_per_user: 10000
  allow_structured_metadata: false
  • limits_config: 시스템 제한 설정
  • max_global_streams_per_user: 사용자당 최대 10,000개의 로그 스트림 허용
  • allow_structured_metadata: 구조화된 메타데이터 비활성화
compactor:
  working_directory: /loki/compactor
  • compactor: 오래된 인덱스 파일을 압축하는 컴포넌트 설정
  • working_directory: 압축 작업을 위한 임시 디렉토리
auth:
  type: basic
  basic:
    username: depromeet_loki_prod
    password: depromeet_loki_pw03241
  • auth: 인증 설정
  • type: basic: 기본 인증(사용자명/비밀번호) 방식 사용
  • username/password: Loki 접근을 위한 인증 정보

Grafana 설정 및 실행

설정 파일 (/home/ubuntu/grafana/config/grafana.ini):

# 익명 접근 설정
[auth.anonymous]
enabled = false  # 익명 사용자 접근 비활성화 (로그인 필요)

# 기본 인증 설정
[auth.basic]
enabled = true

실행 명령어:

docker run -d \
  --name grafana \
  --network monitoring \
  -p 3000:3000 \
  -v /home/ubuntu/grafana/config/grafana.ini:/etc/grafana/grafana.ini \
  -v grafana-data:/var/lib/grafana \
  grafana/grafana:10.2.0

Grafana 설정 파일 설명

파일 경로: /home/ubuntu/grafana/config/grafana.ini

[auth.anonymous]
enabled = false
  • auth.anonymous: 익명 접근 설정
  • enabled = false: 익명 사용자의 Grafana 접근 비활성화 (로그인 필수)
[auth.basic]
enabled = true
  • auth.basic: 기본 인증 설정
  • enabled = true: 사용자명/비밀번호 기반 인증 활성화

Promtail 설정 및 실행

설정 파일 (/home/ubuntu/promtail/config/promtail-config.yml):

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push
    basic_auth:
      username: depromeet_loki_prod
      password: depromeet_loki_pw03241

scrape_configs:
  - job_name: all_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: all_logs
          app: took
          __path__: /var/log/*.log

  - job_name: error_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: error_logs
          app: took
          level: error
          __path__: /var/log/error.log

  - job_name: warn_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: warn_logs
          app: took
          level: warn
          __path__: /var/log/warn.log

  - job_name: http_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: http_logs
          app: took
          __path__: /var/log/http-trace.log

  - job_name: blocking_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: blocking_logs
          app: took
          __path__: /var/log/blocking.log

실행 명령어:

docker run -d \
  --name promtail \
  --network monitoring \
  -v /home/ubuntu/promtail/config/promtail-config.yml:/etc/promtail/config.yml \
  -v ~/logs:/var/log \
  -v promtail-positions:/tmp \
  grafana/promtail:2.9.2 -config.file=/etc/promtail/config.yml

Promtail 설정 파일 설명

파일 경로: /home/ubuntu/promtail/config/promtail-config.yml

server:
  http_listen_port: 9080
  grpc_listen_port: 0
  • server: Promtail 서버 설정
  • http_listen_port: 9080: HTTP API 서버가 사용할 포트
  • grpc_listen_port: 0: gRPC 통신을 비활성화 (0은 사용하지 않음을 의미)
positions:
  filename: /tmp/positions.yaml
  • positions: 로그 파일 읽기 위치 관리
  • filename: 각 로그 파일을 어디까지 읽었는지 기록하는 파일 경로
clients:
  - url: http://loki:3100/loki/api/v1/push
    basic_auth:
      username: depromeet_loki_prod
      password: depromeet_loki_pw03241
  • clients: 로그를 전송할 대상 설정
  • url: Loki 서버의 API 엔드포인트 (Docker 네트워크 내에서 컨테이너 이름으로 접근)
  • basic_auth: Loki 서버에 접근하기 위한 인증 정보
scrape_configs:
  - job_name: all_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: all_logs
          app: took
          __path__: /var/log/*.log
  • scrape_configs: 로그 수집 설정
  • job_name: 작업 식별자
  • targets: 로그 대상 호스트 (로컬 파일이므로 localhost)
  • labels: 수집 로그에 추가할 메타데이터
    • job: 작업 유형 라벨
    • app: 애플리케이션 식별자
    • __path__: 수집할 로그 파일 경로 패턴

나머지 job_name 항목들(error_logs, warn_logs, http_logs, blocking_logs)은 각각 다른 유형의 로그 파일을 별도로 수집하기 위한 설정입니다. 각 항목마다 고유한 라벨과 파일 경로가 지정되어 있어 Grafana에서 로그 유형별 필터링이 가능합니다.

3. 시스템 작동 원리

전체 로그 모니터링 시스템은 다음과 같은 흐름으로 작동합니다:

애플리케이션 → 로그 파일 → Promtail → Loki → Grafana → 사용자
  1. 로그 생성: 애플리케이션이 /var/log/ 디렉토리에 로그 파일을 생성합니다.
  2. 로그 수집: Promtail이 설정된 경로(__path__)에서 로그 파일을 모니터링하고 새로운 로그를 감지합니다.
  3. 로그 전송: Promtail은 수집한 로그에 라벨을 추가하여 Loki로 전송합니다. 이때 설정된 인증 정보를 사용합니다.
  4. 로그 저장: Loki는 받은 로그를 저장하고 라벨 기반으로 인덱싱합니다.
  5. 시각화: GrafanaLoki에 쿼리하여 로그 데이터를 시각화하고 분석 도구를 제공합니다.

이 구성을 통해 애플리케이션의 다양한 로그(에러, 경고, HTTP 요청, 블로킹 이슈)를 효과적으로 모니터링하고 분석할 수 있습니다. 각 컴포넌트는 Docker 네트워크(monitoring)를 통해 서로 통신하며, Loki의 인증 설정으로 보안도 강화되어 있습니다.

Clone this wiki locally