로그 모니터링의 필요성
프로젝트를 진행하며 클라이언트와 엔드포인트를 연결하고 성능테스트를 하는 과정에서 수많은 오류들을 겪었다. 이때마다 매번 서버에 접속해서 로그를 읽는데 로그가 너무 쌓여 가독성도 좋지 못하고, 접속하는 과정 자체만으로도 시간이 소요되었기 때문에 생산성이 많이 떨어지게 됐다. 이로 인해 로그의 모니터링을 구축하고 이를 적용하는 과정을 기록하고자 글을 쓰게 되었다.
Loki
Loki는 프로메테우스로부터 영감을 받아 만들어진 그라파나 랩에서 만든 오픈소스다. 수평적으로 확장이 가능하며 가용성이 높은 여러 테넌트(사용자 그룹)를 지원하는 로그 집계 시스템이며, 자원을 굉장히 효율적으로 사용하며 운영이 쉽게 설계되어 있다. 또한 elasticsearch와는 다르게 log의 컨텐츠를 인덱싱 하지 않으며 로그 시스템의 label(레이블)을 설정하여 로그 집계를 할 수 있다.
아래와 같은 이유로 로키를 사용하고자 한다.
ELK 스택이 로그 시장을 점유하고 있는 가운데, 내가 느낀 Loki만의 차별점은 다음과 같다.
- 사용이 매우 쉽다.
- ELK 같은 경우 노드 설정, 로그 스태시 파이프 라이닝 과정이 처음 하기에는 좀 어렵다고 느껴졌는데 loki는 단순한 만큼 사용도 쉬운 것 같다.
- 그 대신 유연한 검색은 ELK가 더 우월한듯
- 자원을 매우 효율적으로 사용한다.
- 링크에 따르면 0.5 코어, 128MB RAM이 최소 스펙인 것을 보니 elaticsearch에 비해 자원을 정말 효율적으로 사용한다.
위 구조는 Loki가 elasticsearch에 비해 가벼운 이유 중 하나로 메타정보만 인덱스하도록 강제되어 있어, 전체를 설정을 통해 구성하는 elasticsearch에 비해 빠르고 간결하며 적은 저장소를 필요로 하는 구조를 갖는다.
- Promtail을 통한 로그수집, Prometheus와 동일한 Service Discovery 사용
- Loki에 로그 저장, 인덱스구조를 데이터 소스별 인덱싱만 지원하여 작게 저장되고 매우 빠름
- LogQL 을 통한 조회, 특화언어로 Grafana에서 직접연동도 가능
- 로그 기반 알람, Loki가 실시간 감시하고 이를 AlertManger를 통해 알람전달
Promtail
Promtail은 로컬 로그의 내용을 Grafana Loki 인스턴스 또는 Grafana Cloud로 전송하는 에이전트다. 일반적으로 모니터링해야 하는 애플리케이션을 실행하는 모든 머신에 배포된다.
Promatail이 타겟(특정 파일)을 바라보고 있고, promtail 내의 레이블(label) 설정이 올바르게 됐으면 해당 파일을 읽기 시작한다. promtail은 파일을 일괄적(batch)으로 읽으며 충분한 데이터를 읽었을 경우(설정한 timeout, memory를 기준으로 충분함을 판단) 플러시가 일어나 Loki로 적재된다.
또한, Promtail이 마지막으로 읽은 데이터의 offset은 positions.yaml 파일에 저장이 되며 이는 Promtail 인스턴스가 재시작 하더라도 데이터를 지속적으로 읽을 수 있게 한다.
Promtail은 웹 또한 웹서버를 내장하고 있는데 다음의 API 엔드포인트를 통해 접근이 가능하다.
GET /ready
Promtail이 정상적으로 구동되며 target을 하나 이상 바라보고 있을 경우 200 code로 응답한다.
GET /metrics
이 엔드포인트는 Promtheus로 전송할 수 있는 promtail의 metrics 정보를 담으며 어떠한 metrics 정보가 노출되는지 Observing Grafana Loki에서 확인이 가능하다.
Promtail의 자세한 내용은 링크에서 확인할 수 있다.
사용해보기
먼저 promtail, loki를 설치하자
https://github.com/grafana/loki/releases
docker를 사용하지 않는 경우 Assets 항목에서 OS에 맞는 파일을 다운받도록 하자. 나는 window 용으로 설치했다.
로키 설정(아래는 기본 설정이고 로그를 file에 저장할지, S3에 저장할지 등 저장소에 대한 설정을 할 수 있고 로그에 대해 쿼리의 크기를 지정할 수 있으며 로그 파일의 삭제 정책, 압축 정책도 세밀하게 설정이 가능하다.)
auth_enabled: false
server:
http_listen_port: 3100 # 포트 번호 다르면 다르게 넣어주기
grpc_listen_port: 9096
common:
instance_addr: 127.0.0.1
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
query_range:
results_cache:
cache:
embedded_cache:
enabled: true
max_size_mb: 100
schema_config:
configs:
- from: 2020-10-24
store: tsdb
object_store: filesystem
schema: v12
index:
prefix: index_
period: 24h
ruler:
alertmanager_url: http://localhost:9093
# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration
# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/
#
# Statistics help us better understand how Loki is used, and they show us performance
# levels for most users. This helps us prioritize features and documentation.
# For more information on what's sent, look at
# https://github.com/grafana/loki/blob/main/pkg/analytics/stats.go
# Refer to the buildReport method to see what goes into a report.
#
# If you would like to disable reporting, uncomment the following lines:
#analytics:
# reporting_enabled: false
프롬테일 설정
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: ./positions.yaml # 로컬 환경에서 실행 경로에 positions.yaml 작성해줘야 함
clients:
- url: http://localhost:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: sample-log
__path__: C:\Users\doyeon\IdeaProjects\log-practice\logs\dev\dev.log # 로그 파일의 위치를 작성
# 다른 로그파일도 읽고 싶다면 job 추가하면 됨
실행
./promtail-windows-amd64 -config.file=promtail-local-config.yaml
./loki-windows-amd64 -config.file=loki-local-config.yaml
이제 그라파나도 켜주고 datasource를 추가한다.
그 다음 三에서 explorer에서 데이터 소스를 선택한 후 label에 따라 로그를 검색할 수 있다.
대시보드는 만드는 방법은 6 easy ways to improve your log dashboards with Grafana and Grafana Loki | Grafana Labs 여기서 잘 알려주니 참고하자.
위 방법을 통해 만든 대시보드는 실제 아래와 같은 화면으로 볼 수 있다. (로그 포맷팅을 lgfmt 방식으로 해야 함)
한번 적용할 때는 시간이 꽤 걸렸지만 이렇게 모니터링 대시보드를 구성해 놓으니 실제 개발 전체의 퍼포먼스가 많이 올라갔다고 느껴졌다.