Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom health parameters check #39

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ $ echo $?
0
```

### Custom values check

_Since v0.6.0_

In case of the use of a self-rendered status page, it also can become necessary to check for custom parameters. It is possible to define
custom parameters using`FCGI_HEALTH_PARAMS` env var. Multiple parameters can be set and separated by commas.

```console
$ FCGI_HEALTH_PARAMS=custom-param-1,custom-param-2 php-fpm-healthcheck -v --custom-param-1=100 --custom-param-2=10
Trying to connect to php-fpm via: localhost:9000/custom-status-path
...
$ echo $?
0
```

## Kubernetes example

More and more people are looking for health checks on kubernetes for php-fpm, here is an example of livenessProbe and readinessProbe:
Expand Down
30 changes: 23 additions & 7 deletions php-fpm-healthcheck
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,36 @@ check_fpm_health() {
done
}

if ! GETOPT=$(getopt -o v --long verbose,accepted-conn:,listen-queue:,max-listen-queue:,listen-queue-len:,idle-processes:,active-processes:,total-processes:,max-active-processes:,max-children-reached:,slow-requests: -n 'php-fpm-healthcheck' -- "$@"); then
>&2 echo "Invalid options, terminating." ; exit 3
fi;

eval set -- "$GETOPT"

# FastCGI variables
FCGI_CONNECT_DEFAULT="localhost:9000"
FCGI_STATUS_PATH_DEFAULT="/status"
FCGI_HEALTH_PARAMS_DEFAULT=accepted-conn,listen-queue,max-listen-queue,listen-queue-len,idle-processes,active-processes,total-processes,max-active-processes,max-children-reached,slow-requests,
SCRIPT_FLAGS=verbose

FCGI_CONNECT="${FCGI_CONNECT:-$FCGI_CONNECT_DEFAULT}"

export REQUEST_METHOD="GET"
export SCRIPT_NAME="${FCGI_STATUS_PATH:-$FCGI_STATUS_PATH_DEFAULT}"
export SCRIPT_FILENAME="${FCGI_STATUS_PATH:-$FCGI_STATUS_PATH_DEFAULT}"
FCGI_CONNECT="${FCGI_CONNECT:-$FCGI_CONNECT_DEFAULT}"

# Expand script parameters
GETOPT_LIST="$FCGI_HEALTH_PARAMS_DEFAULT"
if ! test -z ${FCGI_HEALTH_PARAMS+x}; then
GETOPT_LIST="$GETOPT_LIST,$FCGI_HEALTH_PARAMS,"
fi;

# Sanitize optional values and add option-name divisor
GETOPT_LIST=$(echo "$GETOPT_LIST" | sed 's/ //g' | sed 's/,,/,/g')
GETOPT_LIST=$(echo "$GETOPT_LIST" | sed 's/,/:,/g')

GETOPT_LIST="$GETOPT_LIST,$SCRIPT_FLAGS"
GETOPT_LIST=$(echo "$GETOPT_LIST" | sed 's/ //g' | sed 's/,,/,/g')

if ! GETOPT=$(getopt -o v --long "$GETOPT_LIST" -n 'php-fpm-healthcheck' -- "$@"); then
>&2 echo "Invalid options, terminating." ; exit 3
fi;

eval set -- "$GETOPT"

VERBOSE=0

Expand Down
68 changes: 53 additions & 15 deletions test/testinfra/test_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,82 @@ def test_valid_with_empty_value_exits_properly(host):
assert cmd.rc == 3
assert "option value must be an integer" in cmd.stderr

@pytest.mark.php_fpm
def test_valid_custom_option_with_empty_value_exits_properly(host):
cmd = host.run("FCGI_HEALTH_PARAMS=custom-param php-fpm-healthcheck --verbose --custom-param=")
assert cmd.rc == 3
assert "option value must be an integer" in cmd.stderr

@pytest.mark.php_fpm
def test_valid_with_non_integer_value_exits_properly(host):
cmd = host.run("php-fpm-healthcheck --listen-queue-len=abc")
assert cmd.rc == 3
assert "option value must be an integer" in cmd.stderr

@pytest.mark.php_fpm
def test_all_available_options_at_once(host):
def test_valid_custom_option_non_integer_value_exits_properly(host):
cmd = host.run("FCGI_HEALTH_PARAMS=custom-param php-fpm-healthcheck --verbose --custom-param=abc")
assert cmd.rc == 3
assert "option value must be an integer" in cmd.stderr

@pytest.mark.php_fpm
def test_all_default_options_at_once(host):
cmd = host.run("php-fpm-healthcheck --accepted-conn=1000 --listen-queue=1000 --max-listen-queue=1000 "
"--listen-queue-len=1000 --idle-processes=1000 --active-processes=1000 --total-processes=1000 "
"--max-active-processes=1000 --max-children-reached=1000 --slow-requests=1000")
assert cmd.rc == 0
assert cmd.rc == 0

@pytest.mark.php_fpm
@pytest.mark.parametrize("option", [
"--accepted-conn",
"--listen-queue",
"--max-listen-queue",
"--idle-processes",
"--active-processes",
"--total-processes",
"--max-active-processes",
"--max-children-reached",
"--slow-requests",
"accepted-conn",
"listen-queue",
"max-listen-queue",
"idle-processes",
"active-processes",
"total-processes",
"max-active-processes",
"max-children-reached",
"slow-requests",
])
def test_all_available_options(host, option):
cmd = host.run("php-fpm-healthcheck --verbose {0}=1000".format(option))
def test_all_default_options(host, option):
cmd = host.run("php-fpm-healthcheck --verbose --{0}=1000".format(option))
assert cmd.rc == 0
assert "value" in cmd.stdout
assert "and expected is less than '1000'" in cmd.stdout

@pytest.mark.php_fpm
@pytest.mark.parametrize("option", [
"accepted-conn",
"listen-queue",
"max-listen-queue",
"idle-processes",
"active-processes",
"total-processes",
"max-active-processes",
"max-children-reached",
"slow-requests",
])
def test_all_default_options_on_custom_list(host, option):
cmd = host.run("FCGI_HEALTH_PARAMS={0} php-fpm-healthcheck --verbose --{0}=1000".format(option, option))
assert cmd.rc == 0
assert "value" in cmd.stdout
assert "and expected is less than '1000'" in cmd.stdout

# @pytest.mark.php_fpm
# def test_custom_option(host):
# This test should be only included when possible to use custom status page
# cmd = host.run("FCGI_HEALTH_PARAMS=custom-param php-fpm-healthcheck --verbose --custom-param=1000")
# assert cmd.rc == 0
# assert "value" in cmd.stdout
# assert "and expected is less than '1000'" in cmd.stdout

@pytest.mark.alpine
def test_missing_fcgi_apk(host):
host.run("apk del fcgi")
cmd = host.run("php-fpm-healthcheck")
assert cmd.rc == 4
assert "Make sure fcgi is installed" in cmd.stderr

# Fail safe for other tests, maybe we could use a docker fixture
# to start a new container everytime
host.run("apk add --no-cache fcgi")
Expand All @@ -62,7 +100,7 @@ def test_missing_fcgi_apt(host):
cmd = host.run("php-fpm-healthcheck")
assert cmd.rc == 4
assert "Make sure fcgi is installed" in cmd.stderr

# Fail safe for other tests, maybe we could use a docker fixture
# to start a new container everytime
host.run("apt-get install -y libfcgi-bin")
9 changes: 9 additions & 0 deletions test/testinfra/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,12 @@ def test_listen_queue_len_and_listen_queue_vars_are_parsed_correctly(host):
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "'listen queue' value '0' and expected is less than '5" in cmd.stdout
assert "'max listen queue' value '0' and expected is less than '1024'" in cmd.stdout

# @pytest.mark.php_fpm
# def test_multiple_custom_option_are_parsed_correctly(host):
# This test should be only included when possible to use custom status page
# cmd = host.run("FCGI_HEALTH_PARAMS=custom-param-one,custom-param-two php-fpm-healthcheck "
# "--verbose --custom-param-one=5 --custom-param-two=1024")
# assert "Trying to connect to php-fpm via:" in cmd.stdout
# assert "'custom param one' value '0' and expected is less than '5" in cmd.stdout
# assert "'custom param two' value '0' and expected is less than '1024'" in cmd.stdout