Services
banshee/services-collection/services/nginx/https/
stub-status
The connections, requests per second and dropped connections of an nginx server, from its stub_status page.
by banshee1 installation1 version
Published on October 27, 2026. First version.
// An nginx server, by its stub_status page over HTTP: the connections open, reading, writing and waiting, the
// requests per second, and the connections nginx accepted but could not handle (worker_connections reached).
// The page answers, in plain text:
// Active connections: 291
// server accepts handled requests
// 16630948 16630948 31070465
// Reading: 6 Writing: 179 Waiting: 106
need('protocol:http');
$user = need('protocol:http:user', 'optional');
$password = need('protocol:http:password', 'optional');
$url = variable('nginx:url', 'text', array(
'label' => 'Status page address',
'help' => 'The address of the stub_status page, http:// or https://, for instance https://www.example/nginx_status.',
));
output('connections', 'number', array('label' => 'Active connections'));
output('reading', 'number', array('label' => 'Connections reading a request'));
output('writing', 'number', array('label' => 'Connections writing a response'));
output('waiting', 'number', array('label' => 'Idle connections waiting'));
output('requests', 'number', array('label' => 'Requests', 'unit' => 'requests/s'));
output('dropped', 'number', array('label' => 'Connections dropped since start'));
watch.increase('dropped', 'Connections dropped', 'dropped', array('warning' => 0, 'window' => '1 h'));
watch.above('busy', 'Many active connections', 'connections', array('enabled' => false));
watch.habit('requests-unusual', 'Unusual request rate', 'requests', array('enabled' => false));
// A server that refuses the connection, or does not answer in time, is down: critical.
$answer = http.get($url, user=$user, password=$password, errors=$err);
if ($err['code'] == 'connection_refused' || $err['code'] == 'timeout') {
fail('critical', 'nginx down', $err['text']);
}
if ($err['code'] != '') {
fail('unreachable', 'nginx unreachable', $err['text']);
}
if ($answer['status'] == 401 || $answer['status'] == 403 || $answer['status'] == 404) {
fail('misconfigured', 'nginx refuses the status page, code ' . $answer['status'],
'See the stub_status location and its allow lines in the documentation.');
}
if ($answer['status'] != 200) {
fail('unreachable', 'nginx answers the status page with code ' . $answer['status']);
}
$active = text.match($answer['body'], 'Active connections: *([0-9]+)');
$counts = text.match($answer['body'], '\n *([0-9]+) +([0-9]+) +([0-9]+)');
$states = text.match($answer['body'], 'Reading: *([0-9]+) +Writing: *([0-9]+) +Waiting: *([0-9]+)');
if (list.count($active) == 0 || list.count($counts) == 0 || list.count($states) == 0) {
fail('misconfigured', 'The address does not serve an nginx stub_status page', $url);
}
// The requests per second, from the counter of this run and the previous one: none at the first run.
$requests = counter.rate('requests', $counts[3]);
if ($requests == '') {
skip('First reading: the request rate comes at the next run');
}
value('connections', $active[1]);
value('reading', $states[1]);
value('writing', $states[2]);
value('waiting', $states[3]);
value('requests', number.round($requests, 2));
// accepts minus handled: the connections nginx closed at once, out of worker_connections.
value('dropped', $counts[1] - $counts[2]);