I've spent some time making this work. I've tried so many different paths, I don't even remember where I started. The current solution, though, is available for you on The Awesome Garage GitHub account.

Here I'll just put down the basics, and you can look into the details in the docker-composer.yml and readme files on GitHub.

The first valuable takeaway you need to know: for this particular setup you don't need the Nginx access log or error log, and the log format is of no interest to Prometheus or the Promethes status exporter. The trick here is to compile Nginx with this great Nginx virtual host traffic status module. Luckily, there is a guy that did almost all of the work compiling in the VTS module. And twice as luckily, his work is open sourced, so I could update software versions in order to make my setup work; it seems Nginx 1.15.2 doesn't play well with my version of the Let's Encrypt Nginx proxy companion. At least it barfed on my certs until I updated the Nginx version to 1.15.11.

Now that you've enabled the VTS module, all your vhosts suddenly starts outputting traffic data on /status. This is a good sign, but you really don't want all this data publicly available. The trick here is to define a special Nginx vhost, only available locally, and for that vhost enable vhost_traffic_status_display. This effectively shuts down the new data end points on all other vhosts. phew. I myself did that with the nginx-vts-status vhost that I added to my version of the nginx-gen container template file.

The server is safe, once again, and spewing VTS data locally. Now we need to transform this data to a Prometheys friendly format. In comes the Nginx VTS exporter. Spin up the container, change the place the exporter fetches statutes:

NGINX_STATUS=http://nginx-vts-status/status/format/json

Make sure nginx-vts-status is available for the exporter container as an alias for your nginx-container. This is a trick to make the nginx-vts-status virtualhost available locally on the Docker network, as long as the containers are on the same Docker network. Check out my docker-compose.yml for the details, but in short this is what you do:

nginx:
    container_name: nginx
    build: ./nginx-vts/.
    networks:
      frontend:
        aliases:
           - nginx-vts-status
     (...)

  nginx-vts-exporter:
    container_name: nginx-vts-exporter
    image: sophos/nginx-vts-exporter
    networks:
      - frontend
    environment:
      - NGINX_STATUS=http://nginx-vts-status/status/format/json

Now, you need to set up a target for Prometheus that fetches the nginx-vts-status.

(...)
scrape_configs:
    - job_name: 'nginx-vts-exporter:'
      static_configs:
        - targets: ['nginx-vts-exporter:9913']
(...)

Now, Prometheus will make time series of your metrics. You just need to import this Grafana dashboard and your up and running. Download the JSON-file, go to "Manage dashboards" and "Import". It's really important that you "Import", because this way the input variables in the JSON-file are put to use. Select Prometheus as your data source and the VTS-data will be in there!

Attention! Some data will not be correctly visualized before you have data for the entire time range you are visualizing. If you're visualizing the last 24 hours, but onle have 1 hour worth of data, the graphs and numbers might be completely off.

I've struggeled a lot with this topic. Maybe it's because normally you are better off visualizing traffic to Nginx virtual hosts with an ELK-stack (Elasticsearch, Logstash and Kibana) or something similar. Or just about any solution where you ship off your access and error logs to some kind of database that is then analyzed by some aggregation tool and visualized by a visualization tool. Me, I just wanted to make it work nomatter what.

Previous Post Next Post