이번글의 promtail은 다음을 따른다.
- promtail 설명 및 설치
- 로그 수집 기초
- loki 설명 및 설치
- loki 설정 기초
- LogQL
이번글에서 설명하는 내용은 2번이다.
1번을 먼저 읽고 오자
2. 로그 수집 기초
Promtail config
promtail --config.file=/path/to/config.yml
앞서 작성한 1번 글에서 command로 입력한 명령어가 있어야만 config.yml이 제대로 적용된다는걸 기억하자
오늘 볼 예시 log는?
2024-12-05 15:30:45.123 ERROR [com.example.service.UserService] (UserService.java:25) - Failed to fetch user details for ID: 12345
2024-12-05 15:31:10.567 INFO [com.example.controller.UserController] (UserController.java:50) - User login request received for ID: 12345
2024-12-05 15:31:45.999 DEBUG [com.example.repository.UserRepository] (UserRepository.java:80) - Executing query to find user by ID: 12345
이런 로그가 생성되는 springboot를 수집한다고 가정하고 시작하겠다.
아래 글을 읽기 전에 이걸 어떤식으로 labeling하면 좋을지 잠시 생각해보고 넘어가는것도 좋다.
설정파일 전문
server:
http_listen_port: 9080
grpc_listen_port: 0
clients:
- url: http://localhost:3100/loki/api/v1/push
positions:
filename: /tmp/promtail-positions.yaml
scrape_configs:
- job_name: spring-logs
static_configs:
- targets:
- localhost
labels:
job: spring-application
application: user-service
__path__: /var/log/spring/*.log
pipeline_stages:
- regex:
expression: '^(?P<timestamp>[^ ]+ [^ ]+\.\d+) (?P<level>[A-Z]+) \[(?P<class_name>[^ ]+)\] \((?P<file>[^:]+):(?P<line>\d+)\) - (?P<message>.*)'
- timestamp:
source: timestamp
format: '2006-01-02 15:04:05.000'
location: Asia/Seoul
- labels:
level:
class_name:
file:
line:
- output:
source: message
위 코드는 config파일이다. 부분적인 설명은 아래서 진행한다.
job_name을 통해서 여러가지를 볼수있다.
또한 지금 사용하는 방식은 같은 서버에 있는 log파일을 volume으로 mount해서 읽어오는 방식이고 다른 서버에 있는 파일을 읽어오는 방식은 따로 있으니 필요시 한번 알아보면 된다.
Server
Promtail이 요청을 수신하는 HTTP/GRPC 서버 포트를 설정한다.
server:
http_listen_port: 9080
grpc_listen_port: 0
외부에서 promtail로 요청을 보낼때 사용하게 된다. (컨테이너를 만들떄 port를 열거나 네트워크로 연결해야한다.)
역할 | HTTP 요청 (상태, 메트릭 제공 등) | gRPC 요청 (데이터 통신 등) |
기반 프로토콜 | HTTP/1.1 | HTTP/2 |
주요 사용 사례 | Prometheus 메트릭 조회, 상태 확인 | loki등이 gRPC 기반 데이터 수신 및 통신 |
비활성화 옵션 | 설정하지 않으면 기본값 사용 | 0으로 설정 시 비활성화 |
설정은 이렇게 비교할수 있다.
Clients
promtail이 요청을 보낼 엔드포인트를 정의한다.
clients:
- url: http://localhost:3100/loki/api/v1/push
지금 코드 방식은 loki로 보내는 방식이며 필요에 따라 변경하면 된다.
network를 연결했다면 아래 코드와 같이 컨테이너 이름으로 통신이 가능하다.
clients:
- url: http://loki:3100/loki/api/v1/push
Positions
pormtail이 재시작될때 읽던 위치을 기억하도록 하는 파일이다.
positions:
filename: /tmp/promtail-positions.yaml
미리 작성해둘 필요는 없다. 알아서 생성하고 작성한다.
Scrape_configs
어떻게 가져올지 설정하는 부분이다. scrape_configs에 여러 log들을 설정할 수 있다.
scrape_configs:
- job_name: spring-logs
static_configs:
- targets:
- localhost
labels:
job: spring-application
application: user-service
__path__: /var/log/spring/*.log
- job_name :작업의 이름으로 Grafana같은 곳에서 분류된다. 원하는 방식대로 적어주면 된다.
- static_configs: 정적으로 가져올 경우 정하면 된다. 동적 설정시 file_sd_configs를 사용할수 있다.
- targets: Promtail이 로그를 수집하는 대상이다. 지금 설정상으로는 형식적인 설정이다.
왜냐하면 path를 기본으로 파일수집을 하고있기 때문이다. 만약 원격으로 설정을 해줘야한다면 달라진다.
원격서버에 있는 로그를 받아올라면 여러 설정이 필요하기 떄문에 아래에서 설명하겠다. - lables: 로그에 기본적으로 추가되는 메타 데이터를 입력한다.
- job: 레이블의 이름이다. Loki등에서 이 레이블로 로그를 검색하거나 필터링 할 수 있다.
- application : 로그가 어떤 어플리케이션에서 생성되었는지 이름을 적으면 된다. 이또한 key값이 된다.
- __path__: 수집할 로그 파일의 경로이다. volume으로 마운트 해온 주소를 적으면 된다.
* 를 사용해서 로그파일을 여러개 수집할수도 있다.
Pipeline_stages
이부분은 주로 log를 labeling하는 부분임으로 더 세분화 해서 설명하겠다.
regex
로그를 정규식으로 분리한다. Go 언어의 정규식 패키지 기반으로 작동한다.
- regex:
expression: '^(?P<timestamp>[^ ]+ [^ ]+\.\d+) (?P<level>[A-Z]+) \[(?P<class_name>[^ ]+)\] \((?P<file>[^:]+):(?P<line>\d+)\) - (?P<message>.*)'
- timestamp: 로그의 타임스탬프 (예: 2024-12-05 15:30:45.123)
- level: 로그 레벨 (예: ERROR, INFO)
- class_name: 클래스 이름 (예: com.example.service.UserService)
- file: 파일 이름 (예: UserService.java)
- line: 코드 라인 번호 (예: 25)
- message: 로그 메시지 (예: Failed to fetch user details for ID: 12345)
상황에 따라 적으면 된다 ?<label 이름> 이런식으로 적으면 된다.
Timestamp
loki가 로그 기반 시계열 데이터베이스라 timestamp를 지정해줘서 데이터를 보내줘야 검색하기가 쉬워진다.
- timestamp:
source: timestamp
format: '2006-01-02 15:04:05.000'
location: Asia/Seoul
- source: timestamp 필드를 로그의 타임스탬프로 사용
- format: 로그의 타임스탬프 형식
- Golang의 time 패키지 형식을 따름
- 예: 2006-01-02 15:04:05.000 (밀리초 포함)
- location: 로그의 시간대를 Asia/Seoul로 지정
format는 자신이 원하는 방식으로 설정해줘도 된다.
location을 통해서 KST로 저장된 로그를 자동으로 UTC로 변환해서 loki로 보낸다.(-9시간이 자동으로 된다.)
loki에서 설정을 할때 loki의 time으로부터 +- 얼마정도 이상의 시간은 받아드리지 않음으로 이를 유의해야한다.
labels
위에서 ?P<> 로 지정한 값을을 라벨링할때 사용한다.
- labels:
level:
class_name:
file:
line:
정규식에서 추출한 값을 lebel로 추가하는 방식인데 공란으로 만들었을 경우 매핑 에러가 생길수도 있으니
pipeline_stages:
- regex:
expression: '^(?P<timestamp>[^ ]+ [^ ]+\.\d+) (?P<level>[A-Z]+) \[(?P<class_name>[^ ]+)\] \((?P<file>[^:]+):(?P<line>\d+)\) - (?P<message>.*)'
- timestamp:
source: timestamp
format: '2006-01-02 15:04:05.000'
- labels:
level: level
class: class_name
file: file
line: line
이렇게 적는게 에러 확률이 적다
Output
- output:
source: message
로그의 메세지 본문만 message 필드에 남긴다.
자주 발생하는 에러? 문의? 궁금증?
로그는 여러줄인데 로그를 1줄만 읽어 와요
2024-12-05 15:30:45.123 ERROR [com.example.service.UserService] (UserService.java:25) - Failed to fetch user details
java.lang.Exception: User not found
at com.example.service.UserService.getUser(UserService.java:25)
at com.example.controller.UserController.login(UserController.java:50)
이렇게 생긴 로그를 읽어와야하는데
2024-12-05 15:30:45.123 ERROR [com.example.service.UserService] (UserService.java:25) - Failed to fetch user details
이렇게 읽어오지 않는가?
pipeline_stages:
- multiline:
firstline: '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [A-Z]+'
max_wait_time: 5s
max_lines: 100
- regex:
expression: '^(?P<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) (?P<level>[A-Z]+)\s+(?P<class>.+?:\d+)\s+- (?P<message>[\s\S]*)'
- labels:
level:
class:
timestamp:
- output:
source: message
multiline을 사용하면 된다.
- firstline : 다중 라인 로그의 첫 번째 줄을 식별하는 정규식을 적을수 있다. 대부분의 로그는 시간값으로 시작하니 이런걸 적으면 된다.
- max_wati_time: 다중 라인을 병합하는 최대 대기 시간이다 로그가 오래동안 생긴 줄을 읽어야하면 늘려야한다.
- max_lines: 최대로 설정할 로그 라인 수이다.
No such file or directory
__path__에서 지정된 로그 파일 경로가 잘못되었거나 파일이 존재하지 않을 확률이 높다.
이는 경로설정이 잘못되었거나 권한이 없을수도 있으니 잘 확인해 보자
Failed to push logs to Loki
Loki와의 서버 문제이다. network를 확인하거나 api를 보내는 주소를 잘 확인해보자
High CPU or memory usage
불필요한 로그를 보낼때 생긴다
pipeline_stages:
- drop:
expression: 'status=200'
이런식으로 불필요한 부분이 있는 log는 안보낼 수 있다.
로그파일을 많이 읽어야 하는데 못읽어요
clients:
- url: http://localhost:3100/loki/api/v1/push
batchsize: 1048576
batchwait: 5s
한번에 전송하는 데이터 크기와 대기 시간을 조정해 성능을 최적화 한다.
고급
외부 log 파일 읽어오기
NFS 또는 CLFS를 통한 파일 공유
원격 서버의 로그 디렉토리를 Promtail 서버에 네트워크 파일 시스템으로 마운트 시킨다.
원격 서버에서 설정한다.
원격서버의 예시 ip : 192.168.0.10
1. /etc/exports 파일에서 로그 디렉토리를 공유시킨다.
/var/log *(rw,sync,no_root_squash)
2. NFS 서버 재시작
sudo systemctl restart nfs-server
3. Promtail 서버에서 NFS 마운트
sudo mount 192.168.0.10:/var/log /mnt/remote_logs
이제 마운트한 곳을 읽으면 된다.
SSHFS
ssh를 통해서 원격 서버의 디렉터리를 promtail 서버에 마운트 한다.
1. promtail 서버에서 ssh 키를 생성하고 원격 서버에 키를 복사한다.
ssh-keygen -t rsa
ssh-copy-id user@192.168.0.10
2. SSHGS로 디렉토리 마운트
sshfs user@192.168.0.10:/var/log /mnt/remote_logs
마운트 한 디렉토리를 읽으면 된다.
Syslog로 로그 전송
1. 원격 서버에서 Syslog 설정해서 /etc/rsyslog.conf에서 로그를 promtail 서버로 전송한다.
*.* @192.168.0.20:514
2. promtail에서 syslong 입력을 활성한다.
scrape_configs:
- job_name: syslog
syslog:
listen_address: 0.0.0.0:514
format: RFC5424
labels:
job: syslog_logs
HTTP API를 통한 로그 접근
원격 서버에서 HTTP API를 통해서 로그를 전송한다.
scrape_configs:
- job_name: http-remote-logs
http_sd_configs:
- url: http://192.168.0.10:8080/logs
refresh_interval: 5m
labels:
job: http_logs
로그를 받아오는 api를 호출하도록 설정한다.
Promtail 설치 및 Push 방식
원격서버에 promtail을 설치해서 전송하도록 한다.
scrape_configs:
- job_name: local-logs
static_configs:
- targets:
- localhost
labels:
job: local_logs
__path__: /var/log/app.log
clients:
- url: http://192.168.0.20:3100/loki/api/v1/push
정리
1. NFS 마운트 | 원격 서버의 로그 디렉터리를 NFS를 통해 Promtail 서버에 마운트 | - 설정이 간단. - 로컬 파일처럼 접근 가능 - 대규모 환경에서 안정적 |
- NFS 서버 필요 - 네트워크 연결 의존 - 권한 및 보안 관리 필요 |
2. SSHFS | SSH를 통해 원격 로그 디렉터리를 Promtail 서버에 마운트 | - 설정이 간단. - SSH로 안전한 연결. - 추가 서버 설치 불필요. |
- SSH 연결 상태 의존. - 성능이 다소 느릴 수 있음 - 대규모 환경에서 부적합 |
3. Syslog | 원격 서버에서 로그를 Syslog로 Promtail 서버로 전송 | - 네트워크 기반. - 실시간 로그 수집 가능. - 기존 Syslog 설정 재활용 가능. |
- 원격 서버에 Syslog 설정 필요 - 로그 형식 제한 가능 - 네트워크 트래픽 증가 |
4. HTTP API | 원격 서버가 로그를 HTTP 엔드포인트로 제공하고 Promtail이 주기적으로 요청 | - 간단한 구현 가능 - 인증 및 보안 관리 용이 - 로그 구조화 전송(JSON/XML 등) 가능 |
- 원격 서버에서 API 구현 필요 - 실시간 로그 전송 어려움 - 네트워크 요청 오버헤드 |
5. 원격 Promtail 설치 | 원격 서버에 Promtail을 설치하고 Loki 서버로 직접 로그 전송 | - 각 서버에서 독립적 동작 - 중앙 집중식 수집 - 실시간 전송 가능 - 대규모에 적합 |
- 각 서버에 Promtail 설치 필요 - 유지보수 및 설정 복잡 - 리소스 사용 증가 |
'Monitoring > Promtail' 카테고리의 다른 글
[Monitoring/Promtail] Promtail 설치 & 설명에 대한 모든 것 (1) (0) | 2024.12.05 |
---|
Coding, Software, Computer Science 내가 공부한 것들 잘 이해했는지, 설명할 수 있는지 적는 공간