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"';
이전 글과 동일하게 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
...
이전 글에서 작성한 것과 같이 연결하면 된다. 설치는 생략하고 scrape_configs
부분을 설정해주면 된다.
# ...
scrape_configs:
- job_name: "nginx"
static_configs:
- targets: ["localhost:4040"]
# ...
연결 후 프로메테우스에 접속해보면 정상적으로 수집하고 있는 것을 볼 수 있다.
이전 글에서 크게 벗어나는 것이 없으며 대쉬보드는 NGINX Log Metrics를 가져다 사용했다.
위의 대쉬포드를 가져다가 사용할 때 삽질을 조금 하게 됬는데 prometheus-nginxlog-exporter에서 설정파일에 namespaces
에서 name
값을 설정할 수 있었다.
여기서 처음에 nginx
가 아니라 커스텀하게 이름을 주었었는데 이미 만들어져 있는 NGINX Log Metrics대쉬보드를 사용하려니 이름이 일치되지 않았던 문제가 있었다.
해당 대쉬보드는 name
값을 nginx
를 default 값으로 쓰고 있었기 때문에 해당 이름의 일치가 되지 않는 다면 promql
을 이용하여 Query를 날릴 때 정상적으로 데이터를 가져오지 못할 것이다.
최종적으로 Nginx의 log에 대해 그라파나를 이용해 시각화 한것이다.