Grafana+Promtail+loki 를 사용한 이유
로그 수집을 하기 위한 기술을 뽑으자면 ELK(Elasticsearch, Logstash, Kibana)를 떠올릴 수 있다.
하지만 서버 스펙의 한계(Ec2 프리티어)로, 비교적 가볍게 실행할 수 있는 PromTail, Loki, Grafana를 도입하게 되었다.
모니터링 서버는 다음과 같다. 모니터링 서버에는 Grafana, Loki를 도커로 띄우고, 운영 서버에는 Promtail과 스프링 부트가 도커로 돌아가게 된다. 모니터링 서버를 분리한 이유는 Promtail, Grafana, Loki 같은 로그/메트릭 수집 도구는 많은 I/O와 네트워크 트래픽을 발생시키기 때문에 분리하였다.
(모니터링 서버)에 Grafana, Loki 도커로 실행하기
docker run -d --name=grafana -p 3000:3000 grafana/grafana
- Grafana를 3000번 포트로 도커 명령어로 실행한다.
docker run -d --name=loki -p 3100:3100 grafana/loki
- Loki를 3100번 포트로 도커 명령어로 실행한다.
이때 EC2는 인바운드 규칙으로 3000번과 3100번이 열어져 있어야 한다!
(배포 서버)에 Promtail 도커로 실행하기
배포 서버는 로그 파일을 Promtail을 통해 loki로 보내게 된다.
Promtail을 통해서 로그 파일을 보내보자.
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://{모니터링 서버 IP}:3100/loki/api/v1/push # Loki 서버 IP로 변경
scrape_configs:
- job_name: jenkins_logs
static_configs:
- targets:
- localhost
labels:
job: jenkins
service: {서비스 이름으로 변경/아무 작명 가능} 예시) kurum
log_type: info
__path__: {로깅 파일 위치} 예시) /var/log/kurum/info/*.log
promtail.config.yml 파일을 다음과 같이 만든다.
모니터링 대상 서버의 IP, 로깅 파일 위치를 적어준다.
docker-compose-promtail.yml
Promtail을 도커로 실행하기 위한 세팅을 진행해야 한다.
services:
promtail:
image: grafana/promtail:latest
container_name: promtail # 컨테이너 이름 지정 (선택 사항)
restart: unless-stopped # 컨테이너가 중지되지 않도록 설정
volumes:
- /volume1/docker/jenkins/custom/kurum/logs:/var/log/kurum # 로깅 파일이 있는 서버내 위치
- /var/run/docker.sock:/var/run/docker.sock # Docker 컨테이너 정보 접근
- ./promtail-config.yml:/etc/promtail/promtail-config.yml # promtail-config.yml 마운트
command: -config.file=/etc/promtail/promtail-config.yml
ports:
- "9080:9080" # Promtail의 HTTP 인터페이스 포트 (필요한 경우)
~
volume에서, 로깅 파일을 해당 도커 컨테이너로 마운트를 시켜줘야 한다.
Ec2 내에서 /volume1/docker/jenkins/custom/kurum/logs 파일 안에 log 파일이 있으니, 도커 내 /var/log/kurum으로 마운트 했다.
현재 Promtail-config.yml 파일이 존재하는 현재디렉터리(./promtail-config.yml)을 마운트 했다.
도커 컴포즈 파일 실행하기
docker-compose -f docker-compose-promtail.yml up -d
를 통해 docker 파일을 실행 가능하다.
스프링 LogBack 이용해서 파일에 저장하기
[src/main/resources/logback.xml]
log 파일을 저장하려면 logback.xml을 작성해야 한다.
info 내용을 오늘날짜.log 파일로 저장하게 된다.
configuration>
<property resource="logback-variables.properties" />
<timestamp key="ToDay" datePattern="yyyyMMdd" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
${LOG_PATTERN}
</Pattern>
</layout>
</appender>
<appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<file>${LOG_PATH}/info/${ToDay}_${LOG_FILE_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_PATH}/info/%d{yyyyMMdd}_${LOG_FILE_NAME}_%i.log
</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE1" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
[src/main/resources/logback-variables.properties]
LOG_PATH = ./logs
LOG_FILE_NAME = sample-logger
LOG_PATTERN = %d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger{36}] - %msg%n
현재 로그 파일을 저장할 주소 ./logs로 지정한다.
Loki로 모니터링 하기
'프로젝트 > Ku:room' 카테고리의 다른 글
메시지 큐 도입기 - 비동기 로깅 처리 및 알림 기능 (RabbitMQ, Kafka, Redis Pub/Sub 비교) (0) | 2025.03.14 |
---|---|
N+1 문제 해결하기 (@EntityGraph 사용) (0) | 2025.02.27 |
Jacoco를 이용한 테스트 커버리지 측정후, 보완하기 (0) | 2025.02.24 |
스프링 인터셉터(Spring Interceptor)로 API로그 DB에 저장하기 (0) | 2025.02.24 |
인터셉터에서 RequestBody를 Read 하지 못하는 이유 및 해결방법 (0) | 2025.02.20 |