Coti Lab
Loki Grafana 로그 수집
셀프호스팅

Loki + Grafana로 홈서버 로그 수집하기

Coti
5분

홈서버에 컨테이너가 10개, 20개씩 쌓이면 문제가 생겼을 때 docker logs 명령을 컨테이너 이름별로 하나하나 쳐봐야 하는 순간이 옵니다. Grafana Loki는 이 흩어진 로그를 한곳에 모으면서도, 로그 본문 전체가 아니라 라벨만 인덱싱하는 독특한 설계 덕분에 저사양 홈서버에서도 부담 없이 돌릴 수 있습니다. 그렇다면 Loki와 Grafana로 홈서버 로그를 어떻게 한곳에 모을 수 있을까요?

Loki는 무엇인가

Loki는 Grafana Labs가 만든 로그 집계 시스템으로, 로그 본문 전체를 인덱싱하는 대신 컨테이너 이름·호스트·서비스명 같은 라벨만 인덱싱해서 훨씬 가볍게 동작해요. Elasticsearch 같은 전통적인 로그 시스템은 로그에 담긴 모든 단어를 색인화하기 때문에 강력한 전문 검색이 가능한 대신 인덱스 크기가 로그 양에 비례해 빠르게 불어나요. Loki는 “Prometheus지만 로그용”이라는 설계 철학을 따라서, 지표를 라벨로 구분하듯 로그 스트림도 라벨로만 구분하고 실제 검색은 그 라벨로 좁혀진 로그를 순회하며 처리해요. 인덱스가 작다는 건 곧 디스크와 메모리 사용량이 작다는 뜻이라, 홈서버처럼 자원이 넉넉하지 않은 환경에 특히 잘 맞아요.

Prometheus 지표와 로그를 한 화면에서

Loki는 애초에 Grafana와 Prometheus로 구성한 지표 모니터링 스택과 나란히 쓰도록 설계됐어요. Prometheus가 “CPU 사용률이 갑자기 90%로 튀었다”는 이상 징후를 지표로 보여주면, 같은 Grafana 화면에서 시간 범위를 맞춰 Loki 패널로 전환해 그 순간의 실제 로그를 바로 확인할 수 있어요. 지표만으로는 “무슨 일이 있었는지”는 알 수 없고 “무언가 이상하다”는 신호만 주는데, 로그를 같은 타임라인 위에 겹쳐보면 원인 파악까지 이어지는 흐름이 자연스럽게 완성돼요.

Promtail/Alloy로 로그 수집하기

Loki 자체는 저장과 검색만 담당하고, 실제로 로그를 긁어모아 전송하는 역할은 별도의 에이전트가 맡아요. 전통적으로는 Promtail이 이 역할을 했지만 Grafana Labs가 여러 텔레메트리 수집기를 하나로 통합한 Grafana Alloy로 후속 전환을 진행하고 있어서, 새로 구축한다면 Alloy를 쓰는 걸 권장해요. Docker 환경에서는 컨테이너 로그 드라이버나 볼륨 마운트를 통해 /var/lib/docker/containers 경로를 읽어 각 컨테이너의 로그를 라벨과 함께 Loki로 전송하는 방식이 일반적이에요.

services:
  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yaml:/etc/loki/local-config.yaml
      - loki_data:/loki
    command: -config.file=/etc/loki/local-config.yaml

  promtail:
    image: grafana/promtail:latest
    volumes:
      - ./promtail-config.yaml:/etc/promtail/config.yaml
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    command: -config.file=/etc/promtail/config.yaml
    depends_on:
      - loki

volumes:
  loki_data:

홈서버 Docker 로그를 한곳에 모으기

Docker Compose로 여러 서비스를 홈서버 하나에 몰아 운영하다 보면 서비스마다 로그 포맷도 다르고 컨테이너 이름도 제각각이라 문제 상황에서 원인을 추적하기가 점점 번거로워져요. Promtail이 Docker 소켓을 통해 각 컨테이너에 container_name, compose_service 같은 라벨을 자동으로 붙여 Loki로 보내주면, Grafana의 Explore 화면에서 {compose_service="nginx"} 같은 라벨 쿼리 하나로 특정 서비스의 로그만 골라볼 수 있어요. 여러 터미널 창을 오가며 로그를 뒤지던 습관이, 브라우저 탭 하나로 정리되는 셈이에요.

LogQL로 검색하기

라벨로 로그 스트림을 좁힌 다음에는 LogQL이라는 쿼리 언어로 로그 본문 안의 특정 문자열이나 패턴을 검색할 수 있어요. {compose_service="nginx"} |= "500" 같은 쿼리를 쓰면 nginx 컨테이너 로그 중 “500”이라는 문자열이 포함된 줄만 걸러낼 수 있는 식이에요. 인덱스 자체는 라벨 수준에서만 만들어지지만 실제 텍스트 검색이 불가능한 건 아니라는 점이 Loki를 처음 접할 때 헷갈리기 쉬운 부분이에요.

결론

컨테이너별로 흩어진 로그를 뒤지던 습관을, 라벨 기반 인덱싱이라는 가벼운 구조 하나로 Grafana 화면 안에 모아넣을 수 있다는 게 Loki의 핵심 가치예요. Grafana+Prometheus로 지표를 보고 있다면 Loki를 얹어 지표와 로그를 같은 타임라인에서 함께 보는 구성을 완성할 수 있고, 반대로 지금 당장 단일 서버의 실시간 상태만 빠르게 확인하고 싶다면 Netdata 쪽이 더 가벼운 대안이 될 수 있어요.

자주 묻는 질문

Q1. Loki는 Elasticsearch를 대체할 수 있나요?

완전히 같은 용도는 아니에요. Elasticsearch는 로그 본문 전체를 인덱싱해 복잡한 전문 검색에 강하지만, Loki는 라벨만 인덱싱하는 대신 훨씬 가볍기 때문에 홈서버처럼 리소스가 제한된 환경에 더 적합해요.

Q2. 로그 원문도 검색할 수 있나요?

네, 라벨로 로그 스트림을 좁힌 뒤에는 LogQL로 로그 본문 안의 문자열이나 패턴도 검색할 수 있어요. 다만 이 과정은 인덱스가 아니라 실제 로그 데이터를 순회하며 처리돼요.

Q3. Promtail과 Grafana Alloy 중 뭘 써야 하나요?

새로 시작한다면 Grafana Alloy를 권장해요. Promtail은 유지보수 모드로 전환됐고, Alloy가 로그 수집을 포함한 통합 후속 에이전트로 자리잡고 있어요.

Q4. Prometheus가 있으면 Loki는 필요 없나요?

아니요, 둘은 다루는 데이터 종류가 달라요. Prometheus는 숫자로 된 지표를 수집하고 Loki는 텍스트로 된 로그를 수집해서, 지표에서 이상 징후를 발견한 뒤 같은 시간대의 로그를 Loki에서 바로 확인하는 식으로 함께 써요.

Q5. 컨테이너를 재시작하면 그동안의 로그가 사라지지 않나요?

아니요, Promtail이나 Alloy가 로그를 실시간으로 Loki에 전송해 별도 저장소에 쌓아두기 때문에 컨테이너가 재시작되거나 삭제돼도 Grafana에서 과거 로그를 계속 조회할 수 있어요.

Q6. 로그 보관 기간을 늘리면 디스크 용량이 급격히 늘어나나요?

라벨만 인덱싱하는 구조 덕분에 Elasticsearch 같은 완전 텍스트 인덱스보다는 증가 폭이 작아요. 그래도 로그 양이 많다면 retention 설정으로 보관 기간을 정해두는 게 안전해요.

C
Coti 백엔드 개발자
프로필

댓글

첫 번째 댓글을 남겨보세요!