├── README-cn.md ├── README.md ├── _ngx_shmap.c ├── _ngx_shmap.h ├── conf └── nginx.conf ├── config ├── ngx_http_request_stats_module.c ├── ngx_http_request_stats_module.h ├── test.sh └── view_html.png /README-cn.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jie123108/ngx_request_stats/ec65ae40f8e767f24e86f7a1888450239577057e/README-cn.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nginx statistics module 2 | ngx_request_stats is a statistical nginx module. Statistical item is configurable, and can count different virtual hosts, different URL. You can request statistics including the number of times of each status code, the flowing output of the accumulated information, the average processing time, and so on. 3 | 4 | [中文版说明](README-cn.md) 5 | # Table of contents 6 | 7 | * [Synopsis] (#synopsis) 8 | * [Compatibility] (#compatibility) 9 | * [Installation] (#installation) 10 | * [Variables] (#variables) 11 | * [Directives] (#directives) 12 | * [shmap_size] (#shmap_size) 13 | * [shmap_exptime] (#shmap_exptime) 14 | * [request_stats] (#request_stats) 15 | * [request_stats_query] (#request_stats_query) 16 | * [statistics Query] (#statistics-query) 17 | * [text format] (#text-format) 18 | * [html format] (#html-format) 19 | * [json format] (#json-format) 20 | * [Query and clear] (#query-and-clear) 21 | * [Query By stats_name] (#query-by-status_name) 22 | * [Scoping] (#scope) 23 | * [Simple test script] (#simple-test-script) 24 | * [Related modules] (#see-also) 25 | 26 | # Synopsis 27 | ```nginx 28 | http { 29 | request_stats statby_host "$host"; 30 | shmap_size 32m; 31 | shmap_exptime 2d; 32 | 33 | server { 34 | listen 81; 35 | server_name localhost; 36 | location / { 37 | echo "byhost:$uri"; 38 | } 39 | location /404 { 40 | return 404; 41 | } 42 | } 43 | 44 | server { 45 | listen 80; 46 | server_name localhost; 47 | 48 | location /stats { 49 | request_stats off; #do not stats. 50 | request_stats_query on; 51 | allow 127.0.0.1; 52 | allow 192.168.0.0/16; 53 | deny all; 54 | } 55 | 56 | location /byuri { 57 | request_stats statby_uri "uri:$uri"; 58 | echo "byuri: $uri"; 59 | } 60 | 61 | location /byarg { 62 | echo_sleep 0.005; 63 | request_stats statby_arg "clitype:$arg_client_type"; 64 | echo "login $args"; 65 | } 66 | 67 | location /byarg/404 { 68 | request_stats statby_arg "clitype:$arg_client_type"; 69 | return 404; 70 | } 71 | 72 | location /byuriarg { 73 | request_stats statby_uriarg "$uri?$arg_from"; 74 | echo "$uri?$args"; 75 | } 76 | 77 | location /byhttpheaderin { 78 | request_stats statby_headerin "header_in:$http_city"; 79 | echo "city: $http_city"; 80 | } 81 | 82 | location /byhttpheaderout/ { 83 | request_stats statby_headerout "cache:$sent_http_cache"; 84 | proxy_pass http://127.0.0.1:82; 85 | } 86 | } 87 | 88 | server { 89 | listen 82; 90 | server_name localhost; 91 | location /byhttpheaderout/hit { 92 | add_header cache hit; 93 | echo "cache: hit"; 94 | } 95 | location /byhttpheaderout/miss { 96 | add_header cache miss; 97 | echo "cache: miss"; 98 | } 99 | } 100 | } 101 | ``` 102 | 103 | # Compatibility 104 | This module is compatible with the following versions nginx: 105 | * 1.7.x (last tested: 1.7.4) 106 | * 1.6.x (last tested: 1.6.1) 107 | * 1.4.x (last tested: 1.4.7) 108 | * 1.2.x (last tested: 1.2.9) 109 | * 1.0.x (last tested: 1.0.15) 110 | 111 | 112 | # Installation 113 | ``` 114 | # echo-nginx-module just need to use for the test, this module does not depend on it. 115 | cd nginx-1.x.x 116 | ./configure --add-module = path / to / ngx_request_stats \ 117 | --add-module = path / to / echo-nginx-module-0.49 / 118 | make 119 | make install 120 | ``` 121 | 122 | # Variables 123 | * nginx_core module supports variable: http://nginx.org/en/docs/http/ngx_http_core_module.html#variables 124 | * This module variables 125 | * uri_full: uri before redirect. 126 | * status: Http response codes 127 | * date: current date in the format: 1970-09-28 128 | * time: current time in the format: 12: 00:00 129 | * year: current year 130 | * month: current month 131 | * day: current date 132 | * hour: current hour 133 | * minute: current minute 134 | * second: current second 135 | 136 | # Directives 137 | * [shmap_size] (#shmap_size) 138 | * [shmap_exptime] (#shmap_exptime) 139 | * [request_stats] (#request_stats) 140 | * [request_stats_query] (#request_stats_query) 141 | 142 | shmap_size 143 | ---------- 144 | **syntax:** *shmap_size <size>* 145 | 146 | **default:** *32m* 147 | 148 | **context:** *http* 149 | 150 | Define shared memory size. 151 | 152 | The **<size>** argument accepts size units such as k,m and g. 153 | 154 | shmap_exptime 155 | ---------- 156 | **syntax:** *shmap_exptime <expire time>* 157 | 158 | **default:** *2d* 159 | 160 | **context:** *http* 161 | 162 | Definition of statistical information in the shared memory expiration time. 163 | 164 | The **<expire time>** argument can be an integer, with an optional time unit, like s(second), m(minute), h(hour), d(day). The default time unit is s 165 | 166 | request_stats 167 | ---------- 168 | **syntax:** *request_stats <stats-name> <stats-key>* 169 | 170 | **default:** *no* 171 | 172 | **context:** *http, server, location, location if* 173 | 174 | Statistics definition format, use the `request_stats off;` can close a statistic under the http, server, location. 175 | * stats-name is the name of the statistics (category), according to the function arbitrarily defined, in the back of the query command, you can specify the stats-name query specified statistical type. 176 | * stats-key definition of statistical key. key can be used the variables, and a string, so that different requests will be recorded separately. [Supported variable] (#variables) one lists all the supported variables. **Note: Do not use too randomized variables as key, this will cause each request has a statistical information, which take up a lot of shared memory space** 177 | 178 | #### Statistics by host 179 | ```nginx 180 | request_stats statby_host "$host"; 181 | ``` 182 | #### Statistics by uri 183 | ```nginx 184 | request_stats statby_uri "uri: $uri"; # also adds uri: prefix. 185 | ``` 186 | #### Statistics by get request parameters 187 | ```nginx 188 | request_stats statby_arg "clitype: $arg_client_type"; # press parameters client_type statistics 189 | ``` 190 | 191 | #### Statistics by uri and parameters 192 | ```nginx 193 | request_stats statby_uriarg "$uri?$arg_from"; 194 | ``` 195 | 196 | ### Statistics by request header 197 | ```nginx 198 | request_stats statby_uriarg "header_in: $http_city"; 199 | ``` 200 | ### Statistics by response header 201 | ```nginx 202 | request_stats statby_uriarg "cache: $sent_http_cache"; 203 | ``` 204 | 205 | request_stats_query 206 | ---------- 207 | **syntax:** *request_stats_query < on >* 208 | 209 | **default:** *off* 210 | 211 | **context:** *location* 212 | 213 | Open statistical query module. When turned on, you can have access to the statistics by the location. 214 | Statistics Query module has three optional arguments: 215 | * clean: is true that the query statistics and statistical items cleared for this query. 216 | * fmt: optional values: html, json, text, respectively, html, json, text format. The default format is text. html browser can be viewed directly, allowing you to json format using scripting language(eg. python/php) parsing results. text format in order to facilitate inquiries, and processed through awk and other shell commands. 217 | * stats_name: To count name queries, the statistics must be a name in the first parameter request_stats instructions specified in the stats-name. When this parameter is not specified, query all statistics. 218 | 219 | 220 | Minimum sample: 221 | ```nginx 222 | location / stats { 223 | request_stats_query on; 224 | } 225 | ``` 226 | Statistics Query see [statistical inquiry] (#statistical-queries) a 227 | 228 | Statistics-Query 229 | -------------- 230 |     after opening request_stats_query, statistical results can be accessed via the corresponding uri, for example in the previous section configuration, access 231 | http://192.168.1.201/stats can display relevant statistics. **192.168.1.201 is my host** 232 | 233 | Query results typically has the following fields: 234 | * key, request_stats defined key 235 | * stats_time, statistics Start Time 236 | * request, the number of requests 237 | * recv, receiving the number of bytes 238 | * sent, bytes sent 239 | * avg_time, request the average time (in milliseconds) 240 | * stats, http response code, where 499 means the backend is timeout. 241 | 242 |     ** the following query results are in operation [simple test script] after (# simple script to test) section of the test scripts produced. ** 243 | 244 | #### Text Format 245 | http://192.168.1.201/stats 246 | ```bash 247 | # Optional parameters: 248 | # clean=true, query stats and set the all query data to zero in the share memory. 249 | # fmt=[html|json|text], The default is text. 250 | # stats_name=[ statby_host| statby_uri| statby_arg| statby_uriarg| statby_headerin| statby_headerout], The default is all. 251 | key stats_time request recv sent avg_time stat 252 | localhost 2014-08-31 22:16:47 1 0 0 0 400:1 253 | 127.0.0.1 2014-08-31 22:16:29 80 14687 15854 0 200:60, 404:20 254 | cache:miss 2014-08-31 22:16:29 20 3560 3800 0 200:20 255 | cache:hit 2014-08-31 22:16:29 20 3540 3760 0 200:20 256 | header_in:beijing 2014-08-31 22:16:29 20 3740 3580 0 200:20 257 | header_in:shengzheng 2014-08-31 22:16:29 20 3800 3660 0 200:20 258 | header_in:shanghai 2014-08-31 22:16:29 20 3760 3600 0 200:20 259 | /byuriarg?mobile_cli 2014-08-31 22:16:29 20 3640 3840 0 200:20 260 | /byuriarg?pc_cli 2014-08-31 22:16:29 20 3560 3760 0 200:20 261 | /byuriarg?partner 2014-08-31 22:16:29 20 3580 3780 0 200:20 262 | clitype:android 2014-08-31 22:16:29 40 7400 10280 2 200:20, 404:20 263 | clitype:ios 2014-08-31 22:16:29 20 3580 3760 5 200:20 264 | clitype:pc 2014-08-31 22:16:29 20 3560 3740 5 200:20 265 | uri:/byuri/14858 2014-08-31 22:16:30 1 169 186 0 200:1 266 | uri:/byuri/10475 2014-08-31 22:16:30 1 169 186 0 200:1 267 | ... 268 | ``` 269 | #### Html Format 270 | http://192.168.1.201/stats?fmt=html 271 | ![查询界面](view_html.png) 272 | 273 | #### Json format 274 | http://192.168.1.201/stats?fmt=json 275 | ```json 276 | {"Optional parameters":{ 277 | "clean":"clean=true, query stats and set the all query data to zero in the share memory.", 278 | "fmt":"fmt=[html|json|text], The default is text.", 279 | "stats_name":[" statby_host| statby_uri| statby_arg| statby_uriarg| statby_headerin| statby_headerout"] 280 | }, 281 | "request-stat":{ 282 | "localhost":{"stats_time":"2014-08-31 22:16:47","request":2,"recv":0,"sent":0,"avg_time":0,"stat":{"400":2}}, 283 | "127.0.0.1":{"stats_time":"2014-08-31 22:16:29","request":80,"recv":14687,"sent":15854,"avg_time":0,"stat":{"200":60,"404":20}}, 284 | "cache:miss":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3560,"sent":3800,"avg_time":0,"stat":{"200":20}}, 285 | "cache:hit":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3540,"sent":3760,"avg_time":0,"stat":{"200":20}}, 286 | "header_in:beijing":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3740,"sent":3580,"avg_time":0,"stat":{"200":20}}, 287 | "header_in:shengzheng":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3800,"sent":3660,"avg_time":0,"stat":{"200":20}}, 288 | "header_in:shanghai":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3760,"sent":3600,"avg_time":0,"stat":{"200":20}}, 289 | "/byuriarg?mobile_cli":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3640,"sent":3840,"avg_time":0,"stat":{"200":20}}, 290 | "/byuriarg?pc_cli":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3560,"sent":3760,"avg_time":0,"stat":{"200":20}}, 291 | "/byuriarg?partner":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3580,"sent":3780,"avg_time":0,"stat":{"200":20}}, 292 | "clitype:android":{"stats_time":"2014-08-31 22:16:29","request":40,"recv":7400,"sent":10280,"avg_time":2,"stat":{"200":20,"404":20}}, 293 | "clitype:ios":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3580,"sent":3760,"avg_time":5,"stat":{"200":20}}, 294 | "clitype:pc":{"stats_time":"2014-08-31 22:16:29","request":20,"recv":3560,"sent":3740,"avg_time":5,"stat":{"200":20}}, 295 | "uri:/byuri/14858":{"stats_time":"2014-08-31 22:16:30","request":1,"recv":169,"sent":186,"avg_time":0,"stat":{"200":1}}, 296 | "uri:/byuri/10475":{"stats_time":"2014-08-31 22:16:30","request":1,"recv":169,"sent":186,"avg_time":0,"stat":{"200":1}} 297 | } 298 | } 299 | ``` 300 | #### query and clear 301 | http://192.168.1.201/stats?clean=true 302 | After use clean = true parameter, this query results are still normal, but all result items will be cleared. 303 | 304 | #### Query by status_name 305 | * http://192.168.1.201/stats?stats_name=statby_headerin 306 | 307 | ```text 308 | key stats_time request recv sent avg_time stat 309 | header_in: beijing 2014-08-31 22:16:29 20 3740 3580 0 200: 20 310 | header_in: shengzheng 2014-08-31 22:16:29 20 3800 3660 0 200: 20 311 | header_in: shanghai 2014-08-31 22:16:29 20 3760 3600 0 200: 20 312 | ``` 313 | * http://192.168.1.201/stats?stats_name=statby_uri 314 | 315 | ```text 316 | key stats_time request recv sent avg_time stat 317 | uri: / byuri / 14858 2014-08-31 22:16:30 1 169 186 0 200: 1 318 | uri: / byuri / 10475 2014-08-31 22:16:30 1 169 186 0 200: 1 319 | uri: / byuri / 20090 2014-08-31 22:16:30 1 169 186 0 200: 1 320 | uri: / byuri / 7054 2014-08-31 22:16:30 1 168 185 0 200: 1 321 | uri: / byuri / 31520 2014-08-31 22:16:30 1 169 186 0 200: 1 322 | uri: / byuri / 22000 2014-08-31 22:16:30 1 169 186 0 200: 1 323 | uri: / byuri / 24415 2014-08-31 22:16:30 1 169 186 0 200: 1 324 | uri: / byuri / 20883 2014-08-31 22:16:30 1 169 186 0 200: 1 325 | ``` 326 | 327 | # Scope 328 | > request_stats directive scope are: 329 | `NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF`, ie request_stats instructions at http, server, location, if peers can occur. However, due to this module is a plug-in NGX_HTTP_LOG_PHASE stage, a request will have a configuration item is valid. When they appear in different levels, only the innermost will start effect. Of course, if there are multiple request_stats instruction with the inside layer, a plurality will have effect. For example: 330 | ``` 331 | http { 332 | # ... 333 | request_stats byhost "$host"; 334 | server { 335 | listen 80; 336 | location / login { 337 | echo "login"; 338 | } 339 | location / login_new { 340 | request_stats byarg "$arg_client_type"; 341 | echo "login_new $args"; 342 | } 343 | } 344 | } 345 | ``` 346 | ##### Using the above configuration, if we make the following three requests: 347 | ```shell 348 | curl http://127.0.0.1:80/login 349 | curl http://127.0.0.1:80/login_new?client_type=pc 350 | curl http://127.0.0.1:80/login_new?client_type=android 351 | ``` 352 | ##### Statistical results would be: 353 | ``` 354 | key request recv sent avg_time 355 | android 1 187 210 0 356 | pc 1 182 205 0 357 | 127.0.0.1 1 163 185 0 358 | ``` 359 | / login_new following request, since there is already a statistic called byarg will not repeat the statistics to byhost inside. Sometimes this may not be the result you want. If you want / login_new also statistics into byhost inside, you can add a request_stats instructions / login_new after the new configuration below: 360 | ``` 361 | http { 362 | # ... 363 | request_stats byhost "$host"; 364 | server { 365 | listen 80; 366 | location / login { 367 | echo "login"; 368 | } 369 | location / login_new { 370 | request_stats byarg "$arg_client_type"; 371 | request_stats byhost "$host"; 372 | echo "login_new $args"; 373 | } 374 | } 375 | } 376 | ``` 377 | ##### After retest results are as follows: 378 | ``` 379 | key request recv sent avg_time 380 | 127.0.0.1 3 532 600 0 381 | android 1 187 210 0 382 | pc 1 182 205 0 383 | ``` 384 | 385 | 386 | 387 | #### Simple test script 388 | 389 | This test corresponds to the configuration in the Synopsis section. 390 | Test depends on the curl command, make sure your system has been installed curl command line. 391 | [test.sh] (test.sh) source code directory 392 | ```bash 393 | for ((i = 0; i <20; i ++)); do 394 | curl http://127.0.0.1:81/$RANDOM 395 | curl http://127.0.0.1:81/404/$RANDOM 396 | curl http://127.0.0.1:80/byuri/$RANDOM 397 | curl http://127.0.0.1:80/byarg?client_type=pc 398 | curl http://127.0.0.1:80/byarg?client_type=ios 399 | curl http://127.0.0.1:80/byarg?client_type=android 400 | curl http://127.0.0.1:80/byarg/404?client_type=android 401 | curl http://127.0.0.1:80/byuriarg?from=partner 402 | curl http://127.0.0.1:80/byuriarg?from=pc_cli 403 | curl http://127.0.0.1:80/byuriarg?from=mobile_cli 404 | curl http://127.0.0.1:80/byhttpheaderin -H "city: shanghai" 405 | curl http://127.0.0.1:80/byhttpheaderin -H "city: shengzheng" 406 | curl http://127.0.0.1:80/byhttpheaderin -H "city: beijing" 407 | curl http://127.0.0.1:80/byhttpheaderout/hit 408 | curl http://127.0.0.1:80/byhttpheaderout/miss 409 | done; 410 | 411 | ``` 412 | 413 | # See Also 414 |         This module all statistical information is stored in memory, require the user to obtain relevant information, and then store the summary. On another project [ngx_req_stat] (https://github.com/jie123108/ngx_req_stat) is a request for statistics module, but it's more powerful, not only key is customizable, even the statistical value also can be customized . And statistical information stored in mongodb in. Project Address: (https://github.com/jie123108/ngx_req_stat) 415 | 416 | Authors 417 | ======= 418 | 419 | * liuxiaojie (刘小杰) 420 | 421 | [Back to TOC](#table-of-contents) 422 | 423 | Copyright & License 424 | =================== 425 | 426 | This module is licenced under the BSD license. 427 | 428 | Copyright (C) 2014, by liuxiaojie (刘小杰) 429 | 430 | All rights reserved. 431 | -------------------------------------------------------------------------------- /_ngx_shmap.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jie123108/ngx_request_stats/ec65ae40f8e767f24e86f7a1888450239577057e/_ngx_shmap.c -------------------------------------------------------------------------------- /_ngx_shmap.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jie123108/ngx_request_stats/ec65ae40f8e767f24e86f7a1888450239577057e/_ngx_shmap.h -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user root; 3 | worker_processes 3; 4 | 5 | daemon on; 6 | master_process on; 7 | worker_rlimit_core 50000000; 8 | working_directory /tmp; 9 | 10 | error_log logs/error.log; 11 | 12 | #pid logs/nginx.pid; 13 | 14 | 15 | events { 16 | worker_connections 1024; 17 | } 18 | 19 | http { 20 | request_stats statby_host "$host"; 21 | shmap_size 32m; 22 | shmap_exptime 2d; 23 | 24 | server { 25 | listen 81; 26 | server_name localhost; 27 | location / { 28 | echo "byhost:$uri"; 29 | } 30 | location /404 { 31 | return 404; 32 | } 33 | } 34 | 35 | server { 36 | listen 80; 37 | server_name localhost; 38 | 39 | location /stats { 40 | request_stats off; #do not stats. 41 | request_stats_query on; 42 | allow 127.0.0.1; 43 | allow 192.168.0.0/16; 44 | deny all; 45 | } 46 | 47 | location /byuri { 48 | request_stats statby_uri "uri:$uri"; 49 | echo "byuri: $uri"; 50 | } 51 | 52 | location /byarg { 53 | echo_sleep 0.005; 54 | request_stats statby_arg "clitype:$arg_client_type"; 55 | echo "login $args"; 56 | } 57 | 58 | location /byarg/404 { 59 | request_stats statby_arg "clitype:$arg_client_type"; 60 | return 404; 61 | } 62 | 63 | location /byuriarg { 64 | request_stats statby_uriarg "$uri?$arg_from"; 65 | echo "$uri?$args"; 66 | } 67 | 68 | location /byhttpheaderin { 69 | request_stats statby_headerin "header_in:$http_city"; 70 | echo "city: $http_city"; 71 | } 72 | 73 | location /byhttpheaderout/ { 74 | request_stats statby_headerout "cache:$sent_http_cache"; 75 | proxy_pass http://127.0.0.1:82; 76 | } 77 | } 78 | 79 | server { 80 | listen 82; 81 | server_name localhost; 82 | location /byhttpheaderout/hit { 83 | add_header cache hit; 84 | echo "cache: hit"; 85 | } 86 | location /byhttpheaderout/miss { 87 | add_header cache miss; 88 | echo "cache: miss"; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /config: -------------------------------------------------------------------------------- 1 | 2 | HTTP_MODULES="$HTTP_MODULES ngx_http_request_stats_module" 3 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_request_stats_module.c" 4 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/_ngx_shmap.c" 5 | -------------------------------------------------------------------------------- /ngx_http_request_stats_module.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jie123108/ngx_request_stats/ec65ae40f8e767f24e86f7a1888450239577057e/ngx_http_request_stats_module.c -------------------------------------------------------------------------------- /ngx_http_request_stats_module.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jie123108/ngx_request_stats/ec65ae40f8e767f24e86f7a1888450239577057e/ngx_http_request_stats_module.h -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for ((i=0;i<20;i++));do 4 | curl http://127.0.0.1:81/$RANDOM 5 | curl http://127.0.0.1:81/404/$RANDOM 6 | curl http://127.0.0.1:80/byuri/$RANDOM 7 | curl http://127.0.0.1:80/byarg?client_type=pc 8 | curl http://127.0.0.1:80/byarg?client_type=ios 9 | curl http://127.0.0.1:80/byarg?client_type=android 10 | curl http://127.0.0.1:80/byarg/404?client_type=android 11 | curl http://127.0.0.1:80/byuriarg?from=partner 12 | curl http://127.0.0.1:80/byuriarg?from=pc_cli 13 | curl http://127.0.0.1:80/byuriarg?from=mobile_cli 14 | curl http://127.0.0.1:80/byhttpheaderin -H"city: shanghai" 15 | curl http://127.0.0.1:80/byhttpheaderin -H"city: shengzheng" 16 | curl http://127.0.0.1:80/byhttpheaderin -H"city: beijing" 17 | curl http://127.0.0.1:80/byhttpheaderout/hit 18 | curl http://127.0.0.1:80/byhttpheaderout/miss 19 | done; 20 | 21 | -------------------------------------------------------------------------------- /view_html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jie123108/ngx_request_stats/ec65ae40f8e767f24e86f7a1888450239577057e/view_html.png --------------------------------------------------------------------------------