본문 바로가기

프로젝트/여행지 오픈 API

[Logstash] 로그스태시로 로그 뽑아서 저장하기

목차

     

    경로 맞추기

    내 스프링부트 컨테이너 내부 경로와 외부 마운팅할 파일 경로를 맞춰줘야 한다.

     

    sudo docker exec -it elastic-container /bin/bash 를 통해 접속한 결과 

    이런 식으로 기본 루트 디렉토리가 /app임을 확인할 수 있다.

    이는 당연한데, 도커파일이 다음과 같이 정의되었기 때문이다.

    따라서 나는 경로를 /app/log/logfiles.log로 저장하고자 한다.

    <도커파일>
    
    # 기본 이미지로 Java 11을 사용합니다..
    FROM openjdk:11-jre-slim
    
    # 작업 디렉토리를 설정합니다.
    WORKDIR /app
    
    # 이 폴더를 외부 볼륨 마운팅 하는 폴더로 설정합니다.
    VOLUME ["/app/logs"]
    
    # 호스트 머신에서 JAR 파일을 복사합니다.
    COPY build/libs/*.jar app.jar
    
    # JAR 파일 실행
    CMD ["java", "-jar", "app.jar"]

     

    본체 스프링부트의 파일 업로드 경로 역시도 'app/logs/..' 하위에 저장하도록 logback을 설정하였다.

     

     

    젠킨스 파이프라인 수정

     

    Deploy 과정에서 재빌드 시 외부의 볼륨과 연동하게 하였다.

      stage('Deploy') {
                steps {
                    sh "docker run -v /home/ubuntu/filelogs:/app/logs --name ${CONTAINER_NAME} -d -p 127.0.0.1:8081:8080 ${IMAGE_NAME}"
                }
    
                post {
                    success {
                        echo 'deploy success'
                    }
    
                    failure {
                        echo 'deploy failed'
                    }
                }
            }

     

     

    이제 컨테이너 내부의 log 파일과, ubuntu 자체의 폴더가 매핑되어 로그파일을 제어할 수 있다.

     

     

     

    로그스태시 파일 만들기

     

    Logstash 설치: 우선 Logstash를 설치한다.

     

    https://www.elastic.co/guide/en/logstash/7.11/installing-logstash.html

     

    Installing Logstash | Logstash Reference [7.11] | Elastic

    Use the echo method described above to add the Logstash repository. Do not use add-apt-repository as it will add a deb-src entry as well, but we do not provide a source package. If you have added the deb-src entry, you will see an error like the following:

    www.elastic.co

     

    Logstash 설정 파일 생성: Logstash의 주요 작업은 설정 파일을 통해 수행된다.

    logstash.conf라는 이름의 설정 파일을 만들자. 'logstash/logstash.conf' 로 생성하였다.

     

    file 생성

      GNU nano 4.8                                                                 logstash.conf                                                                 Modified  
    input {
      file {
        #path 경로 설정
        path => "/home/ubuntu/filelogs/logfile.log"
        start_position => "beginning"
        sincedb_path => "/dev/null"
        ignore_older => 0
      }
    }
    
    #grok을 사용한 필터 설정. 로그의 패턴에 맞춰 필요한 데이터만 추출하
    filter {
      grok {
        match => { "message" => "%{TIMESTAMP_ISO8601:timestamp},%{DATA:thread},%{JAVACLASS:class},%{DATA:controller},%{DATA:method},%{IP:client_ip}" }
      }
      date {
        match => [ "timestamp", "YYYY-MM-dd HH:mm:ss.SSS" ]
        target => "@timestamp"
      }
    }
    
    #Output설정
    
    output {
      elasticsearch {
        hosts => ["https://k9b205a.p.ssafy.io/"]  # Elasticsearch 호스트
        index => "user_used_log"  # 인덱스 패턴
        user => "id"
        password => "pw"
      }
    # Logstash가 처리하는 데이터를 실시간으로 콘솔에 출력하여, 데이터 파이프라인이 올바르게 작동하는지 확인
      stdout { codec => rubydebug }
    }

     

    실행

    /usr/share/logstash/bin/logstash -f /home/ubuntu/logstash/logstash.conf

     

     

    오류 권한 문제

     

    오류 메시지: Your settings are invalid. Reason: Path "/usr/share/logstash/data" must be a writable directory. It is not writable.

     

    https://discuss.elastic.co/t/i-cannot-start-logstash-on-my-machine-error-message-inside/88900

     

    I cannot start logstash on my machine. Error message inside

    The following is the test command from the tutorial: ./logstash -e 'input { stdin { } } output { stdout {} }' The following is the error. WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify t

    discuss.elastic.co

     

    sudo chown -R logstash.logstash /usr/share/logstash
    sudo chmod 777 /usr/share/logstash/data

     

    문제 상황 발생 :9200 포트 추가

    로그스태시로 output을 보낼 때, 자꾸 9200포트를 추가해서 보냈다.

    www.naver.com이  원래 기대한 주소였다면, www.naver.com:9200으로  로 보내는 것이다.

    이를 해결하기 위해 본체 서버에 9200 포트로 받아, 리버스 프록싱하는 코드를 추가로 구현했다.

    conf 파일은 다음과 같다.

    # HTTP 트래픽을 HTTPS로 리디렉션
    server {
        listen 80;
        server_name k9b205a.p.ssafy.io;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # HTTPS 설정
    server {
        listen 443 ssl;
        server_name k9b205a.p.ssafy.io;
    
        ssl_certificate /etc/letsencrypt/live/k9b205a.p.ssafy.io/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/k9b205a.p.ssafy.io/privkey.pem;
    
        # kibana 리버스 프록시 설정
        location /kibana/ {
            proxy_pass http://localhost:5601;
            proxy_http_version 1.1;
    #       proxy_set_header Authorization "Basic aWZyYW1lOmlmcmFtZQ==";
          proxy_set_header Authorization "Basic Y3NnMTM1Mzo1MUB0bHJsY2tk";
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    
        # Elasticsearch 리버스 프록시 설정
        location / {
            proxy_pass http://localhost:9201;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;용
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
    
    # 9200 포트에서 SSL/TLS 트래픽을 처리하는 별도의 서버 블록 -> 본체 로그스태시 수집
    server {
        listen 9200 ssl;
        server_name k9b205a.p.ssafy.io;
    
        ssl_certificate /etc/letsencrypt/live/k9b205a.p.ssafy.io/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/k9b205a.p.ssafy.io/privkey.pem;
    
        location / {
            proxy_pass http://localhost:9201;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }

     

    문제 해결 1 : 프록시 헤더 설정

    에러가 났던 부분인데, 프록시 설정을 추가로 해 주어야 했다.\

    이는 로그스태시가 정보를 보내면서 Header에 아이디와 비밀번호의 정보를 보내기 때문이다. 처음에는 이를 배제하고 보냈다가 Security 에러에 직면했다.

        # Elasticsearch 리버스 프록시 설정
        location / {
            proxy_pass http://localhost:9201;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

     

     

    문제 해결 2 : 프록시 제거..

    1을 해결하는 과정에서 확인했던 내용.

    GPT가 logstash.conf 파일을 만드는 과정에서 에러가 난 걸 

    "output {
      elasticsearch {
        hosts => ["https://k9b205a.p.ssafy.io/"]
        proxy => "https://k9b205a.p.ssafy.io/"

       .. 이하 생략

    " 이렇게 프록시 값을 추가해보라고 조언했었다.

    하지만 이는 결과적으로 잘못된 조언이었는데, 

     

    로그를 보니 프록시 설정으로 인해 정보들이 해시 값으로 들어오는 것 같다...

     

    프록시 설정을 하고, nginx log를 확인하자 다음과 같이 해시 값의 요청이 들어오는 것을 확인할 수 있었다.

     

    ' [WARN ] 2023-11-24 02:11:54.033 [Ruby-0-Thread-9: :1] elasticsearch - Attempted to resurrect connection to dead ES instance, but got an error {:url=>"https://csg1353:xxxxxx@k9b205a.p.ssafy.io:9200/", :exception=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :message=>"Elasticsearch Unreachable: [https://k9b205a.p.ssafy.io:9200/][Manticore::UnknownException] Unsupported or unrecognized SSL message"}'

     

    이런 식으로 logstash에도 에러 로그가 발생하기도 했다. 

    output에서 proxy를 제거하자, 문제가 해결되는 것을 확인할 수 있었다.

     

     

    결과 : 실시간 로그 추가

    실시간으로 요청 로그가 수집되는 모습을 확인할 수 있다

     

    물론 인덱스에 저장도 잘 된다.

     

    이를 통해 실시간 사용 로그 데이터를 수집해서 유의미한 결과로 도출할 수 있게 되었다!