{"id":13439923,"url":"https://github.com/vozlt/nginx-module-vts","last_synced_at":"2025-12-28T13:41:09.015Z","repository":{"id":27285973,"uuid":"30759499","full_name":"vozlt/nginx-module-vts","owner":"vozlt","description":"Nginx virtual host traffic status module","archived":false,"fork":false,"pushed_at":"2025-04-07T11:17:01.000Z","size":1111,"stargazers_count":3321,"open_issues_count":44,"forks_count":477,"subscribers_count":127,"default_branch":"master","last_synced_at":"2025-04-23T20:51:23.917Z","etag":null,"topics":["c","monitoring","nginx","nginx-module","nginx-vhost-traffic-status","vozlt-nginx-modules"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vozlt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-02-13T14:22:24.000Z","updated_at":"2025-04-22T07:09:49.000Z","dependencies_parsed_at":"2024-11-15T03:20:11.137Z","dependency_job_id":"09fbde64-0644-4e87-8c8c-eeb0ecc5e668","html_url":"https://github.com/vozlt/nginx-module-vts","commit_stats":{"total_commits":181,"total_committers":19,"mean_commits":9.526315789473685,"dds":0.6077348066298343,"last_synced_commit":"724b34d7f1eff083860e3ac613a2c1d66a238dfd"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vozlt%2Fnginx-module-vts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vozlt%2Fnginx-module-vts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vozlt%2Fnginx-module-vts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vozlt%2Fnginx-module-vts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vozlt","download_url":"https://codeload.github.com/vozlt/nginx-module-vts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251563575,"owners_count":21609754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","monitoring","nginx","nginx-module","nginx-vhost-traffic-status","vozlt-nginx-modules"],"created_at":"2024-07-31T03:01:18.208Z","updated_at":"2025-12-28T13:41:08.998Z","avatar_url":"https://github.com/vozlt.png","language":"C","funding_links":[],"categories":["C","Third Modules","Third Party Modules"],"sub_categories":["C Modules"],"readme":"Nginx virtual host traffic status module\n==========\n\n[![CI](https://github.com/vozlt/nginx-module-vts/actions/workflows/ci.yml/badge.svg)](https://github.com/vozlt/nginx-module-vts/actions/workflows/ci.yml)\n[![License](http://img.shields.io/badge/license-BSD-brightgreen.svg)](https://github.com/vozlt/nginx-module-vts/blob/master/LICENSE)\n\nNginx virtual host traffic status module\n\nTable of Contents\n=================\n\n* [Version](#version)\n* [Test](#test)\n* [Dependencies](#dependencies)\n* [Compatibility](#compatibility)\n* [Screenshots](#screenshots)\n* [Installation](#installation)\n* [Synopsis](#synopsis)\n* [Description](#description)\n* [Calculations and Intervals](#calculations-and-intervals)\n* [Control](#control)\n  * [To get status of traffic zones on the fly](#to-get-status-of-traffic-zones-on-the-fly)\n    * [To get fully zones](#to-get-fully-zones)\n    * [To get group zones](#to-get-group-zones)\n    * [To get each zones](#to-get-each-zones)\n  * [To reset traffic zones on the fly](#to-reset-traffic-zones-on-the-fly)\n    * [To reset fully zones](#to-reset-fully-zones)\n    * [To reset group zones](#to-reset-group-zones)\n    * [To reset each zones](#to-reset-each-zones)\n  * [To delete traffic zones on the fly](#to-delete-traffic-zones-on-the-fly)\n    * [To delete fully zones](#to-delete-fully-zones)\n    * [To delete group zones](#to-delete-group-zones)\n    * [To delete each zones](#to-delete-each-zones)\n* [Set](#set)\n* [JSON](#json)\n  * [Json used by status](#json-used-by-status)\n  * [Json used by control](#json-used-by-control)\n* [Variables](#variables)\n* [Limit](#limit)\n  * [To limit traffic for server](#to-limit-traffic-for-server)\n  * [To limit traffic for filter](#to-limit-traffic-for-filter)\n  * [To limit traffic for upstream](#to-limit-traffic-for-upstream)\n* [Use cases](#use-cases)\n  * [To calculate traffic for individual country using GeoIP](#to-calculate-traffic-for-individual-country-using-geoip)\n  * [To calculate traffic for individual storage volume](#to-calculate-traffic-for-individual-storage-volume)\n  * [To calculate traffic for individual user agent](#to-calculate-traffic-for-individual-user-agent)\n  * [To calculate traffic for detailed http status code](#to-calculate-traffic-for-detailed-http-status-code)\n  * [To calculate traffic for dynamic dns](#to-calculate-traffic-for-dynamic-dns)\n  * [To calculate traffic except for status page](#to-calculate-traffic-except-for-status-page)\n  * [To maintain statistics data permanently](#to-maintain-statistics-data-permanently)\n* [Customizing](#customizing)\n  * [To customize after the module installed](#to-customize-after-the-module-installed)\n  * [To customize before the module installed](#to-customize-before-the-module-installed)\n* [Directives](#directives)\n  * [vhost_traffic_status](#vhost_traffic_status)\n  * [vhost_traffic_status_zone](#vhost_traffic_status_zone)\n  * [vhost_traffic_status_dump](#vhost_traffic_status_dump)\n  * [vhost_traffic_status_display](#vhost_traffic_status_display)\n  * [vhost_traffic_status_display_format](#vhost_traffic_status_display_format)\n  * [vhost_traffic_status_display_jsonp](#vhost_traffic_status_display_jsonp)\n  * [vhost_traffic_status_display_sum_key](#vhost_traffic_status_display_sum_key)\n  * [vhost_traffic_status_filter](#vhost_traffic_status_filter)\n  * [vhost_traffic_status_filter_by_host](#vhost_traffic_status_filter_by_host)\n  * [vhost_traffic_status_filter_by_set_key](#vhost_traffic_status_filter_by_set_key)\n  * [vhost_traffic_status_filter_check_duplicate](#vhost_traffic_status_filter_check_duplicate)\n  * [vhost_traffic_status_filter_max_node](#vhost_traffic_status_filter_max_node)\n  * [vhost_traffic_status_limit](#vhost_traffic_status_limit)\n  * [vhost_traffic_status_limit_traffic](#vhost_traffic_status_limit_traffic)\n  * [vhost_traffic_status_limit_traffic_by_set_key](#vhost_traffic_status_limit_traffic_by_set_key)\n  * [vhost_traffic_status_limit_check_duplicate](#vhost_traffic_status_limit_check_duplicate)\n  * [vhost_traffic_status_set_by_filter](#vhost_traffic_status_set_by_filter)\n  * [vhost_traffic_status_average_method](#vhost_traffic_status_average_method)\n  * [vhost_traffic_status_histogram_buckets](#vhost_traffic_status_histogram_buckets)\n  * [vhost_traffic_status_bypass_limit](#vhost_traffic_status_bypass_limit)\n  * [vhost_traffic_status_bypass_stats](#vhost_traffic_status_bypass_stats)\n  * [vhost_traffic_status_stats_by_upstream](#vhost_traffic_status_stats_by_upstream)\n* [Releases](#releases)\n* [See Also](#see-also)\n* [TODO](#todo)\n* [Author](#author)\n\n## Version\n\n![GitHub Release](https://img.shields.io/github/v/release/vozlt/nginx-module-vts?display_name=tag\u0026sort=semver)\n\nSee the [GitHub Releases](https://github.com/vozlt/nginx-module-vts/releases) for the latest tagged release.\n\n## Test\nRun `sudo prove -r t` after you have installed this module. The `sudo` is required because\nthe test requires Nginx to listen on port 80.\n\n## Dependencies\n* [nginx](http://nginx.org)\n\n## Compatibility\n* Nginx\n  * 1.27.x (last tested: 1.27.3)\n  * 1.22.x (last tested: 1.22.0)\n  * 1.19.x (last tested: 1.19.6)\n  * 1.18.x (last tested: 1.18.0)\n  * 1.16.x (last tested: 1.15.1)\n  * 1.15.x (last tested: 1.15.0)\n  * 1.14.x (last tested: 1.14.0)\n  * 1.13.x (last tested: 1.13.12)\n  * 1.12.x (last tested: 1.12.2)\n  * 1.11.x (last tested: 1.11.10)\n  * 1.10.x (last tested: 1.10.3)\n  * 1.8.x (last tested: 1.8.0)\n  * 1.6.x (last tested: 1.6.3)\n  * 1.4.x (last tested: 1.4.7)\n\nEarlier versions is not tested.\n\n## Screenshots\n![screenshot-vts-0](https://cloud.githubusercontent.com/assets/3648408/23890539/a4c0de18-08d5-11e7-9a8b-448662454854.png \"screenshot with default\")\n\n---\n![screenshot-vts-1](https://cloud.githubusercontent.com/assets/3648408/23890545/a9d5b504-08d5-11e7-88c2-eb55f39233db.png \"screenshot with filter\")\n\n## Installation\n\n1. Clone the git repository.\n\n  ```\n  shell\u003e git clone git://github.com/vozlt/nginx-module-vts.git\n  ```\n\n2. Add the module to the build configuration by adding\n  `--add-module=/path/to/nginx-module-vts`\n\n3. Build the nginx binary.\n\n4. Install the nginx binary.\n\n### Installtion with Profile-Guided Optimization\n\nIt can be built with Profile-Guided Optimization (PGO) using gcc `fprofile` options. The detail of the PGO mechanisms has refer to the section 7.4 of [this paper](https://people.freebsd.org/~lstewart/articles/cpumemory.pdf).\nHere is an example of the process to make a PGO supported binary. Please use at your own risk.\n\n1. Compile with fprofile-generate.\n\n  ```\n  shell\u003e pwd\n  /somewhere/nginx\n  shell\u003e CC=gcc ./auto/configure --with-cc-opt='-fprofile-generate -fprofile-dir=./objs' --with-ld-opt='-lgcov' --add-module=/somewhere/nginx-module-vts\n  shell\u003e make\n  ```\n\n2. Execute this module tests.\n\n  ```\n  shell\u003e pwd\n  /somewhere/nginx-module-vts\n  shell\u003e sudo PATH=/somewhere/nginx/objs:$PATH prove -r t/000.display_html.t\n  ...(during runtime it records coverage data into .gcda files)\n  ```\n\n3. Recompile with fprofile-use\n\n  ```\n  shell\u003e pwd\n  /somewhere/nginx\n  shell\u003e CC=gcc ./auto/configure --with-cc-opt='-fprofile-use -fprofile-dir=/somewhere/nginx-module-vts/objs' --with-ld-opt='-lgcov' --add-module=/somewhere/nginx-module-vts\n  shell\u003e make\n  ```\n\n## Synopsis\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        ...\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n## Description\nThis is an Nginx module that provides access to virtual host status information.\nIt contains the current status such as servers, upstreams, caches.\nThis is similar to the live activity monitoring of nginx plus.\nThe built-in html is also taken from the demo page of old version.\n\nFirst of all, the directive `vhost_traffic_status_zone` is required,\nand then if the directive `vhost_traffic_status_display` is set, can be access to as follows:\n\n* /status/format/json\n  * If you request `/status/format/json`, will respond with a JSON document containing the current activity data for using in live dashboards and third-party monitoring tools.\n* /status/format/html\n  * If you request `/status/format/html`, will respond with the built-in live dashboard in HTML that requests internally to `/status/format/json`.\n* /status/format/jsonp\n  * If you request `/status/format/jsonp`, will respond with a JSONP callback function containing the current activity data for using in live dashboards and third-party monitoring tools. \n* /status/format/prometheus\n  * If you request `/status/format/prometheus`, will respond with a [prometheus](https://prometheus.io) document containing the current activity data.\n* /status/control\n  * If you request `/status/control`, will respond with a JSON document after it reset or delete zones through a query string. See the [Control](#control).\n\nJSON document contains as follows:\n\n```Json\n{\n    \"hostName\": ...,\n    \"moduleVersion\": ...,\n    \"nginxVersion\": ...,\n    \"loadMsec\": ...,\n    \"nowMsec\": ...,\n    \"connections\": {\n        \"active\":...,\n        \"reading\":...,\n        \"writing\":...,\n        \"waiting\":...,\n        \"accepted\":...,\n        \"handled\":...,\n        \"requests\":...\n    },\n    \"sharedZones\": {\n        \"name\":...,\n        \"maxSize\":...,\n        \"usedSize\":...,\n        \"usedNode\":...\n    },\n    \"serverZones\": {\n        \"...\":{\n            \"requestCounter\":...,\n            \"inBytes\":...,\n            \"outBytes\":...,\n            \"responses\":{\n                \"1xx\":...,\n                \"2xx\":...,\n                \"3xx\":...,\n                \"4xx\":...,\n                \"5xx\":...,\n                \"miss\":...,\n                \"bypass\":...,\n                \"expired\":...,\n                \"stale\":...,\n                \"updating\":...,\n                \"revalidated\":...,\n                \"hit\":...,\n                \"scarce\":...\n            },\n            \"requestMsecCounter\":...,\n            \"requestMsec\":...,\n            \"requestMsecs\":{\n                \"times\":[...],\n                \"msecs\":[...]\n            },\n            \"requestBuckets\":{\n                \"msecs\":[...],\n                \"counters\":[...]\n            },\n        }\n        ...\n    },\n    \"filterZones\": {\n        \"...\":{\n            \"...\":{\n                \"requestCounter\":...,\n                \"inBytes\":...,\n                \"outBytes\":...,\n                \"responses\":{\n                    \"1xx\":...,\n                    \"2xx\":...,\n                    \"3xx\":...,\n                    \"4xx\":...,\n                    \"5xx\":...,\n                    \"miss\":...,\n                    \"bypass\":...,\n                    \"expired\":...,\n                    \"stale\":...,\n                    \"updating\":...,\n                    \"revalidated\":...,\n                    \"hit\":...,\n                    \"scarce\":...\n                },\n                \"requestMsecCounter\":...,\n                \"requestMsec\":...,\n                \"requestMsecs\":{\n                    \"times\":[...],\n                    \"msecs\":[...]\n                },\n                \"requestBuckets\":{\n                    \"msecs\":[...],\n                    \"counters\":[...]\n                },\n            },\n            ...\n        },\n        ...\n    },\n    \"upstreamZones\": {\n        \"...\":[\n            {\n                \"server\":...,\n                \"requestCounter\":...,\n                \"inBytes\":...,\n                \"outBytes\":...,\n                \"responses\":{\n                    \"1xx\":...,\n                    \"2xx\":...,\n                    \"3xx\":...,\n                    \"4xx\":...,\n                    \"5xx\":...\n                },\n                \"requestMsecCounter\":...,\n                \"requestMsec\":...,\n                \"requestMsecs\":{\n                    \"times\":[...],\n                    \"msecs\":[...]\n                },\n                \"requestBuckets\":{\n                    \"msecs\":[...],\n                    \"counters\":[...]\n                },\n                \"responseMsecCounter\":...,\n                \"responseMsec\":...,\n                \"responseMsecs\":{\n                    \"times\":[...],\n                    \"msecs\":[...]\n                },\n                \"responseBuckets\":{\n                    \"msecs\":[...],\n                    \"counters\":[...]\n                },\n                \"weight\":...,\n                \"maxFails\":...,\n                \"failTimeout\":...,\n                \"backup\":...,\n                \"down\":...\n            }\n            ...\n        ],\n        ...\n    }\n    \"cacheZones\": {\n        \"...\":{\n            \"maxSize\":...,\n            \"usedSize\":...,\n            \"inBytes\":...,\n            \"outBytes\":...,\n            \"responses\":{\n                \"miss\":...,\n                \"bypass\":...,\n                \"expired\":...,\n                \"stale\":...,\n                \"updating\":...,\n                \"revalidated\":...,\n                \"hit\":...,\n                \"scarce\":...\n            }\n        },\n        ...\n    }\n}\n```\n\n* main\n  * Basic version, uptime((nowMsec - loadMsec)/1000)\n  * nowMsec, loadMsec is a millisecond.\n* connections\n  * Total connections and requests(same as stub_status_module in NGINX)\n* sharedZones\n  * The shared memory information using in nginx-module-vts.\n* serverZones\n  * Traffic(in/out) and request and response counts and cache hit ratio per each server zone\n  * Total traffic(In/Out) and request and response counts(It zone name is `*`) and hit ratio\n* filterZones\n  * Traffic(in/out) and request and response counts and cache hit ratio per each server zone filtered through the `vhost_traffic_status_filter_by_set_key` directive\n  * Total traffic(In/Out) and request and response counts(It zone name is `*`) and hit ratio filtered through the `vhost_traffic_status_filter_by_set_key` directive\n* upstreamZones\n  * Traffic(in/out) and request and response counts per server in each upstream group\n  * Current settings(weight, maxfails, failtimeout...) in nginx.conf\n* cacheZones\n  * Traffic(in/out) and size(capacity/used) and hit ratio per each cache zone when using the proxy_cache directive.\n\nThe `overCounts` objects in JSON document are mostly for 32bit system and will be increment by 1 if its value is overflowed.\nThe directive `vhost_traffic_status_display_format` sets the default ouput format that is one of json, jsonp, html, prometheus. (Default: json)\n\nTraffic calculation as follows:\n\n* ServerZones\n  * in += requested_bytes\n  * out += sent_bytes\n* FilterZones\n  * in += requested_bytes via the filter\n  * out += sent_bytes via the filter\n* UpstreamZones\n  * in += requested_bytes via the ServerZones\n  * out += sent_bytes via the ServerZones\n* cacheZones\n  * in += requested_bytes via the ServerZones\n  * out += sent_bytes via the ServerZones\n\nAll calculations are working in log processing phase of Nginx.\nInternal redirects(X-Accel-Redirect or error_page) does not calculate in the UpstreamZones.\n\n`Caveats:` this module relies on nginx logging system(NGX_HTTP_LOG_PHASE:last phase of the nginx http), so the traffic may be\nin certain cirumstances different that real bandwidth traffic.\nWebsocket, canceled downloads may be cause of inaccuracies.\nThe working of the module doesn't matter at all whether the access_log directive \"on\" or \"off\".\nAgain, this module works well on \"access_log off\".\nWhen using several domains it sets to be first domain(left) of server_name directive.\nIf you don't want it, see the [vhost_traffic_status_filter_by_host](#vhost_traffic_status_filter_by_host), [vhost_traffic_status_filter_by_set_key](#vhost_traffic_status_filter_by_set_key) directive.\n\nSee the following modules for the `stream` traffic statistics:\n* [nginx-module-sts](https://github.com/vozlt/nginx-module-sts)\n* [nginx-module-stream-sts](https://github.com/vozlt/nginx-module-stream-sts)\n\n## Calculations and Intervals\n\n### Averages\n\nAll averages are currently calculated as [AMM](https://en.wikipedia.org/wiki/Arithmetic_mean)(Arithmetic Mean) over the last [64](https://github.com/vozlt/nginx-module-vts/blob/master/src/ngx_http_vhost_traffic_status_node.h#L11) values.\n\n## Control\nIt is able to reset or delete traffic zones through a query string.\nThe request responds with a JSON document.\n\n* URI Syntax\n  * /*`{status_uri}`*/control?cmd=*`{command}`*\u0026group=*`{group}`*\u0026zone=*`{name}`*\n\n```Nginx\nhttp {\n\n    geoip_country /usr/share/GeoIP/GeoIP.dat;\n\n    vhost_traffic_status_zone;\n    vhost_traffic_status_filter_by_set_key $geoip_country_code country::*;\n\n    ...\n\n    server {\n\n        server_name example.org;\n\n        ...\n\n        vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\nIf it set as above, then the control uri is like `example.org/status/control`.\n\nThe available request arguments are as follows:\n* **cmd**=\\\u003c`status`\\|`reset`\\|`delete`\\\u003e\n  * status\n    * It returns status of traffic zones to json format like `status/format/json`.\n  * reset\n    * It reset traffic zones without deleting nodes in shared memory.(= init to 0)\n  * delete\n    * It delete traffic zones in shared memory. when re-request recreated. \n* **group**=\\\u003c`server`\\|`filter`\\|`upstream@alone`\\|`upstream@group`\\|`cache`\\|`*`\\\u003e\n  * server\n  * filter\n  * upstream@alone\n  * upstream@group\n  * cache\n  * \\*\n* **zone**=*name*\n  * server\n    * *name*\n  * filter\n    * *filter_group*@*name*\n  * upstream@group\n    * *upstream_group*@*name*\n  * upstream@alone\n    * @*name*\n  * cache\n    * *name*\n\n\n### To get status of traffic zones on the fly\nThis is similar to the `status/format/json` except that it can get each zones.\n\n#### To get fully zones\n* It is exactly the same with the `status/format/json`.\n  * /status/control?cmd=status\u0026group=*\n\n#### To get group zones\n* mainZones\n  * /status/control?cmd=status\u0026group=server\u0026zone=::main\n* serverZones\n  * /status/control?cmd=status\u0026group=server\u0026zone=*\n* filterZones\n  * /status/control?cmd=status\u0026group=filter\u0026zone=*\n* upstreamZones\n  * /status/control?cmd=status\u0026group=upstream@group\u0026zone=*\n* upstreamZones::nogroups\n  * /status/control?cmd=status\u0026group=upstream@alone\u0026zone=*\n* cacheZones\n  * /status/control?cmd=status\u0026group=cache\u0026zone=*\n\nThe **mainZones** values are default status values including `hostName`, `moduleVersion`, `nginxVersion`, `loadMsec`, `nowMsec`, `connections`.\n\n#### To get each zones\n* single zone in serverZones\n  * /status/control?cmd=status\u0026group=server\u0026zone=*`name`*\n* single zone in filterZones\n  * /status/control?cmd=status\u0026group=filter\u0026zone=*`filter_group`*@*`name`*\n* single zone in upstreamZones\n  * /status/control?cmd=status\u0026group=upstream@group\u0026zone=*`upstream_group`*@*`name`*\n* single zone in upstreamZones::nogroups\n  * /status/control?cmd=status\u0026group=upstream@alone\u0026zone=*`name`*\n* single zone in cacheZones\n  * /status/control?cmd=status\u0026group=cache\u0026zone=*`name`*\n\n### To reset traffic zones on the fly\nIt reset the values of specified zones to 0.\n\n#### To reset fully zones\n* /status/control?cmd=reset\u0026group=*\n\n#### To reset group zones\n* serverZones\n  * /status/control?cmd=reset\u0026group=server\u0026zone=*\n* filterZones\n  * /status/control?cmd=reset\u0026group=filter\u0026zone=*\n* upstreamZones\n  * /status/control?cmd=reset\u0026group=upstream@group\u0026zone=*\n* upstreamZones::nogroups\n  * /status/control?cmd=reset\u0026group=upstream@alone\u0026zone=*\n* cacheZones\n  * /status/control?cmd=reset\u0026group=cache\u0026zone=*\n\n#### To reset each zones\n* single zone in serverZones\n  * /status/control?cmd=reset\u0026group=server\u0026zone=*`name`*\n* single zone in filterZones\n  * /status/control?cmd=reset\u0026group=filter\u0026zone=*`filter_group`*@*`name`*\n* single zone in upstreamZones\n  * /status/control?cmd=reset\u0026group=upstream@group\u0026zone=*`upstream_group`*@*`name`*\n* single zone in upstreamZones::nogroups\n  * /status/control?cmd=reset\u0026group=upstream@alone\u0026zone=*`name`*\n* single zone in cacheZones\n  * /status/control?cmd=reset\u0026group=cache\u0026zone=*`name`*\n\n### To delete traffic zones on the fly\nIt delete the specified zones in shared memory.\n\n#### To delete fully zones\n* /status/control?cmd=delete\u0026group=*\n\n#### To delete group zones\n* serverZones\n  * /status/control?cmd=delete\u0026group=server\u0026zone=*\n* filterZones\n  * /status/control?cmd=delete\u0026group=filter\u0026zone=*\n* upstreamZones\n  * /status/control?cmd=delete\u0026group=upstream@group\u0026zone=*\n* upstreamZones::nogroups\n  * /status/control?cmd=delete\u0026group=upstream@alone\u0026zone=*\n* cacheZones\n  * /status/control?cmd=delete\u0026group=cache\u0026zone=*\n\n#### To delete each zones\n* single zone in serverZones\n  * /status/control?cmd=delete\u0026group=server\u0026zone=*`name`*\n* single zone in filterZones\n  * /status/control?cmd=delete\u0026group=filter\u0026zone=*`filter_group`*@*`name`*\n* single zone in upstreamZones\n  * /status/control?cmd=delete\u0026group=upstream@group\u0026zone=*`upstream_group`*@*`name`*\n* single zone in upstreamZones::nogroups\n  * /status/control?cmd=delete\u0026group=upstream@alone\u0026zone=*`name`*\n* single zone in cacheZones\n  * /status/control?cmd=delete\u0026group=cache\u0026zone=*`name`*\n\n## Set\nIt can get the status values in nginx configuration separately using `vhost_traffic_status_set_by_filter` directive.\nIt can acquire almost all status values and the obtained value is stored in user-defined-variable which is first argument.\n\n* Directive Syntax\n  * **vhost_traffic_status_set_by_filter** *$variable* *group*/*zone*/*name*\n\n```Nginx\nhttp {\n\n    geoip_country /usr/share/GeoIP/GeoIP.dat;\n\n    vhost_traffic_status_zone;\n    vhost_traffic_status_filter_by_set_key $geoip_country_code country::*;\n\n    ...\n    upstream backend {\n        10.10.10.11:80;\n        10.10.10.12:80;\n    }\n\n    server {\n\n        server_name example.org;\n\n        ...\n\n        vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;\n\n        vhost_traffic_status_set_by_filter $requestCounter server/example.org/requestCounter;\n        vhost_traffic_status_set_by_filter $requestCounterKR filter/country::example.org@KR/requestCounter;\n\n        location /backend {\n            vhost_traffic_status_set_by_filter $requestCounterB1 upstream@group/backend@10.10.10.11:80/requestCounter;\n            proxy_pass http://backend;\n        }\n    }\n}\n```\n\nThe above settings are as follows:\n\n* $requestCounter\n  * serverZones -\u003e example.org -\u003e requestCounter\n* $requestCounterKR\n  * filterZones -\u003e country::example.org -\u003e KR -\u003e requestCounter\n* $requestCounterB1\n  * upstreamZones -\u003e backend -\u003e 10.0.10.11:80 -\u003e requestCounter\n\nPlease see the [vhost_traffic_status_set_by_filter](#vhost_traffic_status_set_by_filter) directive for detailed usage.\n\n## JSON\nThe following status information is provided in the JSON format:\n\n### Json used by status\n/*`{status_uri}`*/format/json\n\n/*`{status_uri}`*/control?cmd=status\u0026...\n\n* hostName\n  * Host name.\n* moduleVersion\n  * Version of the module in *`{version}(|.dev.{commit})`* format.\n* nginxVersion\n  * Version of the provided.\n* loadMsec\n  * Loaded process time in milliseconds.\n* nowMsec\n  * Current time in milliseconds\n* connections\n  * active\n    * The current number of active client connections.\n  * reading\n    * The total number of reading client connections.\n  * writing\n    * The total number of writing client connections.\n  * waiting\n    * The total number of wating client connections.\n  * accepted\n    * The total number of accepted client connections.\n  * handled\n    * The total number of handled client connections.\n  * requests\n    * The total number of requested client connections.\n* sharedZones\n  * name\n    * The name of shared memory specified in the configuration.(default: `vhost_traffic_status`)\n  * maxSize\n    * The limit on the maximum size of the shared memory specified in the configuration.\n  * usedSize\n    * The current size of the shared memory.\n  * usedNode\n    * The current number of node using in shared memory. It can get an approximate size for one node with the following formula: (*usedSize* / *usedNode*)\n* serverZones\n  * requestCounter\n    * The total number of client requests received from clients.\n  * inBytes\n    * The total number of bytes received from clients.\n  * outBytes\n    * The total number of bytes sent to clients.\n  * responses\n    * 1xx, 2xx, 3xx, 4xx, 5xx\n      * The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.\n    * miss\n      * The number of cache miss.\n    * bypass\n      * The number of cache bypass.\n    * expired\n      * The number of cache expired.\n    * stale\n      * The number of cache stale.\n    * updating\n      * The number of cache updating.\n    * revalidated\n      * The number of cache revalidated.\n    * hit\n      * The number of cache hit.\n    * scarce\n      * The number of cache scare.\n  * requestMsecCounter\n    * The number of accumulated request processing time in milliseconds.\n  * requestMsec\n    * The average of request processing times in milliseconds.\n  * requestMsecs\n    * times\n      * The times in milliseconds at request processing times.\n    * msecs\n      * The request processing times in milliseconds.\n  * requestBuckets\n    * msecs\n      * The bucket values of histogram set by `vhost_traffic_status_histogram_buckets` directive.\n    * counters\n      * The cumulative values for the reason that each bucket value is greater than or equal to the request processing time. \n* filterZones\n  * It provides the same fields with `serverZones` except that it included group names.\n* upstreamZones\n  * server\n    * An address of the server.\n  * requestCounter\n    * The total number of client connections forwarded to this server.\n  * inBytes\n    * The total number of bytes received from this server.\n  * outBytes\n    * The total number of bytes sent to this server.\n  * responses\n    * 1xx, 2xx, 3xx, 4xx, 5xx\n      * The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.\n  * requestMsecCounter\n    * The number of accumulated request processing time including upstream in milliseconds.\n  * requestMsec\n    * The average of request processing times including upstream in milliseconds.\n  * requestMsecs\n    * times\n      * The times in milliseconds at request processing times.\n    * msecs\n      * The request processing times including upstream in milliseconds.\n  * requestBuckets\n    * msecs\n      * The bucket values of histogram set by `vhost_traffic_status_histogram_buckets` directive.\n    * counters\n      * The cumulative values for the reason that each bucket value is greater than or equal to the request processing time including upstream.\n  * responseMsecCounter\n    * The number of accumulated only upstream response processing time in milliseconds.\n  * responseMsec\n    * The average of only upstream response processing times in milliseconds.\n  * responseMsecs\n    * times\n      * The times in milliseconds at request processing times.\n    * msecs\n      * The only upstream response processing times in milliseconds.\n  * responseBuckets\n    * msecs\n      * The bucket values of histogram set by `vhost_traffic_status_histogram_buckets` directive.\n    * counters\n      * The cumulative values for the reason that each bucket value is greater than or equal to the only upstream response processing time.\n  * weight\n    * Current `weight` setting of the server.\n  * maxFails\n    * Current `max_fails` setting of the server.\n  * failTimeout\n    * Current `fail_timeout` setting of the server.\n  * backup\n    * Current `backup` setting of the server.\n  * down\n    * Current `down` setting of the server. Basically, this is just a mark the [ngx_http_upstream_module](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server)'s server down(eg. `server backend3.example.com down`), not actual upstream server state. It will changed to actual state if you enabled the upstream zone directive.\n* cacheZones\n  * maxSize\n    * The limit on the maximum size of the cache specified in the configuration. If `max_size` in `proxy_cache_path` directive is not specified, the system dependent value `NGX_MAX_OFF_T_VALUE` is assigned by default. In other words, this value is from nginx, not what I specified.\n  * usedSize\n    * The current size of the cache. This value is taken from nginx like the above `maxSize` value. \n  * inBytes\n    * The total number of bytes received from the cache.\n  * outBytes\n    * The total number of bytes sent from the cache.\n  * responses\n    * miss\n      * The number of cache miss.\n    * bypass\n      * The number of cache bypass.\n    * expired\n      * The number of cache expired.\n    * stale\n      * The number of cache stale.\n    * updating\n      * The number of cache updating.\n    * revalidated\n      * The number of cache revalidated.\n    * hit\n      * The number of cache hit.\n    * scarce\n      * The number of cache scare.\n\n### Json used by control\n/*`{status_uri}`*/control?cmd=reset\u0026...\n\n/*`{status_uri}`*/control?cmd=delete\u0026...\n\n* processingReturn\n  * The result of true or false.\n* processingCommandString\n  * The requested command string.\n* processingGroupString\n  * The requested group string.\n* processingZoneString\n  * The requested zone string.\n* processingCounts\n  * The actual processing number.\n\n## Variables\nThe following embedded variables are provided:\n\n* **$vts_request_counter**\n  * The total number of client requests received from clients.\n* **$vts_in_bytes**\n  * The total number of bytes received from clients.\n* **$vts_out_bytes**\n  * The total number of bytes sent to clients.\n* **$vts_1xx_counter**\n  * The number of responses with status codes 1xx.\n* **$vts_2xx_counter**\n  * The number of responses with status codes 2xx.\n* **$vts_3xx_counter**\n  * The number of responses with status codes 3xx.\n* **$vts_4xx_counter**\n  * The number of responses with status codes 4xx.\n* **$vts_5xx_counter**\n  * The number of responses with status codes 5xx.\n* **$vts_cache_miss_counter**\n  * The number of cache miss.\n* **$vts_cache_bypass_counter**\n  * The number of cache bypass.\n* **$vts_cache_expired_counter**\n  * The number of cache expired.\n* **$vts_cache_stale_counter**\n  * The number of cache stale.\n* **$vts_cache_updating_counter**\n  * The number of cache updating.\n* **$vts_cache_revalidated_counter**\n  * The number of cache revalidated.\n* **$vts_cache_hit_counter**\n  * The number of cache hit.\n* **$vts_cache_scarce_counter**\n  * The number of cache scare.\n* **$vts_request_time_counter**\n  * The number of accumulated request processing time.\n* **$vts_request_time**\n  * The average of request processing times.\n\n## Limit\n\nIt is able to limit total traffic per each host by using the directive\n[`vhost_traffic_status_limit_traffic`](#vhost_traffic_status_limit_traffic).\nIt also is able to limit all traffic by using the directive\n[`vhost_traffic_status_limit_traffic_by_set_key`](#vhost_traffic_status_limit_traffic_by_set_key).\nWhen the limit is exceeded, the server will return the 503\n(Service Temporarily Unavailable) error in reply to a request. \nThe return code can be changeable.\n\n### To limit traffic for server\n```Nginx\nhttp {\n\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        server_name *.example.org;\n\n        vhost_traffic_status_limit_traffic in:64G;\n        vhost_traffic_status_limit_traffic out:1024G;\n\n        ...\n    }\n}\n```\n\n* Limit in/out total traffic on the `*.example.org` to 64G and 1024G respectively.\nIt works individually per each domain if `vhost_traffic_status_filter_by_host` directive is enabled.\n\n### To limit traffic for filter\n```Nginx\nhttp {\n    geoip_country /usr/share/GeoIP/GeoIP.dat;\n\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        server_name example.org;\n\n        vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;\n        vhost_traffic_status_limit_traffic_by_set_key FG@country::$server_name@US out:1024G;\n        vhost_traffic_status_limit_traffic_by_set_key FG@country::$server_name@CN out:2048G;\n\n        ...\n\n    }\n}\n\n```\n\n* Limit total traffic of going into US and CN on the `example.org` to 1024G and 2048G respectively.\n\n### To limit traffic for upstream\n```Nginx\nhttp {\n\n    vhost_traffic_status_zone;\n\n    ...\n\n    upstream backend {\n        server 10.10.10.17:80;\n        server 10.10.10.18:80;\n    }\n\n    server {\n\n        server_name example.org;\n\n        location /backend {\n            vhost_traffic_status_limit_traffic_by_set_key UG@backend@10.10.10.17:80 in:512G;\n            vhost_traffic_status_limit_traffic_by_set_key UG@backend@10.10.10.18:80 in:1024G;\n            proxy_pass http://backend;\n        }\n\n        ...\n\n    }\n}\n\n```\n\n* Limit total traffic of going into upstream backend on the `example.org` to 512G and 1024G per each peer.\n\n`Caveats:` Traffic is the cumulative transfer or counter, not a bandwidth.\n\n## Use cases\n\nIt is able to calculate the user defined individual stats by using the directive `vhost_traffic_status_filter_by_set_key`.\n\n### To calculate traffic for individual country using GeoIP\n```Nginx\nhttp {\n    geoip_country /usr/share/GeoIP/GeoIP.dat;\n\n    vhost_traffic_status_zone;\n    vhost_traffic_status_filter_by_set_key $geoip_country_code country::*;\n\n    ...\n\n    server {\n\n        ...\n\n        vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n* Calculate traffic for individual country of total server groups.\n* Calculate traffic for individual country of each server groups.\n\nBasically, country flags image is built-in in HTML.\nThe country flags image is enabled if the `country` string is included\nin group name which is second argument of `vhost_traffic_status_filter_by_set_key` directive.\n\n### To calculate traffic for individual storage volume\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        ...\n\n        location ~ ^/storage/(.+)/.*$ {\n            set $volume $1;\n            vhost_traffic_status_filter_by_set_key $volume storage::$server_name;\n        }\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n* Calculate traffic for individual storage volume matched by regular expression of location directive.\n\n### To calculate traffic for individual user agent\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    map $http_user_agent $filter_user_agent {\n        default 'unknown';\n        ~iPhone ios;\n        ~Android android;\n        ~(MSIE|Mozilla) windows;\n    }\n\n    vhost_traffic_status_filter_by_set_key $filter_user_agent agent::*;\n\n    ...\n\n    server {\n\n        ...\n\n        vhost_traffic_status_filter_by_set_key $filter_user_agent agent::$server_name;\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n* Calculate traffic for individual `http_user_agent`\n\n### To calculate traffic for detailed http status code\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    server {\n\n        ...\n\n        vhost_traffic_status_filter_by_set_key $status $server_name;\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n* Calculate traffic for detailed `http status code`\n\n`Caveats:` [$status](http://nginx.org/en/docs/http/ngx_http_core_module.html#variables) variable is available in nginx-(1.3.2, 1.2.2).\n\n### To calculate traffic for dynamic dns\n\nIf the domain has multiple DNS A records, you can calculate traffic for individual IPs\nfor the domain using the filter feature or a variable in proxy_pass.\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    upstream backend {\n        elb.example.org:80;\n    }\n\n    ...\n\n    server {\n\n        ...\n\n        location /backend {\n            vhost_traffic_status_filter_by_set_key $upstream_addr upstream::backend;\n            proxy_pass backend;\n        }\n    }\n}\n```\n\n* Calculate traffic for individual IPs for the domain `elb.example.org`.\nIf `elb.example.org` has multiple DNS A records, will be display all IPs in `filterZones`.\nIn the above settings, as NGINX starts up or reloads it configuration,\nit queries a DNS server to resolve domain and DNS A records is cached in memory.\nTherefore the DNS A records are not changed in memory even if\nDNS A records are chagned by DNS administrator unless NGINX re-starts up or reloads.\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    resolver 10.10.10.53 valid=10s\n\n    ...\n\n    server {\n\n        ...\n\n        location /backend {\n            set $backend_server elb.example.org;\n            proxy_pass http://$backend_server;\n        }\n    }\n}\n```\n\n* Calculate traffic for individual IPs for the domain `elb.example.org`.\nIf `elb.example.org`'s DNS A record is changed,\nwill be display both the old IP and the new IP in `::nogroups`.\nUnlike the first upstream group setting, the second setting works well\neven if DNS A records are chagned by DNS administrator.\n\n`Caveats:` Please more details about NGINX DNS see the\n[dns-service-discovery-nginx-plus](https://www.nginx.com/blog/dns-service-discovery-nginx-plus).\n\n### To calculate traffic except for status page\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        ...\n\n        location /status {\n            vhost_traffic_status_bypass_limit on;\n            vhost_traffic_status_bypass_stats on;\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n* The `/status` uri is excluded from the status traffic calculation and limit feature. \nSee the following directives:\n  * [vhost_traffic_status_bypass_limit](#vhost_traffic_status_bypass_limit)\n  * [vhost_traffic_status_bypass_stats](#vhost_traffic_status_bypass_stats)\n\n\n### To maintain statistics data permanently\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n    vhost_traffic_status_dump /var/log/nginx/vts.db;\n\n    ...\n\n    server {\n\n        ...\n\n    }\n}\n```\n\n* The `vhost_traffic_status_dump` directive maintains statistics data permanently\neven if system has been rebooted or nginx has been restarted.\nPlease see the [vhost_traffic_status_dump](#vhost_traffic_status_dump) directive for detailed usage.\n\n## Customizing\n### To customize after the module installed\n1. You need to change the `{{uri}}` string to your status uri in status.template.html as follows:\n ```\n shell\u003e vi share/status.template.html\n ```\n ```\n var vtsStatusURI = \"yourStatusUri/format/json\", vtsUpdateInterval = 1000;\n ```\n\n2. And then, customizing and copy status.template.html to server root directory as follows:\n ```\n shell\u003e cp share/status.template.html /usr/share/nginx/html/status.html\n ```\n\n4. Configure `nginx.conf`\n ```Nginx\n    server {\n        server_name example.org;\n        root /usr/share/nginx/html;\n\n        # Redirect requests for / to /status.html\n        location = / {\n            return 301 /status.html;\n        }\n\n        location = /status.html {}\n\n        # Everything beginning /status (except for /status.html) is\n        # processed by the status handler\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format json;\n        }\n    }\n\n ```\n\n4. Access to your html.\n ```\n http://example.org/status.html\n ```\n\n### To customize before the module installed\n1. Modify `share/status.template.html` (Do not change `{{uri}}` string)\n\n2. Recreate the `ngx_http_vhost_traffic_status_module_html.h` as follows:\n ```\n shell\u003e cd util\n shell\u003e ./tplToDefine.sh ../share/status.template.html \u003e ../src/ngx_http_vhost_traffic_status_module_html.h\n ```\n\n3. Add the module to the build configuration by adding\n  `--add-module=/path/to/nginx-module-vts`\n\n4. Build the nginx binary.\n\n5. Install the nginx binary.\n\n\n## Directives\n\n![draw_io_vts_diagram](https://user-images.githubusercontent.com/3648408/42613122-279cdb70-85da-11e8-940e-e348bd8ea861.png \"The order of nginx-module-vts module directives\")\n\n### vhost_traffic_status\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status** \\\u003con\\|off\\\u003e |\n| **Default** | off |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the module working.\nIf you set `vhost_traffic_status_zone` directive, is automatically enabled.\n\n### vhost_traffic_status_zone\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_zone** [shared:*name:size*] |\n| **Default** | shared:vhost_traffic_status:1m |\n| **Context** | http |\n\n`Description:` Sets parameters for a shared memory zone that will keep states for various keys.\nThe cache is shared between all worker processes.\nIn most cases, the shared memory size used by nginx-module-vts does not increase much.\nThe shared memory size is increased pretty when using `vhost_traffic_status_filter_by_set_key`\ndirective but if filter's keys are fixed(*eg. the total number of the country code is about 240*)\nit does not continuously increase.\n\nIf you use `vhost_traffic_status_filter_by_set_key` directive, set it as follows:\n\n* Set to more than 32M shared memory size by default.\n(`vhost_traffic_status_zone shared:vhost_traffic_status:32m`)\n* If the message(*`\"ngx_slab_alloc() failed: no memory in vhost_traffic_status_zone\"`*)\nprinted in error_log, increase to more than (usedSize * 2).\n\n### vhost_traffic_status_dump\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_dump** *path* [*period*] |\n| **Default** | - |\n| **Context** | http |\n\n`Description:` Enables the statistics data dump and restore.\nThe *path* is a location to dump the statistics data.(e.g. `/var/log/nginx/vts.db`)\nThe *period* is a backup cycle time.(Default: 60s)\nIt is backed up immediately regardless of the backup cycle if nginx is exited by signal(`SIGKILL`).\n\n### vhost_traffic_status_display\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_display** |\n| **Default** | - |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the module display handler.\n\n### vhost_traffic_status_display_format\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_display_format** \\\u003cjson\\|html\\|jsonp\\|prometheus\\\u003e |\n| **Default** | json |\n| **Context** | http, server, location |\n\n`Description:` Sets the display handler's output format.\nIf you set `json`, will respond with a JSON document.\nIf you set `html`, will respond with the built-in live dashboard in HTML.\nIf you set `jsonp`, will respond with a JSONP callback function(default: *ngx_http_vhost_traffic_status_jsonp_callback*).\nIf you set `prometheus`, will respond with a [prometheus](https://prometheus.io) document.\n\n### vhost_traffic_status_display_jsonp\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_display_jsonp** *callback* |\n| **Default** | ngx_http_vhost_traffic_status_jsonp_callback |\n| **Context** | http, server, location |\n\n`Description:` Sets the callback name for the JSONP.\n\n### vhost_traffic_status_display_sum_key\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_display_sum_key** *name* |\n| **Default** | * |\n| **Context** | http, server, location |\n\n`Description:` Sets the sum key string in serverZones field's JSON. The default sum key string is the \"*\".\n\n### vhost_traffic_status_filter\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_filter** \\\u003con\\|off\\\u003e |\n| **Default** | on |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the filter features.\n\n### vhost_traffic_status_filter_by_host\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_filter_by_host** \\\u003con\\|off\\\u003e |\n| **Default** | off |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the keys by Host header field.\nIf you set `on` and nginx's server_name directive set several or wildcard name starting with an asterisk, e.g. “*.example.org”\nand requested to server with hostname such as (a|b|c).example.org or *.example.org\nthen json serverZones is printed as follows:\n\n```Nginx\nserver {\n  server_name *.example.org;\n  vhost_traffic_status_filter_by_host on;\n\n  ...\n\n}\n```\n\n```Json\n  ...\n  \"serverZones\": {\n      \"a.example.org\": {\n      ...\n      },\n      \"b.example.org\": {\n      ...\n      },\n      \"c.example.org\": {\n      ...\n      }\n      ...\n   },\n   ...\n```\n\nIt provides the same function that set `vhost_traffic_status_filter_by_set_key $host`.\n\n### vhost_traffic_status_filter_by_set_key\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_filter_by_set_key** *key* [*name*] |\n| **Default** | - |\n| **Context** | http, server, location |\n\n`Description:` Enables the keys by user defined variable.\nThe *key* is a key string to calculate traffic.\nThe *name* is a group string to calculate traffic.\nThe *key* and *name* can contain variables such as $host, $server_name.\nThe *name*'s group belongs to `filterZones` if specified.\nThe *key*'s group belongs to `serverZones` if not specified second argument *name*.\nThe example with geoip module is as follows:\n\n```Nginx\nserver {\n  server_name example.org;\n  vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;\n\n  ...\n\n}\n```\n\n```Json\n  ...\n  \"serverZones\": {\n  ...\n  },\n  \"filterZones\": {\n      \"country::example.org\": {\n          \"KR\": {\n              \"requestCounter\":...,\n              \"inBytes\":...,\n              \"outBytes\":...,\n              \"responses\":{\n                  \"1xx\":...,\n                  \"2xx\":...,\n                  \"3xx\":...,\n                  \"4xx\":...,\n                  \"5xx\":...,\n                  \"miss\":...,\n                  \"bypass\":...,\n                  \"expired\":...,\n                  \"stale\":...,\n                  \"updating\":...,\n                  \"revalidated\":...,\n                  \"hit\":...,\n                  \"scarce\":...\n              },\n              \"requestMsecCounter\":...,\n              \"requestMsec\":...,\n              \"requestMsecs\":{\n                  \"times\":[...],\n                  \"msecs\":[...]\n              },\n          },\n          \"US\": {\n          ...\n          },\n          ...\n      },\n      ...\n  },\n  ...\n\n```\n\n### vhost_traffic_status_filter_check_duplicate\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_filter_check_duplicate** \\\u003con\\|off\\\u003e |\n| **Default** | on |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the deduplication of vhost_traffic_status_filter_by_set_key.\nIt is processed only one of duplicate values(`key` + `name`) in each directives(http, server, location) if this option is enabled.\n\n### vhost_traffic_status_filter_max_node\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_filter_max_node** *number* [*string* ...] |\n| **Default** | 0 |\n| **Context** | http |\n\n`Description:` Enables the limit of filter size using the specified *number* and *string* values.\nIf the *number* is exceeded, the existing nodes are deleted by the [LRU](https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU) algorithm.\nThe *number* argument is the size of the node that will be limited.\nThe default value `0` does not limit filters.\nThe one node is an object in `filterZones` in JSON document.\nThe *string* arguments are the matching string values for the group string value set by `vhost_traffic_status_filter_by_set_key` directive. \nEven if only the first part matches, matching is successful like the regular expression `/^string.*/`.\nBy default, If you do not set *string* arguments then it applied for all filters.\n\n\nFor examples:\n\n`$ vi nginx.conf`\n\n```Nginx\nhttp {\n\n    geoip_country /usr/share/GeoIP/GeoIP.dat;\n\n    vhost_traffic_status_zone;\n\n    # The all filters are limited to a total of 16 nodes.\n    # vhost_traffic_status_filter_max_node 16\n\n    # The `/^uris.*/` and `/^client::ports.*/` group string patterns are limited to a total of 64 nodes.\n    vhost_traffic_status_filter_max_node 16 uris client::ports;\n\n    ...\n\n    server {\n\n        server_name example.org;\n\n        ...\n\n        vhost_traffic_status_filter_by_set_key $uri uris::$server_name;\n        vhost_traffic_status_filter_by_set_key $remote_port client::ports::$server_name;\n        vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;\n\n    }\n}\n```\n\n`$ for i in {0..1000}; do curl -H 'Host: example.org' -i \"http://localhost:80/test$i\"; done`\n\n![screenshot-vts-filter-max-node](https://user-images.githubusercontent.com/3648408/41475027-96c96136-70f8-11e8-8dd6-ed1825d7b216.png)\n\nIn the above example, the `/^uris.*/` and `/^client::ports.*/` group string patterns are limited to a total of 16 nodes.\nThe other filters like `country::.*` are not limited.\n\n### vhost_traffic_status_limit\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_limit** \\\u003con\\|off\\\u003e |\n| **Default** | on |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the limit features.\n\n### vhost_traffic_status_limit_traffic\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_limit_traffic** *member*:*size* [*code*] |\n| **Default** | - |\n| **Context** | http, server, location |\n\n`Description:` Enables the traffic limit for specified *member*.\nThe *member* is a member string to limit traffic.\nThe *size* is a size(k/m/g) to limit traffic.\nThe *code* is a code to return in response to rejected requests.(Default: 503)\n\nThe available *`member`* strings are as follows:\n* **request**\n  * The total number of client requests received from clients.\n* **in**\n  * The total number of bytes received from clients.\n* **out**\n  * The total number of bytes sent to clients.\n* **1xx**\n  * The number of responses with status codes 1xx.\n* **2xx**\n  * The number of responses with status codes 2xx.\n* **3xx**\n  * The number of responses with status codes 3xx.\n* **4xx**\n  * The number of responses with status codes 4xx.\n* **5xx**\n  * The number of responses with status codes 5xx.\n* **cache_miss**\n  * The number of cache miss.\n* **cache_bypass**\n  * The number of cache bypass.\n* **cache_expired**\n  * The number of cache expired.\n* **cache_stale**\n  * The number of cache stale.\n* **cache_updating**\n  * The number of cache updating.\n* **cache_revalidated**\n  * The number of cache revalidated.\n* **cache_hit**\n  * The number of cache hit.\n* **cache_scarce**\n  * The number of cache scare.\n\n### vhost_traffic_status_limit_traffic_by_set_key\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_limit_traffic_by_set_key** *key* *member*:*size* [*code*] |\n| **Default** | - |\n| **Context** | http, server, location|\n\n`Description:` Enables the traffic limit for specified *key* and *member*.\nThe *key* is a key string to limit traffic.\nThe *member* is a member string to limit traffic.\nThe *size* is a size(k/m/g) to limit traffic.\nThe *code* is a code to return in response to rejected requests.(Default: 503)\n\n\nThe *`key`* syntax is as follows:\n* *`group`*@[*`subgroup`*@]*`name`*\n\nThe available *`group`* strings are as follows:\n* **NO**\n  * The group of server.\n* **UA**\n  * The group of upstream alone.\n* **UG**\n  * The group of upstream group.(use *`subgroup`*)\n* **CC**\n  * The group of cache.\n* **FG**\n  * The group of filter.(use *`subgroup`*)\n\nThe available *`member`* strings are as follows:\n* **request**\n  * The total number of client requests received from clients.\n* **in**\n  * The total number of bytes received from clients.\n* **out**\n  * The total number of bytes sent to clients.\n* **1xx**\n  * The number of responses with status codes 1xx.\n* **2xx**\n  * The number of responses with status codes 2xx.\n* **3xx**\n  * The number of responses with status codes 3xx.\n* **4xx**\n  * The number of responses with status codes 4xx.\n* **5xx**\n  * The number of responses with status codes 5xx.\n* **cache_miss**\n  * The number of cache miss.\n* **cache_bypass**\n  * The number of cache bypass.\n* **cache_expired**\n  * The number of cache expired.\n* **cache_stale**\n  * The number of cache stale.\n* **cache_updating**\n  * The number of cache updating.\n* **cache_revalidated**\n  * The number of cache revalidated.\n* **cache_hit**\n  * The number of cache hit.\n* **cache_scarce**\n  * The number of cache scare.\n\nThe *member* is the same as `vhost_traffic_status_limit_traffic` directive.\n\n### vhost_traffic_status_limit_check_duplicate\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_limit_check_duplicate** \\\u003con\\|off\\\u003e |\n| **Default** | on |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables the deduplication of vhost_traffic_status_limit_by_set_key.\nIt is processed only one of duplicate values(`member` | `key` + `member`)\nin each directives(http, server, location) if this option is enabled.\n\n### vhost_traffic_status_set_by_filter\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_set_by_filter** *$variable* *group*/*zone*/*name* |\n| **Default** | - |\n| **Context** | http, server, location, if |\n\n`Description:` Get the specified status value stored in shared memory.\nIt can acquire almost all status values and the obtained value is stored in *$variable* which is first argument.\n\n* **group**\n  * server\n  * filter\n  * upstream@alone\n  * upstream@group\n  * cache\n* **zone**\n  * server\n    * *name*\n  * filter\n    * *filter_group*@*name*\n  * upstream@group\n    * *upstream_group*@*name*\n  * upstream@alone\n    * @*name*\n  * cache\n    * *name*\n* **name**\n  * requestCounter\n    * The total number of client requests received from clients.\n  * requestMsecCounter\n    * The number of accumulated request processing time in milliseconds.\n  * requestMsec\n    * The average of request processing times in milliseconds.\n  * responseMsecCounter\n    * The number of accumulated only upstream response processing time in milliseconds.\n  * responseMsec\n    * The average of only upstream response processing times in milliseconds.\n  * inBytes\n    * The total number of bytes received from clients.\n  * outBytes\n    * The total number of bytes sent to clients.\n  * 1xx, 2xx, 3xx, 4xx, 5xx\n    * The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.\n  * cacheMaxSize\n    * The limit on the maximum size of the cache specified in the configuration.\n  * cacheUsedSize\n    * The current size of the cache.\n  * cacheMiss\n    * The number of cache miss.\n  * cacheBypass\n    * The number of cache bypass.\n  * cacheExpired\n    * The number of cache expired.\n  * cacheStale\n    * The number of cache stale.\n  * cacheUpdating\n    * The number of cache updating.\n  * cacheRevalidated\n    * The number of cache revalidated.\n  * cacheHit\n    * The number of cache hit.\n  * cacheScarce\n    * The number of cache scare.\n  * weight\n    * Current weight setting of the server.\n  * maxFails\n    * Current max_fails setting of the server.\n  * failTimeout\n    * Current fail_timeout setting of the server.\n  * backup\n    * Current backup setting of the server.(0\\|1)\n  * down\n    * Current down setting of the server.(0\\|1)\n\n`Caveats:` The *name* is case sensitive. All return values take the integer type.\n\nFor examples:\n* requestCounter in serverZones\n  * **vhost_traffic_status_set_by_filter** `$requestCounter` `server/example.org/requestCounter`\n* requestCounter in filterZones\n  * **vhost_traffic_status_set_by_filter** `$requestCounter` `filter/country::example.org@KR/requestCounter`\n* requestCounter in upstreamZones\n  * **vhost_traffic_status_set_by_filter** `$requestCounter` `upstream@group/backend@10.10.10.11:80/requestCounter`\n* requestCounter in upstreamZones::nogroups\n  * **vhost_traffic_status_set_by_filter** `$requestCounter` `upstream@alone/10.10.10.11:80/requestCounter`\n* cacheHit in cacheZones\n  * **vhost_traffic_status_set_by_filter** `$cacheHit` `cache/my_cache_name/cacheHit`\n\n### vhost_traffic_status_average_method\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_average_method** \\\u003cAMM\\|WMA\\\u003e [*period*] |\n| **Default** | AMM 60s |\n| **Context** | http, server, location |\n\n`Description:` Sets the method which is a formula that calculate the average of response processing times.\nThe *period* is an effective time of the values used for the average calculation.(Default: 60s)\nIf *period* set to 0, effective time is ignored.\nIn this case, the last average value is displayed even if there is no requests and after the elapse of time.\nThe corresponding values are `requestMsec` and `responseMsec` in JSON.\n\n* **AMM**\n  * The AMM is the [arithmetic mean](https://en.wikipedia.org/wiki/Arithmetic_mean).\n* **WMA**\n  * THE WMA is the [weighted moving average](https://en.wikipedia.org/wiki/Moving_average#Weighted_moving_average).\n\n### vhost_traffic_status_histogram_buckets\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_histogram_buckets** *second* ... |\n| **Default** | - |\n| **Context** | http, server, location |\n\n`Description:` Sets the observe buckets to be used in the histograms.\nBy default, if you do not set this directive, it will not work.\nThe *second* can be expressed in decimal places with a minimum value of 0.001(1ms).\nThe maximum size of the buckets is 32. If this value is insufficient for you,\nchange the `NGX_HTTP_VHOST_TRAFFIC_STATUS_DEFAULT_BUCKET_LEN` in the `src/ngx_http_vhost_traffic_status_node.h`\n\nFor examples:\n* **vhost_traffic_status_histogram_buckets** `0.005` `0.01` `0.05` `0.1` `0.5` `1` `5` `10`\n  * The observe buckets are [5ms 10ms 50ms 100ms 500ms 1s 5s 10s].\n* **vhost_traffic_status_histogram_buckets** `0.005` `0.01` `0.05` `0.1`\n  * The observe buckets are [5ms 10ms 50ms 100ms].\n\n`Caveats:` By default, if you do not set this directive, the histogram statistics does not work.\nThe restored histograms by `vhost_traffic_status_dump` directive have no affected by changes to the buckets\nby `vhost_traffic_status_histogram_buckets` directive.\nSo you must first delete the zone or the dump file before changing the buckets\nby `vhost_traffic_status_histogram_buckets` directive.\nSimilar to the above, delete the dump file when using the histogram for the first time.\n\n### vhost_traffic_status_bypass_limit\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_bypass_limit** \\\u003con\\|off\\\u003e |\n| **Default** | off |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables to bypass `vhost_traffic_status_limit` directives.\nThe limit features is bypassed if this option is enabled.\nThis is mostly useful if you want to connect the status web page like `/status` regardless of `vhost_traffic_status_limit` directives as follows:\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        ...\n\n        location /status {\n            vhost_traffic_status_bypass_limit on;\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n### vhost_traffic_status_bypass_stats\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_bypass_stats** \\\u003con\\|off\\\u003e |\n| **Default** | off |\n| **Context** | http, server, location |\n\n`Description:` Enables or disables to bypass `vhost_traffic_status`.\nThe traffic status stats features is bypassed if this option is enabled.\nIn other words, it is excluded from the traffic status stats.\nThis is mostly useful if you want to ignore your request in status web page like `/status` as follows:\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n\n    ...\n\n    server {\n\n        ...\n\n        location /status {\n            vhost_traffic_status_bypass_stats on;\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n    }\n}\n```\n\n### vhost_traffic_status_stats_by_upstream\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | **vhost_traffic_status_stats_by_upstream** \\\u003con\\|off\\\u003e |\n| **Default** | on  |\n| **Context** | http|\n\n`Description:` Enables or disables to stats `upstreamZone`.\nThe `upstreamZone` in the traffic status stats features is bypassed if this option is disabled.\nIn other words, it is excluded from the traffic status stats.\nThis is mostly useful if you want to be disable statistics collection for upstream servers to reduce CPU load.\n\n```Nginx\nhttp {\n    vhost_traffic_status_zone;\n    vhost_traffic_status_stats_by_upstream off;\n\n    proxy_cache_path /var/cache/nginx keys_zone=zone1:1m max_size=1g inactive=24h;\n    upstream backend {\n       ...\n    }\n    ...\n\n    server {\n\n        ...\n\n        location /status {\n            vhost_traffic_status_display;\n            vhost_traffic_status_display_format html;\n        }\n        location /backend {\n            proxy_cache zone1;\n            proxy_pass http://backend;\n        }\n    }\n}\n```\n\n### vhost_traffic_status_measure_status_codes\n\nAllows tracking of specific HTTP status codes or all status codes in the Vhost Traffic Status module.\n\n\n| -   | - |\n| --- | --- |\n| **Syntax**  | vhost_traffic_status_measure_status_codes [all] [status_code1] [status_code2] ... |\n| **Default** | off |\n| **Context** | http |\n\n\n\n#### Parameters\n- `status_code1, status_code2, ...`: Specific HTTP status codes to track (100-599)\n- `all`: Track all HTTP status codes\n\n#### Examples\n\nTrack specific status codes:\n```nginx\nvhost_traffic_status_measure_status_codes 200 404 500;\n```\n\nTrack all status codes:\n```nginx\nvhost_traffic_status_measure_status_codes all;\n```\n\n#### Description\n- By default, no specific status code tracking is enabled\n- Status codes must be in ascending order\n- Only valid HTTP status codes between 100 and 599 are accepted\n- When using `all`, every status code will be tracked\n\n## Releases\n\nTo cut a release, create a changelog entry PR with [git-chglog](https://github.com/git-chglog/git-chglog)\n\n    version=\"v0.2.0\"\n    git checkout -b \"cut-${version}\"\n    git-chglog -o CHANGELOG.md --next-tag \"${version}\"\n    git add CHANGELOG.md\n    sed -i \"s/NGX_HTTP_VTS_MODULE_VERSION \\\".*/NGX_HTTP_VTS_MODULE_VERSION \\\"${version}\\\"/\" src/ngx_http_vhost_traffic_status_module.h\n    git add src/ngx_http_vhost_traffic_status_module.h\n    git-chglog -t .chglog/RELNOTES.tmpl --next-tag \"${version}\" \"${version}\" | git commit -F-\n    \nAfter the PR is merged, create the new tag and release on the [GitHub Releases](https://github.com/vozlt/nginx-module-vts/releases).\n\n## See Also\n* Stream traffic status\n  * [nginx-module-sts](https://github.com/vozlt/nginx-module-sts)\n  * [nginx-module-stream-sts](https://github.com/vozlt/nginx-module-stream-sts)\n\n* Prometheus\n  * [nginx-vts-exporter](https://github.com/hnlq715/nginx-vts-exporter)\n\n* System protection\n  * [nginx-module-sysguard](https://github.com/vozlt/nginx-module-sysguard)\n\n## TODO\n* Add an implementation that periodically updates computed statistic in each worker processes to shared memory to reduce the contention due to locks when using ngx_shmtx_lock().\n\n## Author\nYoungJoo.Kim(김영주) [\u003cvozltx@gmail.com\u003e]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvozlt%2Fnginx-module-vts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvozlt%2Fnginx-module-vts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvozlt%2Fnginx-module-vts/lists"}