프로젝트/여행지 오픈 API

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

블랑v 2023. 11. 23. 16:08

 

경로 맞추기

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

 

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를 제거하자, 문제가 해결되는 것을 확인할 수 있었다.

 

 

결과 : 실시간 로그 추가

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

 

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

 

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