mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MINOR: stats: apply stats-file on process startup
This commit is the first one of a serie to implement preloading of haproxy counters via stats-file parsing. This patch defines a basic apply_stats_file() function. It implements reading line by line of a stats-file without any parsing for the moment. It is called automatically on process startup via init().
This commit is contained in:
parent
83731c8048
commit
34ae7755b3
@ -155,6 +155,7 @@ struct global {
|
|||||||
char *log_send_hostname; /* set hostname in syslog header */
|
char *log_send_hostname; /* set hostname in syslog header */
|
||||||
char *server_state_base; /* path to a directory where server state files can be found */
|
char *server_state_base; /* path to a directory where server state files can be found */
|
||||||
char *server_state_file; /* path to the file where server states are loaded from */
|
char *server_state_file; /* path to the file where server states are loaded from */
|
||||||
|
char *stats_file; /* path to stats-file */
|
||||||
unsigned char cluster_secret[16]; /* 128 bits of an SHA1 digest of a secret defined as ASCII string */
|
unsigned char cluster_secret[16]; /* 128 bits of an SHA1 digest of a secret defined as ASCII string */
|
||||||
struct {
|
struct {
|
||||||
int maxpollevents; /* max number of poll events at once */
|
int maxpollevents; /* max number of poll events at once */
|
||||||
|
@ -12,4 +12,12 @@ int stats_dump_fields_file(struct buffer *out,
|
|||||||
|
|
||||||
void stats_dump_file_header(int type, struct buffer *out);
|
void stats_dump_file_header(int type, struct buffer *out);
|
||||||
|
|
||||||
|
/* Maximun number of parsed stat column in a header line.
|
||||||
|
* Directly based on ST_I_PX_MAX, with value doubled to obtain compatibility
|
||||||
|
* between haproxy adjacent versions.
|
||||||
|
*/
|
||||||
|
#define STAT_FILE_MAX_COL_COUNT (ST_I_PX_MAX*2)
|
||||||
|
|
||||||
|
void apply_stats_file(void);
|
||||||
|
|
||||||
#endif /* _HAPROXY_STATS_FILE_H */
|
#endif /* _HAPROXY_STATS_FILE_H */
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#ifndef _HAPROXY_STATS_T_H
|
#ifndef _HAPROXY_STATS_T_H
|
||||||
#define _HAPROXY_STATS_T_H
|
#define _HAPROXY_STATS_T_H
|
||||||
|
|
||||||
|
#include <import/ebtree-t.h>
|
||||||
#include <haproxy/api-t.h>
|
#include <haproxy/api-t.h>
|
||||||
#include <haproxy/buf-t.h>
|
#include <haproxy/buf-t.h>
|
||||||
|
|
||||||
@ -479,6 +480,12 @@ enum stat_idx_px {
|
|||||||
ST_I_PX_MAX
|
ST_I_PX_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Node for name-indexed stat tree from generate_stat_tree(). */
|
||||||
|
struct stcol_node {
|
||||||
|
const struct stat_col *col;
|
||||||
|
struct ebmb_node name;
|
||||||
|
};
|
||||||
|
|
||||||
struct field {
|
struct field {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
union {
|
union {
|
||||||
|
@ -47,6 +47,8 @@ extern THREAD_LOCAL struct field stat_line_info[];
|
|||||||
extern THREAD_LOCAL struct field *stat_lines[];
|
extern THREAD_LOCAL struct field *stat_lines[];
|
||||||
extern struct name_desc *stat_cols[STATS_DOMAIN_COUNT];
|
extern struct name_desc *stat_cols[STATS_DOMAIN_COUNT];
|
||||||
|
|
||||||
|
int generate_stat_tree(struct eb_root *st_tree, const struct stat_col cols[]);
|
||||||
|
|
||||||
struct htx;
|
struct htx;
|
||||||
int stats_putchk(struct appctx *appctx, struct buffer *buf, struct htx *htx);
|
int stats_putchk(struct appctx *appctx, struct buffer *buf, struct htx *htx);
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@
|
|||||||
#include <haproxy/sock.h>
|
#include <haproxy/sock.h>
|
||||||
#include <haproxy/sock_inet.h>
|
#include <haproxy/sock_inet.h>
|
||||||
#include <haproxy/ssl_sock.h>
|
#include <haproxy/ssl_sock.h>
|
||||||
|
#include <haproxy/stats-file.h>
|
||||||
#include <haproxy/stats-t.h>
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/stream.h>
|
#include <haproxy/stream.h>
|
||||||
#include <haproxy/task.h>
|
#include <haproxy/task.h>
|
||||||
@ -2365,6 +2366,9 @@ static void init(int argc, char **argv)
|
|||||||
/* Apply server states */
|
/* Apply server states */
|
||||||
apply_server_state();
|
apply_server_state();
|
||||||
|
|
||||||
|
/* Preload internal counters. */
|
||||||
|
apply_stats_file();
|
||||||
|
|
||||||
for (px = proxies_list; px; px = px->next)
|
for (px = proxies_list; px; px = px->next)
|
||||||
srv_compute_all_admin_states(px);
|
srv_compute_all_admin_states(px);
|
||||||
|
|
||||||
@ -2943,6 +2947,7 @@ void deinit(void)
|
|||||||
ha_free(&localpeer);
|
ha_free(&localpeer);
|
||||||
ha_free(&global.server_state_base);
|
ha_free(&global.server_state_base);
|
||||||
ha_free(&global.server_state_file);
|
ha_free(&global.server_state_file);
|
||||||
|
ha_free(&global.stats_file);
|
||||||
task_destroy(idle_conn_task);
|
task_destroy(idle_conn_task);
|
||||||
idle_conn_task = NULL;
|
idle_conn_task = NULL;
|
||||||
|
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
#include <haproxy/stats-file.h>
|
#include <haproxy/stats-file.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <import/ebmbtree.h>
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/buf.h>
|
#include <haproxy/buf.h>
|
||||||
#include <haproxy/chunk.h>
|
#include <haproxy/chunk.h>
|
||||||
|
#include <haproxy/errors.h>
|
||||||
|
#include <haproxy/global.h>
|
||||||
#include <haproxy/guid-t.h>
|
#include <haproxy/guid-t.h>
|
||||||
#include <haproxy/list.h>
|
#include <haproxy/list.h>
|
||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener-t.h>
|
||||||
@ -90,3 +97,52 @@ void stats_dump_file_header(int type, struct buffer *out)
|
|||||||
|
|
||||||
chunk_strcat(out, "\n");
|
chunk_strcat(out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse a stats-file and preload haproxy internal counters. */
|
||||||
|
void apply_stats_file(void)
|
||||||
|
{
|
||||||
|
struct eb_root st_tree = EB_ROOT;
|
||||||
|
FILE *file;
|
||||||
|
char *line = NULL;
|
||||||
|
ssize_t len;
|
||||||
|
size_t alloc_len;
|
||||||
|
int linenum;
|
||||||
|
|
||||||
|
if (!global.stats_file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
file = fopen(global.stats_file, "r");
|
||||||
|
if (!file) {
|
||||||
|
ha_warning("config: Can't load stats file: cannot open file.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate stat columns map indexed by name. */
|
||||||
|
if (generate_stat_tree(&st_tree, stat_cols_px)) {
|
||||||
|
ha_warning("config: Can't load stats file: not enough memory.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
linenum = 0;
|
||||||
|
while (1) {
|
||||||
|
len = getline(&line, &alloc_len, file);
|
||||||
|
if (len < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++linenum;
|
||||||
|
if (!len || (len == 1 && line[0] == '\n'))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
while (!eb_is_empty(&st_tree)) {
|
||||||
|
struct ebmb_node *node = ebmb_first(&st_tree);
|
||||||
|
struct stcol_node *snode = ebmb_entry(node, struct stcol_node, name);
|
||||||
|
|
||||||
|
ebmb_delete(node);
|
||||||
|
ha_free(&snode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ha_free(&line);
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
31
src/stats.c
31
src/stats.c
@ -23,6 +23,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <import/ebsttree.h>
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/activity.h>
|
#include <haproxy/activity.h>
|
||||||
#include <haproxy/applet.h>
|
#include <haproxy/applet.h>
|
||||||
@ -336,6 +337,36 @@ struct list stats_module_list[STATS_DOMAIN_COUNT] = {
|
|||||||
|
|
||||||
THREAD_LOCAL void *trash_counters;
|
THREAD_LOCAL void *trash_counters;
|
||||||
|
|
||||||
|
/* Insert into <st_tree> all stat columns from <cols> indexed by their name. */
|
||||||
|
int generate_stat_tree(struct eb_root *st_tree, const struct stat_col cols[])
|
||||||
|
{
|
||||||
|
const struct stat_col *col;
|
||||||
|
struct stcol_node *node;
|
||||||
|
size_t len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
||||||
|
col = &cols[i];
|
||||||
|
if (stcol_nature(col) == FN_COUNTER) {
|
||||||
|
len = strlen(col->name);
|
||||||
|
node = malloc(sizeof(struct stcol_node) + len + 1);
|
||||||
|
if (!node)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
node->col = col;
|
||||||
|
memcpy(node->name.key, col->name, len);
|
||||||
|
node->name.key[len] = '\0';
|
||||||
|
|
||||||
|
ebst_insert(st_tree, &node->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int stats_putchk(struct appctx *appctx, struct buffer *buf, struct htx *htx)
|
int stats_putchk(struct appctx *appctx, struct buffer *buf, struct htx *htx)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user