「アクセス数をGrafanaで表示する(promtail × loki × nginx × docker compose)」 わたしのWebサービス開発日記 #31

スポンサーリンク
個人開発
スポンサーリンク

はじめに

自分のサイトへのアクセス数を知りたいと思って、nginxの値をlokiで読み込んでGrafanaで表示させようと思いました。

参考にしたサイトは以下です。

ただし、こちらのサイトはdocker composeは考慮していないので、今回はdocker composeを考慮した構成で実装しました。

実装

✅nginx.conf

nginx.confの以下のハイライトのところを追記

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

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

    log_format  ltsv    'time:$time_iso8601\t'
                        'remote_addr:$remote_addr\t'
                        'remote_port:$realip_remote_port\t'
                        'country:$http_cf_ipcountry\t'
                        'request_method:$request_method\t'
                        'request_uri:$request_uri\t'
                        'server_protocol:$server_protocol\t'
                        'status:$status\t'
                        'body_bytes_sent:$body_bytes_sent\t'
                        'referer:$http_referer\t'
                        'forwardedfor:$http_x_forwarded_for\t'
                        'request_time:$request_time\t'
                        'useragent:$http_user_agent';

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

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

✅promtail-config.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
- job_name: nginx
  static_configs:
  - targets:
    - localhost
    labels:
      job: access_log
      __path__: /var/log/nginx/access.ltsv
  pipeline_stages:
  - match:
      selector: '{job="access_log"}'
      stages:
      - regex:
          expression: '^time:(?P<time>.*)\tremote_addr:(?P<remote_addr>.*)\tremote_port:(?P<remote_port>.*)\tcountry:(?P<country>.*)\trequest_method:(?P<request_method>.*)\trequest_uri:(?P<request_uri>.*)\tserver_protocol:(?P<server_protocol>.*)\tstatus:(?P<status>.*)\tbody_bytes_sent:(?P<body_bytes_send>.*)\treferer:(?P<referer>.*)\tforwardedfor:(?P<forwardedfor>.*)\trequest_time:(?P<request_time>.*)\tuseragent:(?P<useragent>.*)$'
      - labels:
          time:
          remote_addr:
          remote_port:
          country:
          request_method:
          request_uri:
          server_protocol:
          status:
          body_bytes_send:
          referer:
          forwardedfor:
          request_time:
          useragent:

✅docker-compose.yml

version: '3.8'
 
services:
  nginx:
    image: nginx:latest
    container_name: nginx-container
    build:
      context: ./nginx
      dockerfile: ./Dockerfile
    ports:
      - "80:80"
      - "443:443"
    environment:
      TZ: "Asia/Tokyo"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/dist:/dist
      - ./nginx/log:/var/log/nginx
    depends_on:
      - frontend
      - backend
    networks:
      - my_network

・・・【略】・・・

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=xxxxx
      - GF_SECURITY_ADMIN_PASSWORD=xxxxx
    networks:
      - my_network

  promtail:
    image: grafana/promtail:latest
    volumes:
      - ./promtail/promtail-config.yaml:/etc/promtail/promtail-config.yaml
      - ./nginx/log/access.ltsv:/var/log/nginx/access.ltsv
    command: -config.file=/etc/promtail/promtail-config.yaml
    networks:
      - my_network

  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
    networks:
      - my_network

networks:
  my_network:
    ipam:
      driver: default
      config:
        - subnet: 172.19.0.0/24

Grafanaで表示

Grafanaにログインして、Datasourceにlokiを追加します。

Dashboardで以下の内容でアクセスのstatusのグラフを表示させます。

sum (count_over_time({service_name="access_log"} | status != "" [$__interval])) by (status)

以下のような感じ。グラフの種類はBar gaugeです。

アクセスログを表示させるには以下の記述です。

{service_name="access_log"} | line_format "{{.request_method}} {{.request_uri}} {{.server_protocol}} {{.status}}"

画面だと以下のような感じ。

結果、Dashboardは以下のようになりました。

タイトルとURLをコピーしました