끄적이는 메모장

서버 로그 다루기 - filebeat 편 본문

인프라 공부/ELK

서버 로그 다루기 - filebeat 편

밥보92 2023. 5. 1. 17:07
반응형

아래와 같은 분산환경에서 로그를 가장 효율적으로 중앙화시킬 수 있는 로그 수집기는 무엇일까?

Filebeat 

- 로그 전송을 위해 설계된 매우 경량화 된 log collector이다.

- 특정 위치에서 로그를 수집하고 이를 logstashs 혹은 elasticsearch에 전송하는 것에 최적화되어 있다.

- 하나 이상의 input에서 간단한 데이터 후처리를 할 수 있으며, 데이터를 인덱싱 후 전송한다. 

 

1) 리눅스에서 설치하기 

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.7.0-linux-x86_64.tar.gz
tar xzvf filebeat-8.7.0-linux-x86_64.tar.gz

2) filebeat.yml 파일을 수정하여 fileabeat 동작 정의 하기 

A. inputs 설정하기 

  • 어떤 source에서 log를 수집할 것인지에 대한 정보를 기술한다. 
filebeat.inputs:
- type: log
  enabled: true  
  paths:
    - /home/user/apps/logs/app.log
  • 가장 기본적으로 type과 path만 기술해 놓은 형태이다. 
  • 수집한 로그를 별도의 처리 없이 바로 전송하게 된다. 

위의 inputs 설정은 간단하고, 문제없이 ES까지 전송이 될 수 있다. 단, 최종적으로 저장된 로그가 매우 정돈되지 못하고 보기 힘든 로그가 되어 있을 수 있다. 

  • 실제 로그 발생시간과 최종 로그의 timestamp는 상당히 수 밀리초 ~ 초의 차이가 있을 것이다. 
  • 로그 레벨, 시간, 로그 위치 등이 뒤섞인 message로 저장이 될 것이다. 

만약, outputs을 logstash로 설정할 예정이며 logstash에서 log를 가공할 예정이라면 위의 걱정은 잊어도 좋다

하지만 로그를 직접 ES로 전송을 원한다면 우리는 몇 가지 작업을 통해 정돈된 로그를 ES로 전송해주어야 한다. 

 

B. Log를 JSON 형태로 남기자

  • 프로젝트의 언어, 프레임워크에 따라 지원하는 라이브러리의 유무가 갈릴 수 있지만, 적어도 level, timestamp, message 정도는 각 field로 구분된 JSON 형태로 로그를 남기도록 한다. 
{"timestamp":"2023-05-01T16:43:56.932Z","level":"INFO","thread":"SpringApplicationShutdownHook","logger":"org.ehcache.core.EhcacheManager","message":"Cache 'test' removed from EhcacheManager.","context":"default"}
  • JSON으로 남겨진 로그는 filebeat가 로그를 읽을 때 디코딩하여 json 필드 아래에 위치시킨다. 

C. Json 로그를 최상위에 위치시키고 중복되는 fields는 내가 정의한 값으로 덮어쓰기 하기

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /home/user/apps/logs/app.log    
  json.keys_under_root: true
  json.add_error_key: true
  json.overwrite_keys: true
  • json.keys_under_root : json 필드 내에 있던 실제 로그를 최상위 루트로 위치 시킨다. (ES의 검색, kibana에서의 message 노출을 위함이다.)
  • json.overwrite_keys : 겹치는 fields가 있다면 서버가 정의한 값으로 덮어쓰기 시킨다.
  • 여기까지 진행이 되었다면 ES에 직접 로그를 전송하더라도 여러 정보가 섞인 로그를 보지는 않을 것이다. (field별로 정돈되어 검색이 편한 로그가 되어있다.)
  • 하지만 로그 시간은 여전히 예상과는 다른 시간이 찍혀있을 것이다. (filebeat가 ES로 전송한 시간이 곧 로그의 시간으로 지정되기 때문이다.)

D. 로그 시간을 일치시키기 

  • inputs의 processors는 간단한 로그의 후처리를 지원한다. 
  • timestamp를 일치시키고자 하는 작업은 다음과 같다. 
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /home/user/apps/logs/app.log    
  json.keys_under_root: true
  json.add_error_key: true
  json.overwrite_keys: true
  processors:
    - timestamp:
        field: timestamp
        layouts:
          - '2006-01-02T15:04:05.999Z'
        test:
          - '2023-04-21T14:46:57.039Z'
        timezone: Local
  • 내 로그의 timestamp field의 값을 filebeat가 파싱 하여 실제 ES에 저장될 timestamp에 지정해주는 내용이다. 
  • field에는 로그에서 날짜가 기록되어 있는 field의 명을 기술한다. 
  • layouts에는 현재 내 로그가 남기고 있는 날짜 형식을 기술한다. 
    • 중요한 건 yyyy-MM-dd 이런 형식이 아닌, 특정 날짜로 기입을 해야 한다는 것이다. 
    • "2006년 01월 02일 15시 04분 05초 999"를 서버 로그가 남기고 있는 날짜 형식으로 기술해 준다. 
    • 존재하는 단위까지만 기술하면 된다. 
  • test를 지정해 주면 실제 시간에 대한 파싱이 성공했을 때 filebeat를 구동해 준다. 
  • timezone 설정에 따라 로그를 +09:00에서 찾아야하는 경우도 있기 때문에 구동 환경에 따른 테스트를 다양하게 해보길 바란다. 

E. outputs 설정하기 

  • ES의 host와 설정할 index를 지정해 준다. 
  • 경우에 따라서 보안정보를 기술할 수도 있다. 
output.elasticsearch:
  hosts: ["es-host:es-port"]
  username: es-id
  password: es-password
  index: "test-%{+yyyy.MM.dd}"
  • ilm 정책에 따른 전송 실패가 발생하는 경우 setup.ilm.enabled: false 설정을 최하단에 해준다.

전체 예시

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /home/user/apps/logs/app.log    
  json.keys_under_root: true
  json.add_error_key: true
  json.overwrite_keys: true
  processors:
    - timestamp:
        field: timestamp
        layouts:
          - '2006-01-02T15:04:05.999Z'
        test:
          - '2023-04-21T14:46:57.039Z'
        timezone: Local
    
output.elasticsearch:
  hosts: ["es-host:es-port"]
  username: es-id
  password: es-password
  index: "test-%{+yyyy.MM.dd}"
  
logging:
  level: error
  to_files: false
  to_stderr: true
  
setup.ilm.enabled: false

3) 실행 

sudo chown root filebeat.yml 
sudo ./filebeat -e
  • 실행 권한을 root 유저로 지정해준 후 실행을 한다. 
반응형

'인프라 공부 > ELK' 카테고리의 다른 글

서버 로그 다루기 - Fluentd 편  (0) 2021.03.27