Nginx log를 모니터링 해보자

이우길·2022년 12월 27일
2

infra

목록 보기
5/6
post-thumbnail

Nginx Log with Prometheus, Grafana

Goal

  • Nginx의 AccessLog를 노출 시켜 Prometheus, Grafana를 이용하여 시각화 하기

Nginx의 Log

nginx는 요청이 들어올 때 마다 Log가 생성된다. nginx를 설치 후 별도의 설정을 하지 않는다면 nginx.conf파일에 http블록에 아래와 같이 로그에 대한 기본설정이 들어있을 것이다.

http {
    ...
    log_format  main  '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    ...
}

기본적으로 Nginx의 포맷에는 $request.time이 빠져있다. 공식문서에 따름면 $request.time를 아래와 같이 설명하고 있다.

$request_time – Full request time, starting when NGINX reads the first byte from the client and ending when NGINX sends the last byte of the response body

직역하자면 클라이언트에게 처음 요청이 들어와 RequestBody을 읽기 시작해서 ResponseBody의 마지막 byte가 쓰여지기 까지의 시간을 의미한다.

그렇기에 nginx의 로그 포멧에 추가해 주자. 최종적인 로그 포멧은 아래와 같다. (추가적으로 필요한 것은 공식문서를 참고하여 추가하면 된다.)

log_format  main    '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" "$request_time"';

Export 시키기

이전 글과 동일하게 Nginx의 로그를 사용하려면 exporter가 필요하다. 역시 이 또한 존재하기 때문에 가져다가 사용하면 된다. prometheus-nginxlog-exporter

# 설치 기준 v1.10.0
wget https://github.com/martin-helmich/prometheus-nginxlog-exporter/releases/download/v1.10.0/prometheus-nginxlog-exporter_1.10.0_linux_amd64.tar.gz

tar -xvf prometheus-nginxlog-exporter_1.10.0_linux_amd64.tar.gz

# Result
logger/
|-- LICENSE
|-- README.adoc
`-- prometheus-nginxlog-exporter

압축을 해제하면 prometheus-nginxlog-exporter 실행파일이 존재한다.

이전 metrics 정보를 export 시킬 때와 다르게 exporter를 실행시킬 때 설정을 적용시킬 수 있는 .yml을 별도로 작성할 수 있다. 해당 설정 파일에서는 port, endPoint, format, log파일 위치 등을 지정할 수 있다.

listen:
  # port: exporter를 노출시킬 port 설정 기본포트는 4040
  port: 4040
  # address: bindin 할 IP
  address: "0.0.0.0"
  # metrics_endpoint: metrics 정보를 서빙할 endPoint 기본설정은 "/metrics"
  metrics_endpoint: "/metrics"

# consul 사용여부
consul:
  enable: false

namespaces:
  # name: 추 후 Prometheus에서 query할 때 사용된다.
  - name: nginx
    # format: Nginx에서 사용하는 format을 동일하게 작성해준다.
    format: '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$request_time"'
    # source: log 파일의 위치를 정의한다.
    source:
      files:
        - /var/log/nginx/access.log

설정파일이 전부 작성되었다면 실행파일을 설정파일과 같이 실행시켜 준 후 curl로 요청을 보내면 정상적으로 작동하는 것을 확인할 수 있다.

$ ./prometheus-nginxlog-exporter -config-file prometheus-nginxlog-exporter.yml

$ curl localhost:4040/metrics

# 결과
# HELP nginx_http_response_count_total Amount of processed HTTP requests
# TYPE nginx_http_response_count_total counter
nginx_http_response_count_total{method="GET",status="304"} 63
# HELP nginx_http_response_size_bytes Total amount of transferred bytes
# TYPE nginx_http_response_size_bytes counter
nginx_http_response_size_bytes{method="GET",status="304"} 0
# HELP nginx_http_response_time_seconds Time needed by NGINX to handle requests
# TYPE nginx_http_response_time_seconds summary
nginx_http_response_time_seconds{method="GET",status="304",quantile="0.5"} 0
nginx_http_response_time_seconds{method="GET",status="304",quantile="0.9"} 0
nginx_http_response_time_seconds{method="GET",status="304",quantile="0.99"} 0
nginx_http_response_time_seconds_sum{method="GET",status="304"} 0
nginx_http_response_time_seconds_count{method="GET",status="304"} 63
# HELP nginx_http_response_time_seconds_hist Time needed by NGINX to handle requests
# TYPE nginx_http_response_time_seconds_hist histogram
nginx_http_response_time_seconds_hist_bucket{method="GET",status="304",le="0.005"} 63
nginx_http_response_time_seconds_hist_sum{method="GET",status="304"} 0
nginx_http_response_time_seconds_hist_count{method="GET",status="304"} 63
# HELP nginx_parse_errors_total Total number of log file lines that could not be parsed
# TYPE nginx_parse_errors_total counter
nginx_parse_errors_total 0
...

Prometheus 연결

이전 글에서 작성한 것과 같이 연결하면 된다. 설치는 생략하고 scrape_configs 부분을 설정해주면 된다.

# ...
scrape_configs:
  - job_name: "nginx"

    static_configs:
      - targets: ["localhost:4040"]
# ...

연결 후 프로메테우스에 접속해보면 정상적으로 수집하고 있는 것을 볼 수 있다.


Grafana 연결

이전 글에서 크게 벗어나는 것이 없으며 대쉬보드는 NGINX Log Metrics를 가져다 사용했다.


예상치 못한 삽질

위의 대쉬포드를 가져다가 사용할 때 삽질을 조금 하게 됬는데 prometheus-nginxlog-exporter에서 설정파일에 namespaces에서 name값을 설정할 수 있었다.

여기서 처음에 nginx가 아니라 커스텀하게 이름을 주었었는데 이미 만들어져 있는 NGINX Log Metrics대쉬보드를 사용하려니 이름이 일치되지 않았던 문제가 있었다.

해당 대쉬보드는 name값을 nginx를 default 값으로 쓰고 있었기 때문에 해당 이름의 일치가 되지 않는 다면 promql을 이용하여 Query를 날릴 때 정상적으로 데이터를 가져오지 못할 것이다.


최종적으로 Nginx의 log에 대해 그라파나를 이용해 시각화 한것이다.

References

profile
leewoooo

0개의 댓글