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_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 */
struct {
int maxpollevents; /* max number of poll events at once */
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 */
#ifndef _HAPROXY_STATS_T_H
#define _HAPROXY_STATS_T_H
+#include <import/ebtree-t.h>
#include <haproxy/api-t.h>
#include <haproxy/buf-t.h>
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 {
uint32_t type;
union {
extern THREAD_LOCAL struct field *stat_lines[];
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;
int stats_putchk(struct appctx *appctx, struct buffer *buf, struct htx *htx);
#include <haproxy/sock.h>
#include <haproxy/sock_inet.h>
#include <haproxy/ssl_sock.h>
+#include <haproxy/stats-file.h>
#include <haproxy/stats-t.h>
#include <haproxy/stream.h>
#include <haproxy/task.h>
/* Apply server states */
apply_server_state();
+ /* Preload internal counters. */
+ apply_stats_file();
+
for (px = proxies_list; px; px = px->next)
srv_compute_all_admin_states(px);
ha_free(&localpeer);
ha_free(&global.server_state_base);
ha_free(&global.server_state_file);
+ ha_free(&global.stats_file);
task_destroy(idle_conn_task);
idle_conn_task = NULL;
#include <haproxy/stats-file.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <import/ebmbtree.h>
#include <haproxy/api.h>
#include <haproxy/buf.h>
#include <haproxy/chunk.h>
+#include <haproxy/errors.h>
+#include <haproxy/global.h>
#include <haproxy/guid-t.h>
#include <haproxy/list.h>
#include <haproxy/listener-t.h>
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);
+}
#include <sys/stat.h>
#include <sys/types.h>
+#include <import/ebsttree.h>
#include <haproxy/api.h>
#include <haproxy/activity.h>
#include <haproxy/applet.h>
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)
{