{"id":13776271,"url":"https://github.com/iresty/Mio","last_synced_at":"2025-05-11T10:30:54.961Z","repository":{"id":96165147,"uuid":"64641871","full_name":"iresty/Mio","owner":"iresty","description":" API statistics/summary and health datas in NGINX based on OpenResty/ngx_lua, just like NGINX Plus","archived":false,"fork":false,"pushed_at":"2016-12-06T10:54:14.000Z","size":1104,"stargazers_count":285,"open_issues_count":3,"forks_count":69,"subscribers_count":33,"default_branch":"master","last_synced_at":"2024-02-13T21:51:35.028Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iresty.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2016-08-01T06:31:28.000Z","updated_at":"2023-12-11T06:17:07.000Z","dependencies_parsed_at":"2023-04-12T05:34:36.251Z","dependency_job_id":null,"html_url":"https://github.com/iresty/Mio","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iresty%2FMio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iresty%2FMio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iresty%2FMio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iresty%2FMio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iresty","download_url":"https://codeload.github.com/iresty/Mio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253551499,"owners_count":21926304,"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":[],"created_at":"2024-08-03T18:00:21.621Z","updated_at":"2025-05-11T10:30:53.836Z","avatar_url":"https://github.com/iresty.png","language":"Lua","funding_links":[],"categories":["Libraries"],"sub_categories":[],"readme":"# Mio\n\n`change NGINX world from metrics to insight`\n\nThe first goal of `Mio` is to provide powerful API statistics and summary for NGINX.\n\nMetrics is just base, the final goal is automatic improve the user's NGINX system with the power of data.\n\n## Dashborad screenshot\n![dashborad](/docs/screenshot.png)\n\n## Installation \u0026 run\n\n[install](https://openresty.org/en/installation.html) The **latest** OpenResty version.\n\nIf  your OpenResty version above 1.11.2.1, pelase use `develop` branch instead of `master` branch. Because OpenResty added the optional \"init\" argument for `shdict:incr()` in 1.11.2.1, which can reduce a lot of `if` conditions and improve performance.\n\nPlease remember add `--with-http_stub_status_module` configuration parameter when run `./configure`.\n\nBy default, OpenResty is installed into the prefix `/usr/local/openresty/`.\n\n------\n\ndownload Mio to your application directories, then run like this:\n```\nsudo openresty -p /opt/my-fancy-app/\n```\n\nIf you build OpenResty from source code, maybe you can not find `openresty`,which is symbolic link to OpenResty's nginx executable file, /usr/local/openresty/nginx/sbin/nginx. So you can run like this:\n```\nsudo /usr/local/openresty/nginx/sbin/nginx -p /opt/my-fancy-app/\n```\n\n------\n\nyou can test Mio like this:\n\n+ The port `80` is designed for your own API.\n\n```\ncurl -i http://127.0.0.1/\n```\n\n\u003e hello! this is Mio.\n\n+ The port `9090` is designed for Mio's statistics and summary API.\n\n```\ncurl -i http://127.0.0.1:9090/summary\n```\n\n\u003e {\"\\/hello\":{\"total\":1,\"4xx\":1,\"sent\":314,\"request_time\":0}}\n\n\n```\ncurl -i http://127.0.0.1:9090/status\n```\n\n\u003e {\"load_timestamp\":1470384389,\"requests\":{\"current\":0,\"total\":2,\"success\":1},\"worker_count\":2,\"address\":\"127.0.0.1:80\",\"ngx_lua_version\":\"0.10.5\",\"server_zones\":[],\"nginx_version\":\"1.9.15\",\"connections\":{\"active\":1,\"writing\":1,\"current\":1,\"idle\":0,\"reading\":0},\"timestamp\":1470384409,\"generation\":0,\"upstreams\":[]}\n\n+ The port `8080` is designed for Mio's dashboard.\n\nOpen your browser with `http://127.0.0.1:8080`, you will you'll see a monitor page similar to NGINX plus. And this monitor page is preview version, we are working for it.\n\n------\nCongratulations,`Mio` is running!\n\nIf you run failed, please create a new issue, I will fix it ASAP.\n\n## TODO list\n\n- [ ] use shared dict incr() method  \n- [ ] add beautiful UI\n\n## API Compatibility\n\nThe `/status` and `/summary` APIs are 100%  compatible with NGINX Plus.\n\n### /status\n\n```\ncurl http://127.0.0.1/status\n```\n\nNGINX Plus 的统计模块数据格式和说明文档在[这里](http://nginx.org/en/docs/http/ngx_http_status_module.html)。NGINX Plus 的json 大块数据为：\n\n```\n{\n    \"version\": 6,\n    \"nginx_version\": \"1.9.13\",\n    \"address\": \"206.251.255.64\",\n    \"generation\": 21,\n    \"load_timestamp\": 1462615200247,\n    \"timestamp\": 1462870443024,\n    \"pid\": 24978,\n    \"processes\": {},\n    \"connections\": {},\n    \"ssl\": {},\n    \"requests\": {},\n    \"server_zones\": {},\n    \"upstreams\": {},\n    \"caches\": {},\n    \"stream\": {}\n}\n```\n\n**注意下面数据的缩进，缩进代表json数据的组织**。\n\n比如\n\n\u003e - server_zones\n    - hg.nginx.org\n        - processing\n    - trac.nginx.org\n        - responses\n            - 1xx\n\n代表的json格式为：\n\n```\n\"server_zones\":{\n    \"processing\":0,\n    \"requests\":71639,\n    \"responses\":{\n    \t\"1xx\":0,\n    \t\"2xx\":66973,\n    \t\"3xx\":3289,\n    \t\"4xx\":941,\n    \t\"5xx\":264,\n    \t\"total\":71467\n    },\n    \"discarded\":172,\n    \"received\":21575699,\n    \"sent\":2652969417\n},\n```\n\n- version\n\n    json格式数据集合的版本号，现在为1。为了兼容性设计\n\n- nginx_version\n\n    NGINX 版本号\n\n- ngx_lua_version\n\n    nginx lua 版本号\n\n- address\n\n   接收 status 请求的服务器地址\n\n- generation\n\n   NGINX 重新加载的次数。不是stop-start的模式，而是reload\n\n- start_timestamp\n\n    NGINX 上次 reload 时的时间戳（ms）\n\n- timestamp\n\n    当前时间戳（ms）。timestamp 和 start_timestamp 之间的差值，就是NGINX 的 uptime\n\n- worker_count\n\n    NGINX worker数\n\n- connections\n\n    \u003e lua 模块获取不到，通过[这个c模块](http://nginx.org/en/docs/http/ngx_http_stub_status_module.html)获取\n\n    - accepted\n\n        曾经接收到的所有终端连接总数（TODO：暂时获取不到）\n    - dropped\n\n        drop 掉的所有终端连接总数（TODO：暂时获取不到）\n    - current\n\n        当前所有连接数，包括读、写和空闲\n    - active\n\n        当前活跃的终端连接数,不包括空闲连接数\n    - idle\n\n        当前空闲的终端连接数。**avtive 和 idle 的和，就是 Current**。\n    - writing\n\n        当前 NGINX 正在 write response 给终端的连接数\n\n    - reading\n\n        当前 NGINX 正在 read 终端请求头的连接数\n- requests\n    - total\n\n        NGINX 处理的终端请求总数。自从上一次 stop-start 开始计数，reload 不会影响这个数字。\n\n    - qps\n\n        每秒请求数。\n\n    - success\n\n        NGINX 处理成功的请求总数。内部是通过http应答码小于400来判断的。\n\n    - current\n\n        正在处理的终端请求数(TODO:意义不大，先不做实现)\n\n\n- server_zones\n  - server_zone(这个是 **用户自定义** 的字符串，不是关键字)\n    - processing(TODO: 需要 access 阶段配合，稍后完成)\n\n      (The number of client requests that are currently being processed.)\n\n    - requests\n\n      (The total number of client requests received from clients.)\n\n    - discarded\n\n      (The total number of requests completed without sending a response.)\n\n    - received\n\n      (The total number of bytes received from clients.)\n\n    - receive_per_second\n\n        每秒接收到的数据大小，单位是 kb。两次received的差值除以秒数\n\n    - sent\n\n      (The total number of bytes sent to clients.)\n\n    - send_per_second\n\n        每秒发送的数据大小，单位是 kb。两次sent的差值除以秒数\n\n    - responses\n      - total  \n        The total number of responses sent to clients.\n      - 1xx, 2xx, 3xx, 4xx, 5xx  \n        The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.\n\n- upstreams\n    - upstream_name(这个是 **用户自定义** 的字符串，不是关键字)\n        - peers\n            - id\n\n                server 的 ID\n            - server\n\n                server 的 IP:port\n            - backup\n\n                布尔值。标记是否为 backup server\n            - weight\n\n                这个 server 的权重\n            - state（TODO：逻辑比较复杂，稍后完成）\n\n                当前健康状态。值为 “up”, “draining”, “down”, “unavail”,  “unhealthy” 中的一个\n\n            - active\n\n                当前活跃连接数\n            - max_conns （TODO：暂时获取不到）\n\n                这个 server 的最大连接数限制\n            - requests\n\n                经过这个 server 的所有终端请求总数\n\n            - qps\n\n                每秒请求数\n\n            - response\n                - total\n\n                    这个 server 返回响应的总数\n                - 1xx, 2xx, 3xx, 4xx, 5xx\n\n                    每个 response 状态码的总数\n            - sent\n\n                发送给这个 server 的字节总数。\n\n            - send_per_second\n\n                通过 sent 两次的差值计算出每秒的速率并显示\n\n            - received\n\n                这个 server 接收到的字节总数。\n\n            - receive_per_second\n\n                通过 received 两次的差值计算出每秒的速率并显示\n\n            - fails\n                尝试和这个 server 通信，没有成功的总次数\n\n            - unavail\n\n                这个 server 变为『unavail』状态的次数。变为unavail是因为 fails 超过了 [max_fails](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#max_fails) 定义的阈值\n            - health_checks( TODO：整个这一项都拿不到，NGINX 没有暴露出来)\n                - checks\n\n                    已经发送的[health check](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#health_check) 的次数\n                - fails\n\n                    健康检查失败的次数\n                - unhealthy\n\n                    这个 server 变为 『unhealthy』状态的次数\n                - last_passed\n\n                    布尔值。上一次健康检查是否成功，并且通过了[match测试](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#match)\n\n            - latency\n                - mean\n\n                    server 总的平均响应时间，单位是 ms\n                - per_minute_mean\n\n                    1分钟内的平均响应时间，单位是 ms\n                - per_minute_min\n\n                    1分钟内的最小响应时间，单位是 ms\n                - per_minute_max\n\n                    1分钟内的最大响应时间，单位是 ms\n\n### /summary\n出于性能考虑，summary 的统计数据会先放在 lru cache 中，由 timer 定时同步到 shared dict 中。\nsummary 接口的返回值格式为 json，示例：\n\n```\nday:{\n    \"/hello\":{\n        \"total\":123, -- 接口访问总数\n        \"avg_time\":0.008, -- 平均返回时间\n        \"avg_size\":10, -- 返回值的平均 body 大小\n        \"1xx\":0,\n        \"2xx\":100982,\n        \"3xx\":0,\n        \"4xx\":222,\n        \"5xx\":112\n    },\n    \"/status\":{}\n}\n```\n\n- 当天的 summary 获取：curl http://127.0.0.1/summary\n- 昨天和前天的历史 summary 获取：curl http://127.0.0.1/summary_history\n- 最近一分钟的 summary 获取：curl http://127.0.0.1/summary_one_minute\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firesty%2FMio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firesty%2FMio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firesty%2FMio/lists"}