1 Star 0 Fork 0

流动de云 / ngx_healthcheck_module

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ngx_healthcheck_status.c 29.78 KB
AI 代码解读
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
/*
* Copyright (C) 2017- Changxun Zhou(changxunzhou@qq.com)
* desc: Healthcheck status interface
*/
#include <nginx.h>
#include <ngx_core.h>
#include <ngx_stream.h>
#include <ngx_http.h>
#include "common.h.in"
#define NGX_CHECK_STATUS_DOWN 0x0001
#define NGX_CHECK_STATUS_UP 0x0002
typedef void (*ngx_upstream_check_status_format_pt) (ngx_buf_t *b,
ngx_upstream_check_peers_t *peers,
ngx_uint_t flag);
typedef struct {
ngx_str_t format;
ngx_str_t content_type;
ngx_upstream_check_status_format_pt output;
} ngx_check_status_conf_t;
typedef struct {
ngx_check_status_conf_t *format;
ngx_flag_t flag;
} ngx_upstream_check_status_ctx_t;
typedef ngx_int_t (*ngx_upstream_check_status_command_pt)
(ngx_upstream_check_status_ctx_t *ctx, ngx_str_t *value);
typedef struct {
ngx_str_t name;
ngx_upstream_check_status_command_pt handler;
} ngx_check_status_command_t;
// check module main config data.
typedef struct {
ngx_uint_t check_shm_size;
ngx_upstream_check_peers_t *peers;
} ngx_upstream_check_main_conf_t;
typedef struct {
ngx_check_status_conf_t *format;
} ngx_upstream_check_loc_conf_t;
// external var declare
extern ngx_uint_t ngx_stream_upstream_check_shm_generation ; //reload counter
extern ngx_upstream_check_peers_t *stream_peers_ctx ; //stream peers data
extern ngx_upstream_check_peers_t *http_peers_ctx ; // http peers data
//begin check_status function declare
static ngx_int_t ngx_upstream_check_status_handler(
ngx_http_request_t *r);
static void ngx_upstream_check_status_parse_args(ngx_http_request_t *r,
ngx_upstream_check_status_ctx_t *ctx);
static ngx_int_t ngx_upstream_check_status_command_format(
ngx_upstream_check_status_ctx_t *ctx, ngx_str_t *value);
static ngx_int_t ngx_upstream_check_status_command_status(
ngx_upstream_check_status_ctx_t *ctx, ngx_str_t *value);
static void ngx_upstream_check_status_html_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag);
static void ngx_upstream_check_status_csv_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag);
static void ngx_upstream_check_status_json_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag);
static void ngx_http_upstream_check_status_prometheus_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag);
static ngx_check_status_conf_t *ngx_http_get_check_status_format_conf(
ngx_str_t *str);
static char *ngx_upstream_check_status(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
static void *ngx_upstream_check_create_loc_conf(ngx_conf_t *cf);
static char * ngx_upstream_check_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
//end check_status function declare
//1 cmd define
static ngx_command_t ngx_upstream_check_status_commands[] = {
{ ngx_string("healthcheck_status"),
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1|NGX_CONF_NOARGS,
ngx_upstream_check_status,
0,
0,
NULL },
ngx_null_command
};
//2 ctx define
static ngx_http_module_t ngx_upstream_check_status_module_ctx = {
NULL, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_upstream_check_create_loc_conf, /* create location configuration */
ngx_upstream_check_merge_loc_conf /* merge location configuration */
};
//3 module define
ngx_module_t ngx_upstream_check_status_module = {
NGX_MODULE_V1,
&ngx_upstream_check_status_module_ctx, /* module context */
ngx_upstream_check_status_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
//health checker cmd callback.
static char *
ngx_upstream_check_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_str_t *value;
ngx_http_core_loc_conf_t *clcf;
ngx_upstream_check_loc_conf_t *uclcf;
value = cf->args->elts;
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_upstream_check_status_handler;
if (cf->args->nelts == 2) {
uclcf = ngx_http_conf_get_module_loc_conf(cf,
ngx_upstream_check_status_module);
uclcf->format = ngx_http_get_check_status_format_conf(&value[1]);
if (uclcf->format == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid check format \"%V\"", &value[1]);
return NGX_CONF_ERROR;
}
}
return NGX_CONF_OK;
}
// location config callback
static void *
ngx_upstream_check_create_loc_conf(ngx_conf_t *cf)
{
ngx_upstream_check_loc_conf_t *uclcf;
uclcf = ngx_pcalloc(cf->pool, sizeof(ngx_upstream_check_loc_conf_t));
if (uclcf == NULL) {
return NULL;
}
uclcf->format = NGX_CONF_UNSET_PTR;
return uclcf;
}
static char *
ngx_upstream_check_merge_loc_conf(ngx_conf_t *cf, void *parent,
void *child)
{
ngx_str_t format = ngx_string("html");
ngx_upstream_check_loc_conf_t *prev = parent;
ngx_upstream_check_loc_conf_t *conf = child;
ngx_conf_merge_ptr_value(conf->format, prev->format,
ngx_http_get_check_status_format_conf(&format));
return NGX_CONF_OK;
}
static ngx_check_status_conf_t ngx_check_status_formats[] = {
{ ngx_string("html"),
ngx_string("text/html"),
ngx_upstream_check_status_html_format },
{ ngx_string("csv"),
ngx_string("text/plain"),
ngx_upstream_check_status_csv_format },
{ ngx_string("json"),
ngx_string("application/json"), // RFC 4627
ngx_upstream_check_status_json_format },
{ ngx_string("prometheus"),
ngx_string("text/plain"),
ngx_http_upstream_check_status_prometheus_format },
{ ngx_null_string, ngx_null_string, NULL }
};
static ngx_check_status_command_t ngx_check_status_commands[] = {
{ ngx_string("format"),
ngx_upstream_check_status_command_format },
{ ngx_string("status"),
ngx_upstream_check_status_command_status },
{ ngx_null_string, NULL }
};
/* http request handler. */
static ngx_int_t
ngx_upstream_check_status_handler(ngx_http_request_t *r)
{
size_t buffer_size;
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
ngx_upstream_check_peers_t *peers;
ngx_upstream_check_loc_conf_t *uclcf;
ngx_upstream_check_status_ctx_t *ctx;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"[ngx-healthcheck][status-interface] recv query request");
if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
return NGX_HTTP_NOT_ALLOWED;
}
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
return rc;
}
uclcf = ngx_http_get_module_loc_conf(r, ngx_upstream_check_status_module);
ctx = ngx_pcalloc(r->pool, sizeof(ngx_upstream_check_status_ctx_t));
if (ctx == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_upstream_check_status_parse_args(r, ctx);
if (ctx->format == NULL) {
ctx->format = uclcf->format;
}
r->headers_out.content_type = ctx->format->content_type;
if (r->method == NGX_HTTP_HEAD) {
r->headers_out.status = NGX_HTTP_OK;
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
}
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"[ngx-healthcheck][status-interface]"
" stream_peers_ctx:%p, http_peers_ctx:%p",
stream_peers_ctx, http_peers_ctx);
peers = http_peers_ctx;
/*
if (peers == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"[ngx-healthcheck][status-interface] peers == NULL");
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
*/
// 1/4 pagesize for each record
if(stream_peers_ctx == NULL){
buffer_size = http_peers_ctx->peers.nelts * ngx_pagesize / 4;
}else{
buffer_size = (stream_peers_ctx->peers.nelts + http_peers_ctx->peers.nelts) * ngx_pagesize / 4;
}
buffer_size = ngx_align(buffer_size, ngx_pagesize) + ngx_pagesize;
b = ngx_create_temp_buf(r->pool, buffer_size);
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
out.buf = b;
out.next = NULL;
ctx->format->output(b, peers, ctx->flag); // construct status data.
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = b->last - b->pos;
if (r->headers_out.content_length_n == 0) {
r->header_only = 1;
}
b->last_buf = 1;
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
return ngx_http_output_filter(r, &out);
}
static void
ngx_upstream_check_status_parse_args(ngx_http_request_t *r,
ngx_upstream_check_status_ctx_t *ctx)
{
ngx_str_t value;
ngx_uint_t i;
ngx_check_status_command_t *command;
if (r->args.len == 0) {
return;
}
for (i = 0; ; i++) {
command = &ngx_check_status_commands[i];
if (command->name.len == 0) {
break;
}
if (ngx_http_arg(r, command->name.data, command->name.len, &value)
== NGX_OK) {
if (command->handler(ctx, &value) != NGX_OK) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"stream upstream check, bad argument: \"%V\"",
&value);
}
}
}
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,
"stream upstream check, flag: \"%ui\"", ctx->flag);
}
static ngx_int_t
ngx_upstream_check_status_command_format(
ngx_upstream_check_status_ctx_t *ctx, ngx_str_t *value)
{
ctx->format = ngx_http_get_check_status_format_conf(value);
if (ctx->format == NULL) {
return NGX_ERROR;
}
return NGX_OK;
}
static ngx_int_t
ngx_upstream_check_status_command_status(
ngx_upstream_check_status_ctx_t *ctx, ngx_str_t *value)
{
if (value->len == (sizeof("down") - 1)
&& ngx_strncasecmp(value->data, (u_char *) "down", value->len) == 0) {
ctx->flag |= NGX_CHECK_STATUS_DOWN;
} else if (value->len == (sizeof("up") - 1)
&& ngx_strncasecmp(value->data, (u_char *) "up", value->len)
== 0) {
ctx->flag |= NGX_CHECK_STATUS_UP;
} else {
return NGX_ERROR;
}
return NGX_OK;
}
static void
ngx_upstream_check_status_html_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag)
{
ngx_uint_t i,stream_count,http_count,stream_up_count,http_up_count;
ngx_upstream_check_peer_t *peer;
stream_count = 0;
http_count = 0;
stream_up_count = 0;
http_up_count = 0;
peers = stream_peers_ctx;
if(peers != NULL){
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (!peer[i].shm->down) {
stream_up_count ++;
}
stream_count++;
}
}
peers = http_peers_ctx; //http
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (!peer[i].shm->down) {
http_up_count ++;
}
http_count++;
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\n"
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
"<head>\n"
" <title>Nginx upstream status checker</title>\n"
"</head>\n"
"<body>\n"
"<h1 align=\"center\">Nginx upstream status monitor</h1>\n");
// =======begin http data==========
b->last = ngx_snprintf(b->last, b->end - b->last,
"<h2>http upstream servers </h2> up: %ui down: %ui total: %ui\n"
"<table style=\"background-color:white\" cellspacing=\"0\" "
" cellpadding=\"3\" border=\"1\">\n"
" <tr bgcolor=\"#C0C0C0\">\n"
" <th>Index</th>\n"
" <th>Upstream</th>\n"
" <th>Name</th>\n"
" <th>Status</th>\n"
" <th>Rise counts</th>\n"
" <th>Fall counts</th>\n"
" <th>Check type</th>\n"
" <th>Check port</th>\n"
" </tr>\n",
http_up_count, http_count-http_up_count, http_count);
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
" <tr%s>\n"
" <td>%ui</td>\n"
" <td>%V</td>\n"
" <td>%V</td>\n"
" <td>%s</td>\n"
" <td>%ui</td>\n"
" <td>%ui</td>\n"
" <td>%V</td>\n"
" <td>%ui</td>\n"
" </tr>\n",
peer[i].shm->down ? " bgcolor=\"#FF0000\"" : "",
i,
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->down ? "down" : "up",
peer[i].shm->rise_count,
peer[i].shm->fall_count,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port);
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"</table>\n");
// =======begin stream data==========
b->last = ngx_snprintf(b->last, b->end - b->last,
"<h2>stream upstream servers </h2> up: %ui down: %ui total: %ui\n"
"<table style=\"background-color:white\" cellspacing=\"0\" "
" cellpadding=\"3\" border=\"1\">\n"
" <tr bgcolor=\"#C0C0C0\">\n"
" <th>Index</th>\n"
" <th>Upstream</th>\n"
" <th>Name</th>\n"
" <th>Status</th>\n"
" <th>Rise counts</th>\n"
" <th>Fall counts</th>\n"
" <th>Check type</th>\n"
" <th>Check port</th>\n"
" </tr>\n",
stream_up_count, stream_count-stream_up_count, stream_count);
peers = stream_peers_ctx; //stream
if(peers != NULL){
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
" <tr%s>\n"
" <td>%ui</td>\n"
" <td>%V</td>\n"
" <td>%V</td>\n"
" <td>%s</td>\n"
" <td>%ui</td>\n"
" <td>%ui</td>\n"
" <td>%V</td>\n"
" <td>%ui</td>\n"
" </tr>\n",
peer[i].shm->down ? " bgcolor=\"#FF0000\"" : "",
i,
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->down ? "down" : "up",
peer[i].shm->rise_count,
peer[i].shm->fall_count,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port);
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"</table>\n"
"<h2>total servers(check enabled): %ui </h2>\n"
"</body></html>\n",
stream_count+http_count);
}
static void
ngx_upstream_check_status_csv_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag)
{
ngx_uint_t i;
ngx_upstream_check_peer_t *peer;
b->last = ngx_snprintf(b->last, b->end - b->last,
"index,upstream_type,upstream_name,host,rise,fall,check_type,check_port,status\n");
peers = http_peers_ctx; //http
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"%ui,http,%V,%V,%ui,%ui,%V,%ui,%s\n",
i,
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->rise_count,
peer[i].shm->fall_count,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
peer[i].shm->down ? "down" : "up");
}
peers = stream_peers_ctx; //stream
if(peers == NULL) return;
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"%ui,stream,%V,%V,%ui,%ui,%V,%ui,%s\n",
i,
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->rise_count,
peer[i].shm->fall_count,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
peer[i].shm->down ? "down" : "up");
}
}
static void
ngx_upstream_check_status_json_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag)
{
ngx_uint_t count, i;
ngx_uint_t stream_count=0, http_count=0;
ngx_upstream_check_peer_t *peer;
/* calc display total num after filter param*/
count = 0;
peers = stream_peers_ctx; //stream
if(peers != NULL){ //when no stream section, peers is NULL
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
count++;stream_count++;
}
}
peers = http_peers_ctx; //http
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
count++;http_count++;
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"{\"servers\": {\n"
" \"total\": %ui,\n"
" \"generation\": %ui,\n"
" \"http\": [\n",
count,
ngx_stream_upstream_check_shm_generation);
//http
count = 0;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
count++;
b->last = ngx_snprintf(b->last, b->end - b->last,
" {\"index\": %ui, "
"\"upstream\": \"%V\", "
"\"name\": \"%V\", "
"\"status\": \"%s\", "
"\"rise\": %ui, "
"\"fall\": %ui, "
"\"type\": \"%V\", "
"\"port\": %ui}"
"%s\n",
i,
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->down ? "down" : "up",
peer[i].shm->rise_count,
peer[i].shm->fall_count,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
(count == http_count) ? "" : ",");
}
//http end
b->last = ngx_snprintf(b->last, b->end - b->last,
" ],\n"
" \"stream\": [\n");
peers = stream_peers_ctx; //stream
count = 0;
if(peers != NULL){
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
count++;
b->last = ngx_snprintf(b->last, b->end - b->last,
" {\"index\": %ui, "
"\"upstream\": \"%V\", "
"\"name\": \"%V\", "
"\"status\": \"%s\", "
"\"rise\": %ui, "
"\"fall\": %ui, "
"\"type\": \"%V\", "
"\"port\": %ui}"
"%s\n",
i,
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->down ? "down" : "up",
peer[i].shm->rise_count,
peer[i].shm->fall_count,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
(count == stream_count) ? "" : ",");
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
" ]\n");
b->last = ngx_snprintf(b->last, b->end - b->last,
"}}\n");
}
static void
ngx_http_upstream_check_status_prometheus_format(ngx_buf_t *b,
ngx_upstream_check_peers_t *peers, ngx_uint_t flag)
{
ngx_uint_t count, upCount, downCount, i, j;
ngx_upstream_check_peer_t *peer;
ngx_str_t upstream_type[2] = {ngx_string("http"), ngx_string("stream")};
ngx_upstream_check_peers_t *upstream_peers[2] = {http_peers_ctx, stream_peers_ctx};
/* 1. summary */
upCount = 0;
downCount = 0;
count = 0;
for(j=0; j < 2; j++) {
peers = upstream_peers[j];
if (peers == NULL) continue;
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
/*
if (peer[i].delete) {
continue;
}
*/
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
count++;
if (peer[i].shm->down) {
downCount++;
} else {
upCount++;
}
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"# HELP nginx_upstream_count_total Nginx total number of servers\n"
"# TYPE nginx_upstream_count_total gauge\n"
"nginx_upstream_count_total %ui\n"
"# HELP nginx_upstream_count_up Nginx total number of servers that are UP\n"
"# TYPE nginx_upstream_count_up gauge\n"
"nginx_upstream_count_up %ui\n"
"# HELP nginx_upstream_count_down Nginx total number of servers that are DOWN\n"
"# TYPE nginx_upstream_count_down gauge\n"
"nginx_upstream_count_down %ui\n"
"# HELP nginx_upstream_count_generation Nginx generation\n"
"# TYPE nginx_upstream_count_generation gauge\n"
"nginx_upstream_count_generation %ui\n",
count,
upCount,
downCount,
ngx_stream_upstream_check_shm_generation);
/* 2. ngninx_upstream_server_rise */
b->last = ngx_snprintf(b->last, b->end - b->last,
"# HELP nginx_upstream_server_rise Nginx rise counter\n"
"# TYPE nginx_upstream_server_rise counter\n");
for(j=0; j < 2; j++) {
peers = upstream_peers[j];
if (peers == NULL) continue;
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
/*
if (peer[i].delete) {
continue;
}
*/
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"nginx_upstream_server_rise{index=\"%ui\",upstream_type=\"%V\",upstream=\"%V\",name=\"%V\",status=\"%s\",type=\"%V\",port=\"%ui\"} %ui\n",
i,
&upstream_type[j],
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->down ? "down" : "up",
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
peer[i].shm->rise_count);
}
}
/* 3. ngninx_upstream_server_fall */
b->last = ngx_snprintf(b->last, b->end - b->last,
"# HELP nginx_upstream_server_fall Nginx fall counter\n"
"# TYPE nginx_upstream_server_fall counter\n");
for(j=0; j < 2; j++) {
peers = upstream_peers[j];
if (peers == NULL) continue;
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
/*
if (peer[i].delete) {
continue;
}
*/
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"nginx_upstream_server_fall{index=\"%ui\",upstream_type=\"%V\",upstream=\"%V\",name=\"%V\",status=\"%s\",type=\"%V\",port=\"%ui\"} %ui\n",
i,
&upstream_type[j],
peer[i].upstream_name,
&peer[i].peer_addr->name,
peer[i].shm->down ? "down" : "up",
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
peer[i].shm->fall_count);
}
}
/* 4. ngninx_upstream_server_active */
b->last = ngx_snprintf(b->last, b->end - b->last,
"# HELP nginx_upstream_server_active Nginx active 1 for UP / 0 for DOWN\n"
"# TYPE nginx_upstream_server_active gauge\n");
for(j=0; j < 2; j++) {
peers = upstream_peers[j];
if (peers == NULL) continue;
peer = peers->peers.elts;
for (i = 0; i < peers->peers.nelts; i++) {
/*
if (peer[i].delete) {
continue;
}
*/
if (flag & NGX_CHECK_STATUS_DOWN) {
if (!peer[i].shm->down) {
continue;
}
} else if (flag & NGX_CHECK_STATUS_UP) {
if (peer[i].shm->down) {
continue;
}
}
b->last = ngx_snprintf(b->last, b->end - b->last,
"nginx_upstream_server_active{index=\"%ui\",upstream_type=\"%V\",upstream=\"%V\",name=\"%V\",type=\"%V\",port=\"%ui\"} %ui\n",
i,
&upstream_type[j],
peer[i].upstream_name,
&peer[i].peer_addr->name,
&peer[i].conf->check_type_conf->name,
peer[i].conf->port,
peer[i].shm->down ? 0 : 1);
}
}
}
static ngx_check_status_conf_t *
ngx_http_get_check_status_format_conf(ngx_str_t *str)
{
ngx_uint_t i;
for (i = 0; ; i++) {
if (ngx_check_status_formats[i].format.len == 0) {
break;
}
if (str->len != ngx_check_status_formats[i].format.len) {
continue;
}
if (ngx_strncmp(str->data, ngx_check_status_formats[i].format.data,
str->len) == 0)
{
return &ngx_check_status_formats[i];
}
}
return NULL;
}
//end healthcheck status interface
1
https://gitee.com/hrq/ngx_healthcheck_module.git
git@gitee.com:hrq/ngx_healthcheck_module.git
hrq
ngx_healthcheck_module
ngx_healthcheck_module
master

搜索帮助