2018년 5월 18일 금요일

Elastic Stack을 이용한 서버 에러 로그 대시보드 만들기

각 서버에 분산되어 있는 에러 로그를 FileBeat를 통해서 LogStash로 보내고, 데이터를 필터링 한 후 ElasticSearch에 저장한다. 저장 된 데이터를 Kibana를 통해서 시각화하여 각 서버에서 발생하고 있는 에러 로그를 통합해서 볼 수 있게 한다.

시스템 구조




설치 환경


  • ElasticSearch, LogStash, Kibana를 로그 집계를 위한 한 서버에 설치
    • CPU : Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz (듀얼코어)
    • RAM : 4GB
    • OS : Ubuntu 16.04 LTS
  • FileBeat를 로그가 발생하고 있는 각 서버에 설치
    • CPU : Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz (싱글코어)
    • RAM : 1GB
    • OS : Ubuntu 14.04 LTS, 16.04 LTS

사전 준비


  • 자바 설치 (Java 8 이상 필요, Oracle JDK 1.8.0_131 버전 권장)
    sudo add-apt-repository ppa:webupd8team/java
    sudo apt-get update
    sudo apt-get install oracle-java8-installer
    sudo apt-get install oracle-java8-set-default 
  • 자바 버전 확인
    java -version

설치


  • ElasticSearch
    • 설치 패키지 다운로드
      wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.deb
    • 패키지 설치
      sudo dpkg -i elasticsearch-6.2.4.deb
    • 서비스(시스템 시작 시 자동 시작) 등록 / 해제
      sudo systemctl daemon-reload
      sudo systemctl enable elasticsearch.service
      sudo systemctl disable elasticsearch.service
    • 서비스 시작 / 종료
      sudo systemctl start elasticsearch.service
      sudo systemctl stop elasticsearch.service
    • 설치 확인
      curl -X GET "localhost:9200/"
      {
        "name" : "Cp8oag6",
        "cluster_name" : "elasticsearch",
        "cluster_uuid" : "AT69_T_DTp-1qgIJlatQqA",
        "version" : {
          "number" : "6.2.4",
          "build_hash" : "f27399d",
          "build_date" : "2016-03-30T09:51:41.449Z",
          "build_snapshot" : false,
          "lucene_version" : "7.2.1",
          "minimum_wire_compatibility_version" : "1.2.3",
          "minimum_index_compatibility_version" : "1.2.3"
        },
        "tagline" : "You Know, for Search"
      }
  • Kibana
    • 설치 패키지 다운로드
      wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.4-amd64.deb
    • 패키지 설치
      sudo dpkg -i kibana-6.2.4-amd64.deb
    • 서비스 등록
      sudo systemctl daemon-reload
      sudo systemctl enable kibana.service
    • 서비스 시작
      sudo systemctl start kibana.service
    • 설치 확인
      인터넷 브라우저에서 localhost:5601로 접속해서 kibana 화면이 나오는지 확인

  • LogStash
    • 설치 패키지 다운로드
      wget https://artifacts.elastic.co/downloads/logstash/logstash-6.2.4.deb
    • 패키지 설치
      sudo dpkg -i logstash-6.2.4.deb
    • 서비스 등록
      sudo systemctl daemon-reload
      sudo systemctl enable logstash.service
    • 서비스 시작
      sudo systemctl start logstash.service


  • FileBeat
    • 설치 패키지 다운로드
      wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.4-amd64.deb
    • 패키지 설치
      sudo dpkg -i filebeat-6.2.4-amd64.deb
    • 서비스 등록
      sudo systemctl daemon-reload
      sudo systemctl enable filebeat.service
    • 서비스 시작
      sudo systemctl start filebeat.service



환경 설정

  • ElasticSearch
    • 설정 파일 수정
      sudo vi /etc/elasticsearch/elasticsearch.yml
      - ElasticSearch와 binding 할 IP 주소를 설정한다. (port는 수정 안 할 경우 기본 9200)
      network.host : 0.0.0.0
    • 서비스 재시작
      sudo systemctl restart elasticsearch.service
  • Kibana
    • 설정 파일 수정
      sudo vi /etc/kibana/kibana.yml
      - Kibana와 binding할 IP 주소를 설정한다. (port는 수정 안 할 경우 기본 5601)
      server.host : "0.0.0.0"
      elasticsearch.url : "http://elasticsearch_server_address:9200"
    • 서비스 재시작
      sudo systemctl restart kibana.service

  • LogStash
    • 설정 파일 생성
      sudo vi /etc/logstash/conf.d/[원하는 파일 명].conf
      input {
        beats {
          port => 5044
        }
      }
      
      filter {
        if [fields][server_name] == "api-server" {
          if [fields][log_type] == "nginx_access" {
            grok {
              match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\"\"%{DATA:[nginx][access][agent]}\""] }
              remove_field => "message"
            }
            mutate {
              add_field => { "read_timestamp" => "%{@timestamp}" }
            }
            date {
              match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
              remove_field => "[nginx][access][time]"
            }
            useragent {
              source => "[nginx][access][agent]"
              target => "[nginx][access][user_agent]"
              remove_field => "[nginx][access][agent]"
            }
            geoip {
              source => "[nginx][access][remote_ip]"
              target => "[nginx][access][geoip]"
            }
          }
        }
      }
      
      output {
        if([fields][server_name] == "api-server" and [fields][log_type] == "nginx_access") {
          elasticsearch {
            hosts => ["localhost:9200"]
            index => "new-api-access-log-%{+YYYY.MM.dd}"
          }
        }
        else {
          elasticsearch {
            hosts => ["localhost:9200"]
            index => "error-log-%{+YYYY.MM.dd}"
          }
        }
      }
      filebeat에서 로그 데이터를 받아서 nginx_access 로그만 별도의 index에 저장하고 나머지는 기본 index를 사용해서 elasticsearch에 저장 하는 설정

    • 서비스 재시작
      sudo systemctl restart logstash.service

  • FileBeat
    • 설정 파일 수정
      sudo vi /etc/filebeat/filebeat.yml
      filebeat.prospectors:
      - type : log
        enabled: true
        paths:
          - /var/log/php7.0-fpm.log
      
      
      - type : log
        enabled: true
        paths:
          - /var/log/nginx/error.log
        fields:
          server_name: api-server
          log_type: nginx_error
      
      #output.elasticsearch:
      
      output.logstash:
        hosts: ["logstash_server_address:5044"]
php-fpm, nginx에서 발생하는 에러 로그를 수집하기 위한 설정. 빨간색 부분은 추가 데이터를 지정하는 부분 kibana에서 server_name 별로 필터링해서 보여주고자 할 때 이런식으로 각 서버 마다 server_name을 다르게 설정하면, 원하는 서버만 필터링해서 보기 편하다. elasticsearch에 바로 데이터를 보내지 않고, logstash를 거치기 때문에 elasticsearch 설정은 주석 처리한다.

    • 모듈 사용 설정
      : 많이 사용하는 것들은 미리 module로 빼 놓았다. 지원 module 목록
      • nginx 모듈 사용 설정
        sudo filebeat modules enable nginx
      • 설정 된 모듈 확인
        sudo filebeat modules list
      • 초기 환경 설정
        sudo filebeat setup -e
      • 모듈 설정 파일 수정
        sudo vi /etc/filebeat/modules.d/nginx.yml
        - module: nginx
          # Access logs
          access:
            enabled: true
            prospector:
              fields:
                server_name: api-server
                log_type: nginx_access
    • 서비스 재시작
      sudo systemctl restart filebeat.service
  • Kibana
    • 접속
      웹 브라우저에 kibana_server_ip:5601 입력해서 접속
    • 설정
      • 데이터 불러오기
        • Management -> Index Partterns
        • + Create Index Pattern
        • Index pattern 입력 위의 설정대로 따라 했다면 new-api-access-log-YYYY.MM.dd
          error-log-YYYY.MM.dd


          두 가지 형태의 index가 생성되었을 것이다.
          pattern 입력을 한 후 Next step 버튼을 누른다.
        • Time filter field name 설정
      • 원하는 데이터 뽑아 내기
        • Discover -> index 선택
        • 원본 데이터 확인
        • 원하는 데이터만 뽑아서 보기 : 보고 싶은 필드를 확인하고 add를 누르면 해당 필드만 나온다.
        • 선택한 필드 데이터 보기
          미리 설정해 놓은 filebeat에서 추가로 설정한 fields.log_type, fields.server_name와 message만 보이도록 설정했다.
        • 해당 데이터 중 특정 값을 갖는 데이터만 보기

        • 필터링 결과 저장하기
      • 그래프 만들기
        • Visualize -> [+]
        • 원하는 그래프 선택
        • Index 선택
        • 그래프 설정
          error-log 를 서버 별로 필터링해서 막대 그래프로 표현

댓글 2개:

  1. 그림이 깨지네요... 그림이 안 깨진 게시글을 보고 싶습니다!!
    좋은 포스팅 감사합니다. 도움이 많이 되는 글이었습니다.

    답글삭제
    답글
    1. 안녕하세요. 오래된 글 읽어 주셔서 감사합니다.
      아래 링크에 새롭게 포스팅 된 글이 있습니다~^^
      https://link.medium.com/2uNVR25tKbb

      삭제