{"id":15020839,"url":"https://github.com/zigzagak/ngx_dynamic_healthcheck","last_synced_at":"2026-03-11T16:03:32.754Z","repository":{"id":148036405,"uuid":"148533582","full_name":"ZigzagAK/ngx_dynamic_healthcheck","owner":"ZigzagAK","description":"Nginx upstream healthcheck module","archived":false,"fork":false,"pushed_at":"2025-01-16T15:02:12.000Z","size":163,"stargazers_count":20,"open_issues_count":3,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-31T18:56:52.742Z","etag":null,"topics":["health","healthcheck","nginx","nginx-health","nginx-healthcheck","nginx-upstream-health-check","nginx-upstream-healthcheck","upstream","upstream-check","upstream-healchcheck","upstream-health"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ZigzagAK.png","metadata":{"files":{"readme":"README.markdown","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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-12T19:49:26.000Z","updated_at":"2025-01-23T11:09:06.000Z","dependencies_parsed_at":"2023-05-28T06:45:18.667Z","dependency_job_id":"e24bc8b3-3223-472d-97d2-44ce52f1c83f","html_url":"https://github.com/ZigzagAK/ngx_dynamic_healthcheck","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZigzagAK%2Fngx_dynamic_healthcheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZigzagAK%2Fngx_dynamic_healthcheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZigzagAK%2Fngx_dynamic_healthcheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZigzagAK%2Fngx_dynamic_healthcheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZigzagAK","download_url":"https://codeload.github.com/ZigzagAK/ngx_dynamic_healthcheck/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238319466,"owners_count":19452342,"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":["health","healthcheck","nginx","nginx-health","nginx-healthcheck","nginx-upstream-health-check","nginx-upstream-healthcheck","upstream","upstream-check","upstream-healchcheck","upstream-health"],"created_at":"2024-09-24T19:55:45.304Z","updated_at":"2025-10-26T11:31:24.796Z","avatar_url":"https://github.com/ZigzagAK.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"Name\n====\n\nngx-dynamic-healthcheck - Nginx upstreams healthchecks.\n\nModule requires [zone](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#zone) upstream directive.\n\n* support http, tcp, ssl checks.\n* support dynamic reconfiguration\n* support persistance of healthcheck parameters\n* optionally support LUA API for reconfiguration\n* with [dynamic-upstream-module](https://github.com/ZigzagAK/ngx_dynamic_upstream) automaticaly cover by healthchecks new added peers (with DNS balancing).\n* TCP checks with requrest/response (for Redis for example)\n* pattern matching\n* disabling hosts\n\nThis module supports http and stream upstream types.\n\nBuild status\n======\n[![Build Status](https://travis-ci.org/ZigzagAK/ngx_dynamic_healthcheck.svg?branch=master)](https://travis-ci.org/ZigzagAK/ngx_dynamic_healthcheck)\n\nTable of Contents\n=================\n\n* [Name](#name)\n* [Status](#status)\n* [Description](#description)\n* [Install](#install)\n* [Synopsis](#synopsis)\n* [Configuration directives](#configuration-directives)\n    * [Individual upstream parameters](#individual_upstream_parameters)\n        - [check](#check)\n        - [check_request_uri](#check_request_uri)\n        - [check_request_headers](#check_request_headers)\n        - [check_request_body](#check_request_body)\n        - [check_response_codes](#check_response_codes)\n        - [check_response_body](#check_response_body)\n        - [check_persistent](#check_persistent)\n        - [check_disable_host](#check_disable_host)\n        - [check_exclude_host](#check_exclude_host)\n    * [Global healthcheck parameters](#global_healthcheck_parameters)\n        - [healthcheck](#healthcheck)\n        - [healthcheck_request_uri](#healthcheck_request_uri)\n        - [healthcheck_request_headers](#healthcheck_request_headers)\n        - [healthcheck_request_body](#healthcheck_request_body)\n        - [healthcheck_response_codes](#chealthheck_response_codes)\n        - [healthcheck_response_body](#chealthheck_response_body)\n        - [healthcheck_persistent](#healthcheck_persistent)\n        - [healthcheck_disable_host](#healthcheck_disable_host)\n    * [Reconfiguration API](#reconfiguration_api)\n        - [get](#healthcheck_get)\n        - [status](#healthcheck_status)\n        - [update](#healthcheck_update)\n* [LUA API](#lua)\n    * [get](#lua_get)\n    * [update](#lua_update)\n    * [disable](#lua_disable)\n    * [disable_host](#lua_disable_host)\n    * [status](#lua_status)\n\nStatus\n====\n\nThis module is production ready.\n\nDescription\n=======\n\nThis module provides dynamicaly configurable healthchecks.\n\n[Back to TOC](#table-of-contents)\n\nInstall\n====\n\nBuild nginx.\nAll dependencies are downloaded automaticaly.\n\n```\ngit clone git@github.com:ZigzagAK/ngx_dynamic_healthchecks.git\ncd ngx_dynamic_healthchecks\n./build.sh\n```\n\nArchive will be placed in the `install` folder after successful build.\n\n[Back to TOC](#table-of-contents)\n\nSynopsis\n=====\n\n```\nhttp {\n  healthcheck fall=2 rise=2 interval=60 timeout=10000 type=tcp;\n  healthcheck_persistent healthcheck;\n\n  healthcheck_disable_host balancer01.domain.net:9000;\n  healthcheck_disable_host balancer02.domain.net:9000;\n\n  server {\n    listen 8888;\n    location = /healthcheck/get {\n        healthcheck_get;\n    }\n    location = /healthcheck/status {\n        healthcheck_status;\n    }\n    location = /healthcheck/update {\n        healthcheck_update;\n    }\n  }\n\n  upstream mail {\n      zone mail 128k;\n\n      # https://github.com/ZigzagAK/ngx_dynamic_upstream ver \u003e= 2.X.X\n      dns_update 10s;\n      dns_ipv6 off;\n\n      server mail.ru:443 down;\n\n      check fall=2 rise=2 interval=10 timeout=10000 type=ssl;\n  }\n\n  upstream google {\n      zone google 128k;\n\n      # https://github.com/ZigzagAK/ngx_dynamic_upstream ver \u003e= 2.X.X\n      dns_update 10s;\n      dns_ipv6 off;\n\n      server mail.ru down;\n\n      check fall=2 rise=2 interval=10 timeout=10000 type=tcp;\n  }\n\n  upstream test {\n      zone test 128k;\n\n      # https://github.com/ZigzagAK/ngx_dynamic_upstream ver \u003e= 2.X.X\n      dns_update 10s;\n      dns_ipv6 off;\n\n      server balancer.domain.net:9000 down;\n\n      check fall=2 rise=2 interval=10 timeout=10000 type=http;\n      check_request_uri GET /health;\n      check_request_body ping;\n      check_response_body .*;\n      check_request_headers a=1 b=2;\n      check_response_codes 200 204;\n  }\n}\n\nstream {\n    upstream redis-ro {\n      zone shm_redis-ro 128k;\n\n      server 127.0.0.1:6379 down;\n      server 127.0.0.2:6379 down;\n      server 127.0.1.1:6379 down;\n      server 127.0.1.2:6379 down;\n\n      check fall=1 rise=2 timeout=10000 interval=10;\n\n      check_request_body \"multi\\r\\ninfo replication\\r\\nget x\\r\\nexec\\r\\nquit\\r\\n\";\n      check_response_body \"(\\+OK).*(\\+QUEUED).*(\\+QUEUED).*(role:slave).*(master_link_status:up).*(master_sync_in_progress:0).*(check).*(\\+OK)\";\n    }\n\n    upstream redis-rw {\n      zone shm_redis-rw 128k;\n\n      server 127.0.0.1:6379 down;\n      server 127.0.0.2:6379 down;\n      server 127.0.1.1:6379 down;\n      server 127.0.1.2:6379 down;\n\n      check fall=1 rise=2 timeout=10000 interval=10;\n\n      check_request_body \"multi\\r\\ninfo replication\\r\\nset x check\\r\\nget x\\r\\nexec\\r\\nquit\\r\\n\";\n      check_response_body \"(\\+OK).*(\\+QUEUED).*(\\+QUEUED).*(\\+QUEUED).*(role:master).*(\\+OK).*(check).*(\\+OK)\";\n    }\n}\n```\n[Back to TOC](#table-of-contents)\n\n\nConfiguration directives\n===============\nGlobal healthcheck parameters may be used in case when you want to cover all upstreams with same healthchecks.\nEvery parameter may be redefined on `upstream` level.\n\nIndividual upstream parameters\n--------------------------\n\ncheck\n-----\n* **syntax**: `check fall=2 rise=2 timeout=1000 interval=10 keepalive=10 type=http|tcp|ssl port=\u003cother check port\u003e \u003cpassive\u003e`\n* **default**: `none`\n* **context**: `upstream`\n\nConfigure healthcheck base parameters.\nIf `interval` is 0 - no healthcheks for this upstream.  \nIf you want change default port (got from upstream peer) you may override it with `port=xxx` parameter.  \nFor example: Your service is responsible on port A and working by TCP binary protocol and you have another port opened by HTTP and returns healthcheck status.\nIn this case you may override peer port with separate HTTP port and setup check_request_uri and check_response_codes, check_response_body parameters.\nPeer port in this case will not be check because healthcheck may be accessed on separate HTTP port.  \n  \n`passive` parameter may be used to minimze HTTP checks. In this mode active checks are not applied when success (status \u003c 300) responses are received from upstream peer.  \n\n\ncheck_request_uri\n-----------------\n* **syntax**: `check_request_uri GET|POST /ping`\n* **default**: `none`\n* **context**: `upstream`\n\nConfigure http request for healthcheck.\n\ncheck_request_headers\n-------------------\n* **syntax**: `check_request_headers a=1 b=2`\n* **default**: `none`\n* **context**: `upstream`\n\nConfigure http request headers for healthcheck.\n\ncheck_request_body\n-----------------\n* **syntax**: `check_request_body hello`\n* **default**: `none`\n* **context**: `upstream`\n\nConfigure http request body for healthcheck.\n\ncheck_response_codes\n-------------------\n* **syntax**: `check_response_codes 200 201 202`\n* **default**: `none`\n* **context**: `upstream`\n\nConfigure http response codes for healthcheck.\n\ncheck_response_body\n-------------------\n* **syntax**: `check_response_body .*`\n* **default**: `none`\n* **context**: `upstream`\n\nConfigure regular expression for http response body.\n\n[Back to TOC](#table-of-contents)\n\ncheck_persistent\n--------------\n* **syntax**: `check_persistent \u003cfolder\u003e/off`\n* **default**: `off`\n* **context**: `upstream`\n\nConfigure persistance for healthcheck parameters.\n\nParameters a stored in plain text files and may be changed online in any time without reloads.\nSaved parameters have higher priority than configuration parameters. They are redefine them.\n\nTo disable persistace for specific upstream you may write `check_persistent off`.\n\n[Back to TOC](#table-of-contents)\n\ncheck_disable_host\n----------------\n* **syntax**: `check_disable_host 1.1.1.1:3456`\n* **default**: `none`\n* **context**: `upstream`\n\nDisable specific host or peer in upstream (may be changed via persistance).\n\n[Back to TOC](#table-of-contents)\n\ncheck_exclude_host\n----------------\n* **syntax**: `check_exclude_host 1.1.1.1:3456`\n* **default**: `none`\n* **context**: `upstream`\n\nExclude specific host or peer in upstream from healthcheck.\n\n[Back to TOC](#table-of-contents)\n\nGlobal healthcheck parameters\n--------------------------\n\nhealthcheck\n----------\n* **syntax**: `healthcheck fall=2 rise=2 timeout=1000 interval=10 keepalive=10 type=http|tcp|ssl`\n* **default**: `none`\n* **context**: `http`\n\nConfigure healthcheck base parameters globally.\n\nhealthcheck_request_uri\n--------------------\n* **syntax**: `healthcheck_request_uri GET|POST /ping`\n* **default**: `none`\n* **context**: `http`\n\nConfigure http request for healthcheck globally.\n\nhealthcheck_request_headers\n------------------------\n* **syntax**: `healthcheck_request_headers a=1 b=2`\n* **default**: `none`\n* **context**: `http`\n\nConfigure http request headers for healthcheck globally.\n\nhealthcheck_request_body\n----------------------\n* **syntax**: `healthcheck_request_body hello`\n* **default**: `none`\n* **context**: `http`\n\nConfigure http request body for healthcheck globally.\n\nhealthcheck_response_codes\n------------------------\n* **syntax**: `healthcheck_response_codes 200 201 202`\n* **default**: `none`\n* **context**: `http`\n\nConfigure http response codes for healthcheck globally.\n\nhealthcheck_response_body\n-----------------------\n* **syntax**: `healthcheck_response_body .*`\n* **default**: `none`\n* **context**: `http`\n\nConfigure regular expression for http response body globally.\n\n[Back to TOC](#table-of-contents)\n\nhealthcheck_persistent\n-------------------\n* **syntax**: `healthcheck_persistent \u003cfolder\u003e/off`\n* **default**: `off`\n* **context**: `http`\n\nConfigure persistance for healthcheck parameters globally.\n\nParameters a stored in plain text files and may be changed online in any time without reloads.\nSaved parameters have higher priority than configuration parameters. They are redefine them.\n\n[Back to TOC](#table-of-contents)\n\nhealthcheck_disable_host\n---------------------\n* **syntax**: `healthcheck_disable_host 1.1.1.1:4567`\n* **default**: `none`\n* **context**: `upstream`\n\nDisable specific host or peer in upstream (may be changed via persistance) globally.\n\nhealthcheck_buffer_size\n--------------------\n* **syntax**: `healthcheck_buffer_size 32k`\n* **default**: `pagesize`\n* **context**: `http`\n\nSpecify buffer size for sending and parsing requests and responses.\n\n[Back to TOC](#table-of-contents)\n\nReconfiguration API\n============\n\nhealthcheck_get\n-------------\n* **syntax**: `healthcheck_get;`\n* **context**: `location`\n\nRegister get healthcheck information handler.\n\nExample output:\n`curl localhost:8888/healthcheck/get`\n```\n{\n    \"a\":{\n        \"rise\":1,\n        \"fall\":2,\n        \"interval\":10,\n        \"keepalive\":10,\n        \"timeout\":10000,\n        \"type\":\"http\",\n        \"command\":{\n            \"uri\":\"/health\",\n            \"method\":\"GET\",\n            \"headers\":{\"a\":\"1\",\"b\":\"2\"},\n            \"body\":\"ping\",\n            \"expected\":{\n                \"body\":\"pong\",\n                \"codes\":[200,204,201]\n            }\n        },\n        \"disabled\":0,\n        \"off\":0,\n        \"disabled_hosts\":[]\n    },\n    \"google\":{\n        \"rise\":2,\n        \"fall\":2,\n        \"interval\":10,\n        \"keepalive\":1,\n        \"timeout\":10000,\n        \"type\":\"http\",\n        \"command\":{\n            \"uri\":\"/\",\n            \"method\":\"GET\",\n            \"headers\":[],\n            \"request_body\":\"\",\n            \"expected\":{\n                \"body\":\"\",\n                \"codes\":[]\n            }\n        },\n        \"disabled\":0,\n        \"off\":0,\n        \"disabled_hosts\":[]\n    }\n}\n```\n\nArguments:\n\n- stream=\n- upstream=name\n\nOn default the handler returns information about all http upstreams. To get information about streams you may pass `stream=` argument to request.  \nTo get information about specific upstream you may mass `upstream=xxx` agrument.\n\n\n[Back to TOC](#table-of-contents)\n\nhealthcheck_status\n----------------\n* **syntax**: `healthcheck_status;`\n* **context**: `location`\n\nGet healthcheck online information.\n\nExample output:\n`curl localhost:8888/healthcheck/status`\n```\n{\n    \"a\":{\n        \"primary\":{\n            \"127.0.0.1:9000\":{\n                \"down\":1,\n                \"fall\":0,\n                \"rise\":0,\n                \"fall_total\":0,\n                \"rise_total\":0\n            },\n            \"127.0.1.1:9000\":{\n                \"down\":1,\n                \"fall\":0,\n                \"rise\":0,\n                \"fall_total\":0,\n                \"rise_total\":0\n            }\n        },\n        \"backup\":{\n            \"127.0.2.1:9000\":{\n                \"down\":1,\n                \"fall\":3,\n                \"rise\":0,\n                \"fall_total\":1,\n                \"rise_total\":0\n            }\n        }\n    },\n    \"google\":{\n        \"primary\":{\n            \"173.194.220.102:80\":{\n                \"down\":0,\n                \"fall\":0,\n                \"rise\":2,\n                \"fall_total\":0,\n                \"rise_total\":2\n            },\n            \"173.194.220.138:80\":{\n                \"down\":0,\n                \"fall\":0,\n                \"rise\":2,\n                \"fall_total\":0,\n                \"rise_total\":2\n            },\n            \"173.194.220.113:80\":{\n                \"down\":0,\n                \"fall\":0,\n                \"rise\":2,\n                \"fall_total\":0,\n                \"rise_total\":2\n            },\n            \"173.194.220.139:80\":{\n                \"down\":0,\n                \"fall\":0,\n                \"rise\":2,\n                \"fall_total\":0,\n                \"rise_total\":2\n            },\n            \"173.194.220.100:80\":{\n                \"down\":0,\n                \"fall\":0,\n                \"rise\":2,\n                \"fall_total\":0,\n                \"rise_total\":2\n            },\n            \"173.194.220.101:80\":{\n                \"down\":0,\n                \"fall\":0,\n                \"rise\":2,\n                \"fall_total\":0,\n                \"rise_total\":2\n            }\n        }\n    }\n}\n```\n\nArguments:\n\n- stream=\n- upstream=name\n\nOn default the handler returns information about all http upstreams. To get information about streams you may pass `stream=` argument to request.  \nTo get information about specific upstream you may mass `upstream=xxx` agrument.\n\nhealthcheck_update\n----------------\n* **syntax**: `healthcheck_update;`\n* **context**: `location`\n\nArguments:\n\n```\n- stream=\n- upstream=xxx\n- type=http|tcp|ssl\n- fall=N\n- rise=N\n- timeout=ms\n- interval=sec\n- keepalive=N\n- request_uri=URI\n- request_method=GET|POST|....\n- request_headers=h1:v1|h2:v2|...\n- request_body=BODY\n- response_codes=200|201|...\n- response_body=REGEXP\n- off=1|0\n- disable_host=XXX.XXX.XXX.XXX:PORT\n- enable_host=XXX.XXX.XXX.XXX:PORT\n- disable=1|0\n\n```\n**upstream** is mandatory for all updates (ex. disable/enable hosts).  \n**off** - enable/disable healthchecks for upstream.  \n**disable** - absolutely disable app peers in upstream.  \n**enable/disable host** may be used with upstream or not. When no upstream is defined peers disabling/enabling in all upstreams.  \n\n[Back to TOC](#table-of-contents)\n\nLUA API\n=====\n\nPackage `ngx.healthcheck` is used for manipulation http upstreams.\nPackage `ngx.healthcheck.stream` is used for manipulation stream upstreams.\n\nFunctionality of both packages is same.\n\n\nMethods\n=======\n\nlua_get\n------\n**syntax 1:** `healthcheck, error = hc.get(upstream)`  \n**syntax 2:** `healthcheck, error = hc.get()`  \n**context:** *\u0026#42;_by_lua\u0026#42;*  \n\nGet healthcheck parameters.\n\nReturns lua table on success, or error otherwise.\n\n[Back to TOC](#table-of-contents)\n\nlua_update\n---------\n**syntax:** `ok, error = hc.update(upstream, tab)`  \n**context:** *\u0026#42;_by_lua\u0026#42;*  \n\nUpdate healthcheck parameters.\n\nExample table:\n```\n{\n    \"rise\":1,\n    \"fall\":2,\n    \"interval\":10,\n    \"keepalive\":10,\n    \"timeout\":10000,\n    \"type\":\"http\",\n    \"command\":{\n        \"uri\":\"/health\",\n        \"method\":\"GET\",\n        \"headers\":{\"a\":\"1\",\"b\":\"2\"},\n        \"body\":\"ping\",\n        \"expected\":{\n            \"body\":\"1111\",\n            \"codes\":[200,204,201]\n        }\n    },\n    \"disabled\":0,\n    \"off\":0\n}\n```\n\n[Back to TOC](#table-of-contents).\n\nlua_disable_host\n-------------\n**syntax:** `ok, error = hc.disable_host(host, disabled=1|0, [upstream])`  \n**context:** *\u0026#42;_by_lua\u0026#42;*  \n\nDisable (permanent down) specific host in upstream (or in all upstreams).\n\nReturns `true` or throws the error.\n\n[Back to TOC](#table-of-contents).\n\nlua_disable\n---------\n**syntax:** `ok, error = hc.disable(upstream, disabled=1|0)`  \n**context:** *\u0026#42;_by_lua\u0026#42;*  \n\nDisable (permanent down) all hosts in upstream.\n\nReturns `true` or throws the error.\n\n[Back to TOC](#table-of-contents).\n\nlua_status\n---------\n**syntax:** `status, error = hc.status(upstream)`  \n**context:** *\u0026#42;_by_lua\u0026#42;*  \n\nReturns runlime healthcheck information about peers in upstream.\n\n[Back to TOC](#table-of-contents).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzigzagak%2Fngx_dynamic_healthcheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzigzagak%2Fngx_dynamic_healthcheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzigzagak%2Fngx_dynamic_healthcheck/lists"}