REORG: cli: move "show info" to stats.c
Move the "show info" command to stats.c using the CLI keyword API
to register it on the CLI. The stats_dump_info_to_buffer() function
is now static again. Note, we don't need proto_ssl anymore in cli.c.
diff --git a/include/types/cli.h b/include/types/cli.h
index 9c7bed5..883c72d 100644
--- a/include/types/cli.h
+++ b/include/types/cli.h
@@ -38,69 +38,6 @@
struct cli_kw kw[VAR_ARRAY];
};
-/* Show Info fields for CLI output. For any field added here, please add the text
- * representation in the info_field_names array below. Please only append at the end,
- * before the INF_TOTAL_FIELDS entry, and never insert anything in the middle
- * nor at the beginning.
- */
-enum info_field {
- INF_NAME,
- INF_VERSION,
- INF_RELEASE_DATE,
- INF_NBPROC,
- INF_PROCESS_NUM,
- INF_PID,
- INF_UPTIME,
- INF_UPTIME_SEC,
- INF_MEMMAX_MB,
- INF_POOL_ALLOC_MB,
- INF_POOL_USED_MB,
- INF_POOL_FAILED,
- INF_ULIMIT_N,
- INF_MAXSOCK,
- INF_MAXCONN,
- INF_HARD_MAXCONN,
- INF_CURR_CONN,
- INF_CUM_CONN,
- INF_CUM_REQ,
- INF_MAX_SSL_CONNS,
- INF_CURR_SSL_CONNS,
- INF_CUM_SSL_CONNS,
- INF_MAXPIPES,
- INF_PIPES_USED,
- INF_PIPES_FREE,
- INF_CONN_RATE,
- INF_CONN_RATE_LIMIT,
- INF_MAX_CONN_RATE,
- INF_SESS_RATE,
- INF_SESS_RATE_LIMIT,
- INF_MAX_SESS_RATE,
- INF_SSL_RATE,
- INF_SSL_RATE_LIMIT,
- INF_MAX_SSL_RATE,
- INF_SSL_FRONTEND_KEY_RATE,
- INF_SSL_FRONTEND_MAX_KEY_RATE,
- INF_SSL_FRONTEND_SESSION_REUSE_PCT,
- INF_SSL_BACKEND_KEY_RATE,
- INF_SSL_BACKEND_MAX_KEY_RATE,
- INF_SSL_CACHE_LOOKUPS,
- INF_SSL_CACHE_MISSES,
- INF_COMPRESS_BPS_IN,
- INF_COMPRESS_BPS_OUT,
- INF_COMPRESS_BPS_RATE_LIM,
- INF_ZLIB_MEM_USAGE,
- INF_MAX_ZLIB_MEM_USAGE,
- INF_TASKS,
- INF_RUN_QUEUE,
- INF_IDLE_PCT,
- INF_NODE,
- INF_DESCRIPTION,
-
- /* must always be the last one */
- INF_TOTAL_FIELDS
-};
-
-
/* stats socket states */
enum {
STAT_CLI_INIT = 0, /* initial state, must leave to zero ! */
@@ -110,7 +47,6 @@
STAT_CLI_PROMPT, /* display the prompt (first output, same code) */
STAT_CLI_PRINT, /* display message in cli->msg */
STAT_CLI_PRINT_FREE, /* display message in cli->msg. After the display, free the pointer */
- STAT_CLI_O_INFO, /* dump info */
STAT_CLI_O_ERR, /* dump errors */
STAT_CLI_O_TAB, /* dump tables */
STAT_CLI_O_CLR, /* clear tables */
diff --git a/include/types/stats.h b/include/types/stats.h
index dd52bba..48cf645 100644
--- a/include/types/stats.h
+++ b/include/types/stats.h
@@ -224,6 +224,69 @@
} u;
};
+/* Show Info fields for CLI output. For any field added here, please add the text
+ * representation in the info_field_names array below. Please only append at the end,
+ * before the INF_TOTAL_FIELDS entry, and never insert anything in the middle
+ * nor at the beginning.
+ */
+enum info_field {
+ INF_NAME,
+ INF_VERSION,
+ INF_RELEASE_DATE,
+ INF_NBPROC,
+ INF_PROCESS_NUM,
+ INF_PID,
+ INF_UPTIME,
+ INF_UPTIME_SEC,
+ INF_MEMMAX_MB,
+ INF_POOL_ALLOC_MB,
+ INF_POOL_USED_MB,
+ INF_POOL_FAILED,
+ INF_ULIMIT_N,
+ INF_MAXSOCK,
+ INF_MAXCONN,
+ INF_HARD_MAXCONN,
+ INF_CURR_CONN,
+ INF_CUM_CONN,
+ INF_CUM_REQ,
+ INF_MAX_SSL_CONNS,
+ INF_CURR_SSL_CONNS,
+ INF_CUM_SSL_CONNS,
+ INF_MAXPIPES,
+ INF_PIPES_USED,
+ INF_PIPES_FREE,
+ INF_CONN_RATE,
+ INF_CONN_RATE_LIMIT,
+ INF_MAX_CONN_RATE,
+ INF_SESS_RATE,
+ INF_SESS_RATE_LIMIT,
+ INF_MAX_SESS_RATE,
+ INF_SSL_RATE,
+ INF_SSL_RATE_LIMIT,
+ INF_MAX_SSL_RATE,
+ INF_SSL_FRONTEND_KEY_RATE,
+ INF_SSL_FRONTEND_MAX_KEY_RATE,
+ INF_SSL_FRONTEND_SESSION_REUSE_PCT,
+ INF_SSL_BACKEND_KEY_RATE,
+ INF_SSL_BACKEND_MAX_KEY_RATE,
+ INF_SSL_CACHE_LOOKUPS,
+ INF_SSL_CACHE_MISSES,
+ INF_COMPRESS_BPS_IN,
+ INF_COMPRESS_BPS_OUT,
+ INF_COMPRESS_BPS_RATE_LIM,
+ INF_ZLIB_MEM_USAGE,
+ INF_MAX_ZLIB_MEM_USAGE,
+ INF_TASKS,
+ INF_RUN_QUEUE,
+ INF_IDLE_PCT,
+ INF_NODE,
+ INF_DESCRIPTION,
+
+ /* must always be the last one */
+ INF_TOTAL_FIELDS
+};
+
+
/* Stats fields for CSV output. For any field added here, please add the text
* representation in the stat_field_names array below. Please only append at the end,
* before the ST_F_TOTAL_FIELDS entry, and never insert anything in the middle
diff --git a/src/cli.c b/src/cli.c
index cdfbebf..a395e23 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -67,74 +67,7 @@
#include <proto/stream_interface.h>
#include <proto/task.h>
-#ifdef USE_OPENSSL
-#include <proto/ssl_sock.h>
-#include <types/ssl_sock.h>
-#endif
-
-/* These are the field names for each INF_* field position. Please pay attention
- * to always use the exact same name except that the strings for new names must
- * be lower case or CamelCase while the enum entries must be upper case.
- */
-const char *info_field_names[INF_TOTAL_FIELDS] = {
- [INF_NAME] = "Name",
- [INF_VERSION] = "Version",
- [INF_RELEASE_DATE] = "Release_date",
- [INF_NBPROC] = "Nbproc",
- [INF_PROCESS_NUM] = "Process_num",
- [INF_PID] = "Pid",
- [INF_UPTIME] = "Uptime",
- [INF_UPTIME_SEC] = "Uptime_sec",
- [INF_MEMMAX_MB] = "Memmax_MB",
- [INF_POOL_ALLOC_MB] = "PoolAlloc_MB",
- [INF_POOL_USED_MB] = "PoolUsed_MB",
- [INF_POOL_FAILED] = "PoolFailed",
- [INF_ULIMIT_N] = "Ulimit-n",
- [INF_MAXSOCK] = "Maxsock",
- [INF_MAXCONN] = "Maxconn",
- [INF_HARD_MAXCONN] = "Hard_maxconn",
- [INF_CURR_CONN] = "CurrConns",
- [INF_CUM_CONN] = "CumConns",
- [INF_CUM_REQ] = "CumReq",
- [INF_MAX_SSL_CONNS] = "MaxSslConns",
- [INF_CURR_SSL_CONNS] = "CurrSslConns",
- [INF_CUM_SSL_CONNS] = "CumSslConns",
- [INF_MAXPIPES] = "Maxpipes",
- [INF_PIPES_USED] = "PipesUsed",
- [INF_PIPES_FREE] = "PipesFree",
- [INF_CONN_RATE] = "ConnRate",
- [INF_CONN_RATE_LIMIT] = "ConnRateLimit",
- [INF_MAX_CONN_RATE] = "MaxConnRate",
- [INF_SESS_RATE] = "SessRate",
- [INF_SESS_RATE_LIMIT] = "SessRateLimit",
- [INF_MAX_SESS_RATE] = "MaxSessRate",
- [INF_SSL_RATE] = "SslRate",
- [INF_SSL_RATE_LIMIT] = "SslRateLimit",
- [INF_MAX_SSL_RATE] = "MaxSslRate",
- [INF_SSL_FRONTEND_KEY_RATE] = "SslFrontendKeyRate",
- [INF_SSL_FRONTEND_MAX_KEY_RATE] = "SslFrontendMaxKeyRate",
- [INF_SSL_FRONTEND_SESSION_REUSE_PCT] = "SslFrontendSessionReuse_pct",
- [INF_SSL_BACKEND_KEY_RATE] = "SslBackendKeyRate",
- [INF_SSL_BACKEND_MAX_KEY_RATE] = "SslBackendMaxKeyRate",
- [INF_SSL_CACHE_LOOKUPS] = "SslCacheLookups",
- [INF_SSL_CACHE_MISSES] = "SslCacheMisses",
- [INF_COMPRESS_BPS_IN] = "CompressBpsIn",
- [INF_COMPRESS_BPS_OUT] = "CompressBpsOut",
- [INF_COMPRESS_BPS_RATE_LIM] = "CompressBpsRateLim",
- [INF_ZLIB_MEM_USAGE] = "ZlibMemUsage",
- [INF_MAX_ZLIB_MEM_USAGE] = "MaxZlibMemUsage",
- [INF_TASKS] = "Tasks",
- [INF_RUN_QUEUE] = "Run_queue",
- [INF_IDLE_PCT] = "Idle_pct",
- [INF_NODE] = "node",
- [INF_DESCRIPTION] = "description",
-};
-
-/* one line of stats */
-static struct field info[INF_TOTAL_FIELDS];
-
static int stats_dump_env_to_buffer(struct stream_interface *si);
-static int stats_dump_info_to_buffer(struct stream_interface *si);
static int stats_dump_errors_to_buffer(struct stream_interface *si);
static int stats_table_request(struct stream_interface *si, int show);
@@ -149,7 +82,6 @@
" prompt : toggle interactive mode with prompt\n"
" quit : disconnect\n"
" show env [var] : dump environment variables known to the process\n"
- " show info : report information about the running process\n"
" show errors : report last request and response errors for each proxy\n"
" show table [id]: report table usage stats or dump this table's contents\n"
" set table [id] : update or create a table entry's data\n"
@@ -1076,12 +1008,6 @@
appctx->st2 = STAT_ST_END;
}
}
- else if (strcmp(args[1], "info") == 0) {
- if (strcmp(args[2], "typed") == 0)
- appctx->ctx.stats.flags |= STAT_FMT_TYPED;
- appctx->st2 = STAT_ST_INIT;
- appctx->st0 = STAT_CLI_O_INFO; // stats_dump_info_to_buffer
- }
else if (strcmp(args[1], "errors") == 0) {
if (strm_li(s)->bind_conf->level < ACCESS_LVL_OPER) {
appctx->ctx.cli.msg = stats_permission_denied_msg;
@@ -1807,10 +1733,6 @@
else
si_applet_cant_put(si);
break;
- case STAT_CLI_O_INFO:
- if (stats_dump_info_to_buffer(si))
- appctx->st0 = STAT_CLI_PROMPT;
- break;
case STAT_CLI_O_ERR: /* errors dump */
if (stats_dump_errors_to_buffer(si))
appctx->st0 = STAT_CLI_PROMPT;
@@ -1894,167 +1816,6 @@
si->state, req->flags, res->flags, req->buf->i, req->buf->o, res->buf->i, res->buf->o);
}
-/* Dump all fields from <info> into <out> using the "show info" format (name: value) */
-static int stats_dump_info_fields(struct chunk *out, const struct field *info)
-{
- int field;
-
- for (field = 0; field < INF_TOTAL_FIELDS; field++) {
- if (!field_format(info, field))
- continue;
-
- if (!chunk_appendf(out, "%s: ", info_field_names[field]))
- return 0;
- if (!stats_emit_raw_data_field(out, &info[field]))
- return 0;
- if (!chunk_strcat(out, "\n"))
- return 0;
- }
- return 1;
-}
-
-/* Dump all fields from <info> into <out> using the "show info typed" format */
-static int stats_dump_typed_info_fields(struct chunk *out, const struct field *info)
-{
- int field;
-
- for (field = 0; field < INF_TOTAL_FIELDS; field++) {
- if (!field_format(info, field))
- continue;
-
- if (!chunk_appendf(out, "%d.%s.%u:", field, info_field_names[field], info[INF_PROCESS_NUM].u.u32))
- return 0;
- if (!stats_emit_field_tags(out, &info[field], ':'))
- return 0;
- if (!stats_emit_typed_data_field(out, &info[field]))
- return 0;
- if (!chunk_strcat(out, "\n"))
- return 0;
- }
- return 1;
-}
-
-/* Fill <info> with HAProxy global info. <info> is preallocated
- * array of length <len>. The length of the aray must be
- * INF_TOTAL_FIELDS. If this length is less then this value, the
- * function returns 0, otherwise, it returns 1.
- */
-int stats_fill_info(struct field *info, int len)
-{
- unsigned int up = (now.tv_sec - start_date.tv_sec);
- struct chunk *out = get_trash_chunk();
-
-#ifdef USE_OPENSSL
- int ssl_sess_rate = read_freq_ctr(&global.ssl_per_sec);
- int ssl_key_rate = read_freq_ctr(&global.ssl_fe_keys_per_sec);
- int ssl_reuse = 0;
-
- if (ssl_key_rate < ssl_sess_rate) {
- /* count the ssl reuse ratio and avoid overflows in both directions */
- ssl_reuse = 100 - (100 * ssl_key_rate + (ssl_sess_rate - 1) / 2) / ssl_sess_rate;
- }
-#endif
-
- if (len < INF_TOTAL_FIELDS)
- return 0;
-
- chunk_reset(out);
- memset(info, 0, sizeof(*info) * len);
-
- info[INF_NAME] = mkf_str(FO_PRODUCT|FN_OUTPUT|FS_SERVICE, PRODUCT_NAME);
- info[INF_VERSION] = mkf_str(FO_PRODUCT|FN_OUTPUT|FS_SERVICE, HAPROXY_VERSION);
- info[INF_RELEASE_DATE] = mkf_str(FO_PRODUCT|FN_OUTPUT|FS_SERVICE, HAPROXY_DATE);
-
- info[INF_NBPROC] = mkf_u32(FO_CONFIG|FS_SERVICE, global.nbproc);
- info[INF_PROCESS_NUM] = mkf_u32(FO_KEY, relative_pid);
- info[INF_PID] = mkf_u32(FO_STATUS, pid);
-
- info[INF_UPTIME] = mkf_str(FN_DURATION, chunk_newstr(out));
- chunk_appendf(out, "%ud %uh%02um%02us", up / 86400, (up % 86400) / 3600, (up % 3600) / 60, (up % 60));
-
- info[INF_UPTIME_SEC] = mkf_u32(FN_DURATION, up);
- info[INF_MEMMAX_MB] = mkf_u32(FO_CONFIG|FN_LIMIT, global.rlimit_memmax);
- info[INF_POOL_ALLOC_MB] = mkf_u32(0, (unsigned)(pool_total_allocated() / 1048576L));
- info[INF_POOL_USED_MB] = mkf_u32(0, (unsigned)(pool_total_used() / 1048576L));
- info[INF_POOL_FAILED] = mkf_u32(FN_COUNTER, pool_total_failures());
- info[INF_ULIMIT_N] = mkf_u32(FO_CONFIG|FN_LIMIT, global.rlimit_nofile);
- info[INF_MAXSOCK] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxsock);
- info[INF_MAXCONN] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxconn);
- info[INF_HARD_MAXCONN] = mkf_u32(FO_CONFIG|FN_LIMIT, global.hardmaxconn);
- info[INF_CURR_CONN] = mkf_u32(0, actconn);
- info[INF_CUM_CONN] = mkf_u32(FN_COUNTER, totalconn);
- info[INF_CUM_REQ] = mkf_u32(FN_COUNTER, global.req_count);
-#ifdef USE_OPENSSL
- info[INF_MAX_SSL_CONNS] = mkf_u32(FN_MAX, global.maxsslconn);
- info[INF_CURR_SSL_CONNS] = mkf_u32(0, sslconns);
- info[INF_CUM_SSL_CONNS] = mkf_u32(FN_COUNTER, totalsslconns);
-#endif
- info[INF_MAXPIPES] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxpipes);
- info[INF_PIPES_USED] = mkf_u32(0, pipes_used);
- info[INF_PIPES_FREE] = mkf_u32(0, pipes_free);
- info[INF_CONN_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&global.conn_per_sec));
- info[INF_CONN_RATE_LIMIT] = mkf_u32(FO_CONFIG|FN_LIMIT, global.cps_lim);
- info[INF_MAX_CONN_RATE] = mkf_u32(FN_MAX, global.cps_max);
- info[INF_SESS_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&global.sess_per_sec));
- info[INF_SESS_RATE_LIMIT] = mkf_u32(FO_CONFIG|FN_LIMIT, global.sps_lim);
- info[INF_MAX_SESS_RATE] = mkf_u32(FN_RATE, global.sps_max);
-
-#ifdef USE_OPENSSL
- info[INF_SSL_RATE] = mkf_u32(FN_RATE, ssl_sess_rate);
- info[INF_SSL_RATE_LIMIT] = mkf_u32(FO_CONFIG|FN_LIMIT, global.ssl_lim);
- info[INF_MAX_SSL_RATE] = mkf_u32(FN_MAX, global.ssl_max);
- info[INF_SSL_FRONTEND_KEY_RATE] = mkf_u32(0, ssl_key_rate);
- info[INF_SSL_FRONTEND_MAX_KEY_RATE] = mkf_u32(FN_MAX, global.ssl_fe_keys_max);
- info[INF_SSL_FRONTEND_SESSION_REUSE_PCT] = mkf_u32(0, ssl_reuse);
- info[INF_SSL_BACKEND_KEY_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&global.ssl_be_keys_per_sec));
- info[INF_SSL_BACKEND_MAX_KEY_RATE] = mkf_u32(FN_MAX, global.ssl_be_keys_max);
- info[INF_SSL_CACHE_LOOKUPS] = mkf_u32(FN_COUNTER, global.shctx_lookups);
- info[INF_SSL_CACHE_MISSES] = mkf_u32(FN_COUNTER, global.shctx_misses);
-#endif
- info[INF_COMPRESS_BPS_IN] = mkf_u32(FN_RATE, read_freq_ctr(&global.comp_bps_in));
- info[INF_COMPRESS_BPS_OUT] = mkf_u32(FN_RATE, read_freq_ctr(&global.comp_bps_out));
- info[INF_COMPRESS_BPS_RATE_LIM] = mkf_u32(FO_CONFIG|FN_LIMIT, global.comp_rate_lim);
-#ifdef USE_ZLIB
- info[INF_ZLIB_MEM_USAGE] = mkf_u32(0, zlib_used_memory);
- info[INF_MAX_ZLIB_MEM_USAGE] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxzlibmem);
-#endif
- info[INF_TASKS] = mkf_u32(0, nb_tasks_cur);
- info[INF_RUN_QUEUE] = mkf_u32(0, run_queue_cur);
- info[INF_IDLE_PCT] = mkf_u32(FN_AVG, idle_pct);
- info[INF_NODE] = mkf_str(FO_CONFIG|FN_OUTPUT|FS_SERVICE, global.node);
- if (global.desc)
- info[INF_DESCRIPTION] = mkf_str(FO_CONFIG|FN_OUTPUT|FS_SERVICE, global.desc);
-
- return 1;
-}
-
-/* This function dumps information onto the stream interface's read buffer.
- * It returns 0 as long as it does not complete, non-zero upon completion.
- * No state is used.
- */
-static int stats_dump_info_to_buffer(struct stream_interface *si)
-{
- struct appctx *appctx = __objt_appctx(si->end);
-
- if (!stats_fill_info(info, INF_TOTAL_FIELDS))
- return 0;
-
- chunk_reset(&trash);
-
- if (appctx->ctx.stats.flags & STAT_FMT_TYPED)
- stats_dump_typed_info_fields(&trash, info);
- else
- stats_dump_info_fields(&trash, info);
-
- if (bi_putchk(si_ic(si), &trash) == -1) {
- si_applet_cant_put(si);
- return 0;
- }
-
- return 1;
-}
-
-
/* This is called when the stream interface is closed. For instance, upon an
* external abort, we won't call the i/o handler anymore so we may need to
* remove back references to the stream currently being dumped.
diff --git a/src/stats.c b/src/stats.c
index e879614..56266eb 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -74,6 +74,64 @@
#endif
+/* These are the field names for each INF_* field position. Please pay attention
+ * to always use the exact same name except that the strings for new names must
+ * be lower case or CamelCase while the enum entries must be upper case.
+ */
+const char *info_field_names[INF_TOTAL_FIELDS] = {
+ [INF_NAME] = "Name",
+ [INF_VERSION] = "Version",
+ [INF_RELEASE_DATE] = "Release_date",
+ [INF_NBPROC] = "Nbproc",
+ [INF_PROCESS_NUM] = "Process_num",
+ [INF_PID] = "Pid",
+ [INF_UPTIME] = "Uptime",
+ [INF_UPTIME_SEC] = "Uptime_sec",
+ [INF_MEMMAX_MB] = "Memmax_MB",
+ [INF_POOL_ALLOC_MB] = "PoolAlloc_MB",
+ [INF_POOL_USED_MB] = "PoolUsed_MB",
+ [INF_POOL_FAILED] = "PoolFailed",
+ [INF_ULIMIT_N] = "Ulimit-n",
+ [INF_MAXSOCK] = "Maxsock",
+ [INF_MAXCONN] = "Maxconn",
+ [INF_HARD_MAXCONN] = "Hard_maxconn",
+ [INF_CURR_CONN] = "CurrConns",
+ [INF_CUM_CONN] = "CumConns",
+ [INF_CUM_REQ] = "CumReq",
+ [INF_MAX_SSL_CONNS] = "MaxSslConns",
+ [INF_CURR_SSL_CONNS] = "CurrSslConns",
+ [INF_CUM_SSL_CONNS] = "CumSslConns",
+ [INF_MAXPIPES] = "Maxpipes",
+ [INF_PIPES_USED] = "PipesUsed",
+ [INF_PIPES_FREE] = "PipesFree",
+ [INF_CONN_RATE] = "ConnRate",
+ [INF_CONN_RATE_LIMIT] = "ConnRateLimit",
+ [INF_MAX_CONN_RATE] = "MaxConnRate",
+ [INF_SESS_RATE] = "SessRate",
+ [INF_SESS_RATE_LIMIT] = "SessRateLimit",
+ [INF_MAX_SESS_RATE] = "MaxSessRate",
+ [INF_SSL_RATE] = "SslRate",
+ [INF_SSL_RATE_LIMIT] = "SslRateLimit",
+ [INF_MAX_SSL_RATE] = "MaxSslRate",
+ [INF_SSL_FRONTEND_KEY_RATE] = "SslFrontendKeyRate",
+ [INF_SSL_FRONTEND_MAX_KEY_RATE] = "SslFrontendMaxKeyRate",
+ [INF_SSL_FRONTEND_SESSION_REUSE_PCT] = "SslFrontendSessionReuse_pct",
+ [INF_SSL_BACKEND_KEY_RATE] = "SslBackendKeyRate",
+ [INF_SSL_BACKEND_MAX_KEY_RATE] = "SslBackendMaxKeyRate",
+ [INF_SSL_CACHE_LOOKUPS] = "SslCacheLookups",
+ [INF_SSL_CACHE_MISSES] = "SslCacheMisses",
+ [INF_COMPRESS_BPS_IN] = "CompressBpsIn",
+ [INF_COMPRESS_BPS_OUT] = "CompressBpsOut",
+ [INF_COMPRESS_BPS_RATE_LIM] = "CompressBpsRateLim",
+ [INF_ZLIB_MEM_USAGE] = "ZlibMemUsage",
+ [INF_MAX_ZLIB_MEM_USAGE] = "MaxZlibMemUsage",
+ [INF_TASKS] = "Tasks",
+ [INF_RUN_QUEUE] = "Run_queue",
+ [INF_IDLE_PCT] = "Idle_pct",
+ [INF_NODE] = "node",
+ [INF_DESCRIPTION] = "description",
+};
+
const char *stat_field_names[ST_F_TOTAL_FIELDS] = {
[ST_F_PXNAME] = "pxname",
[ST_F_SVNAME] = "svname",
@@ -160,10 +218,13 @@
[ST_F_DSES] = "dses",
};
+/* one line of info */
+static struct field info[INF_TOTAL_FIELDS];
/* one line of stats */
static struct field stats[ST_F_TOTAL_FIELDS];
+
/*
* http_stats_io_handler()
* -> stats_dump_stat_to_buffer() // same as above, but used for CSV or HTML
@@ -2813,6 +2874,175 @@
/* just to make gcc happy */ ;
}
+/* Dump all fields from <info> into <out> using the "show info" format (name: value) */
+static int stats_dump_info_fields(struct chunk *out, const struct field *info)
+{
+ int field;
+
+ for (field = 0; field < INF_TOTAL_FIELDS; field++) {
+ if (!field_format(info, field))
+ continue;
+
+ if (!chunk_appendf(out, "%s: ", info_field_names[field]))
+ return 0;
+ if (!stats_emit_raw_data_field(out, &info[field]))
+ return 0;
+ if (!chunk_strcat(out, "\n"))
+ return 0;
+ }
+ return 1;
+}
+
+/* Dump all fields from <info> into <out> using the "show info typed" format */
+static int stats_dump_typed_info_fields(struct chunk *out, const struct field *info)
+{
+ int field;
+
+ for (field = 0; field < INF_TOTAL_FIELDS; field++) {
+ if (!field_format(info, field))
+ continue;
+
+ if (!chunk_appendf(out, "%d.%s.%u:", field, info_field_names[field], info[INF_PROCESS_NUM].u.u32))
+ return 0;
+ if (!stats_emit_field_tags(out, &info[field], ':'))
+ return 0;
+ if (!stats_emit_typed_data_field(out, &info[field]))
+ return 0;
+ if (!chunk_strcat(out, "\n"))
+ return 0;
+ }
+ return 1;
+}
+
+/* Fill <info> with HAProxy global info. <info> is preallocated
+ * array of length <len>. The length of the aray must be
+ * INF_TOTAL_FIELDS. If this length is less then this value, the
+ * function returns 0, otherwise, it returns 1.
+ */
+int stats_fill_info(struct field *info, int len)
+{
+ unsigned int up = (now.tv_sec - start_date.tv_sec);
+ struct chunk *out = get_trash_chunk();
+
+#ifdef USE_OPENSSL
+ int ssl_sess_rate = read_freq_ctr(&global.ssl_per_sec);
+ int ssl_key_rate = read_freq_ctr(&global.ssl_fe_keys_per_sec);
+ int ssl_reuse = 0;
+
+ if (ssl_key_rate < ssl_sess_rate) {
+ /* count the ssl reuse ratio and avoid overflows in both directions */
+ ssl_reuse = 100 - (100 * ssl_key_rate + (ssl_sess_rate - 1) / 2) / ssl_sess_rate;
+ }
+#endif
+
+ if (len < INF_TOTAL_FIELDS)
+ return 0;
+
+ chunk_reset(out);
+ memset(info, 0, sizeof(*info) * len);
+
+ info[INF_NAME] = mkf_str(FO_PRODUCT|FN_OUTPUT|FS_SERVICE, PRODUCT_NAME);
+ info[INF_VERSION] = mkf_str(FO_PRODUCT|FN_OUTPUT|FS_SERVICE, HAPROXY_VERSION);
+ info[INF_RELEASE_DATE] = mkf_str(FO_PRODUCT|FN_OUTPUT|FS_SERVICE, HAPROXY_DATE);
+
+ info[INF_NBPROC] = mkf_u32(FO_CONFIG|FS_SERVICE, global.nbproc);
+ info[INF_PROCESS_NUM] = mkf_u32(FO_KEY, relative_pid);
+ info[INF_PID] = mkf_u32(FO_STATUS, pid);
+
+ info[INF_UPTIME] = mkf_str(FN_DURATION, chunk_newstr(out));
+ chunk_appendf(out, "%ud %uh%02um%02us", up / 86400, (up % 86400) / 3600, (up % 3600) / 60, (up % 60));
+
+ info[INF_UPTIME_SEC] = mkf_u32(FN_DURATION, up);
+ info[INF_MEMMAX_MB] = mkf_u32(FO_CONFIG|FN_LIMIT, global.rlimit_memmax);
+ info[INF_POOL_ALLOC_MB] = mkf_u32(0, (unsigned)(pool_total_allocated() / 1048576L));
+ info[INF_POOL_USED_MB] = mkf_u32(0, (unsigned)(pool_total_used() / 1048576L));
+ info[INF_POOL_FAILED] = mkf_u32(FN_COUNTER, pool_total_failures());
+ info[INF_ULIMIT_N] = mkf_u32(FO_CONFIG|FN_LIMIT, global.rlimit_nofile);
+ info[INF_MAXSOCK] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxsock);
+ info[INF_MAXCONN] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxconn);
+ info[INF_HARD_MAXCONN] = mkf_u32(FO_CONFIG|FN_LIMIT, global.hardmaxconn);
+ info[INF_CURR_CONN] = mkf_u32(0, actconn);
+ info[INF_CUM_CONN] = mkf_u32(FN_COUNTER, totalconn);
+ info[INF_CUM_REQ] = mkf_u32(FN_COUNTER, global.req_count);
+#ifdef USE_OPENSSL
+ info[INF_MAX_SSL_CONNS] = mkf_u32(FN_MAX, global.maxsslconn);
+ info[INF_CURR_SSL_CONNS] = mkf_u32(0, sslconns);
+ info[INF_CUM_SSL_CONNS] = mkf_u32(FN_COUNTER, totalsslconns);
+#endif
+ info[INF_MAXPIPES] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxpipes);
+ info[INF_PIPES_USED] = mkf_u32(0, pipes_used);
+ info[INF_PIPES_FREE] = mkf_u32(0, pipes_free);
+ info[INF_CONN_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&global.conn_per_sec));
+ info[INF_CONN_RATE_LIMIT] = mkf_u32(FO_CONFIG|FN_LIMIT, global.cps_lim);
+ info[INF_MAX_CONN_RATE] = mkf_u32(FN_MAX, global.cps_max);
+ info[INF_SESS_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&global.sess_per_sec));
+ info[INF_SESS_RATE_LIMIT] = mkf_u32(FO_CONFIG|FN_LIMIT, global.sps_lim);
+ info[INF_MAX_SESS_RATE] = mkf_u32(FN_RATE, global.sps_max);
+
+#ifdef USE_OPENSSL
+ info[INF_SSL_RATE] = mkf_u32(FN_RATE, ssl_sess_rate);
+ info[INF_SSL_RATE_LIMIT] = mkf_u32(FO_CONFIG|FN_LIMIT, global.ssl_lim);
+ info[INF_MAX_SSL_RATE] = mkf_u32(FN_MAX, global.ssl_max);
+ info[INF_SSL_FRONTEND_KEY_RATE] = mkf_u32(0, ssl_key_rate);
+ info[INF_SSL_FRONTEND_MAX_KEY_RATE] = mkf_u32(FN_MAX, global.ssl_fe_keys_max);
+ info[INF_SSL_FRONTEND_SESSION_REUSE_PCT] = mkf_u32(0, ssl_reuse);
+ info[INF_SSL_BACKEND_KEY_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&global.ssl_be_keys_per_sec));
+ info[INF_SSL_BACKEND_MAX_KEY_RATE] = mkf_u32(FN_MAX, global.ssl_be_keys_max);
+ info[INF_SSL_CACHE_LOOKUPS] = mkf_u32(FN_COUNTER, global.shctx_lookups);
+ info[INF_SSL_CACHE_MISSES] = mkf_u32(FN_COUNTER, global.shctx_misses);
+#endif
+ info[INF_COMPRESS_BPS_IN] = mkf_u32(FN_RATE, read_freq_ctr(&global.comp_bps_in));
+ info[INF_COMPRESS_BPS_OUT] = mkf_u32(FN_RATE, read_freq_ctr(&global.comp_bps_out));
+ info[INF_COMPRESS_BPS_RATE_LIM] = mkf_u32(FO_CONFIG|FN_LIMIT, global.comp_rate_lim);
+#ifdef USE_ZLIB
+ info[INF_ZLIB_MEM_USAGE] = mkf_u32(0, zlib_used_memory);
+ info[INF_MAX_ZLIB_MEM_USAGE] = mkf_u32(FO_CONFIG|FN_LIMIT, global.maxzlibmem);
+#endif
+ info[INF_TASKS] = mkf_u32(0, nb_tasks_cur);
+ info[INF_RUN_QUEUE] = mkf_u32(0, run_queue_cur);
+ info[INF_IDLE_PCT] = mkf_u32(FN_AVG, idle_pct);
+ info[INF_NODE] = mkf_str(FO_CONFIG|FN_OUTPUT|FS_SERVICE, global.node);
+ if (global.desc)
+ info[INF_DESCRIPTION] = mkf_str(FO_CONFIG|FN_OUTPUT|FS_SERVICE, global.desc);
+
+ return 1;
+}
+
+/* This function dumps information onto the stream interface's read buffer.
+ * It returns 0 as long as it does not complete, non-zero upon completion.
+ * No state is used.
+ */
+static int stats_dump_info_to_buffer(struct stream_interface *si)
+{
+ struct appctx *appctx = __objt_appctx(si->end);
+
+ if (!stats_fill_info(info, INF_TOTAL_FIELDS))
+ return 0;
+
+ chunk_reset(&trash);
+
+ if (appctx->ctx.stats.flags & STAT_FMT_TYPED)
+ stats_dump_typed_info_fields(&trash, info);
+ else
+ stats_dump_info_fields(&trash, info);
+
+ if (bi_putchk(si_ic(si), &trash) == -1) {
+ si_applet_cant_put(si);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int cli_parse_show_info(char **args, struct appctx *appctx, void *private)
+{
+ if (strcmp(args[2], "typed") == 0)
+ appctx->ctx.stats.flags |= STAT_FMT_TYPED;
+ appctx->st2 = STAT_ST_INIT;
+ return 0;
+}
+
+
static int cli_parse_show_stat(char **args, struct appctx *appctx, void *private)
{
if (*args[2] && *args[3] && *args[4]) {
@@ -2830,6 +3060,11 @@
return 0;
}
+static int cli_io_handler_dump_info(struct appctx *appctx)
+{
+ return stats_dump_info_to_buffer(appctx->owner);
+}
+
/* This I/O handler runs as an applet embedded in a stream interface. It is
* used to send raw stats over a socket.
*/
@@ -2840,6 +3075,7 @@
/* register cli keywords */
static struct cli_kw_list cli_kws = {{ },{
+ { { "show", "info", NULL }, "show info : report information about the running process", cli_parse_show_info, cli_io_handler_dump_info, NULL },
{ { "show", "stat", NULL }, "show stat : report counters for each proxy and server", cli_parse_show_stat, cli_io_handler_dump_stat, NULL },
{{},}
}};