Willy Tarreau | 9186126 | 2007-10-17 17:06:05 +0200 | [diff] [blame] | 1 | /* |
Willy Tarreau | eb47268 | 2010-05-28 18:46:57 +0200 | [diff] [blame] | 2 | * include/proto/dumpstats.h |
| 3 | * This file contains definitions of some primitives to dedicated to |
| 4 | * statistics output. |
| 5 | * |
Willy Tarreau | b24281b | 2011-02-13 13:16:36 +0100 | [diff] [blame] | 6 | * Copyright (C) 2000-2011 Willy Tarreau - w@1wt.eu |
Willy Tarreau | eb47268 | 2010-05-28 18:46:57 +0200 | [diff] [blame] | 7 | * |
| 8 | * This library is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU Lesser General Public |
| 10 | * License as published by the Free Software Foundation, version 2.1 |
| 11 | * exclusively. |
| 12 | * |
| 13 | * This library is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | * Lesser General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU Lesser General Public |
| 19 | * License along with this library; if not, write to the Free Software |
| 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 21 | */ |
Willy Tarreau | 9186126 | 2007-10-17 17:06:05 +0200 | [diff] [blame] | 22 | |
| 23 | #ifndef _PROTO_DUMPSTATS_H |
| 24 | #define _PROTO_DUMPSTATS_H |
| 25 | |
| 26 | #include <common/config.h> |
Willy Tarreau | 8a8d83b | 2015-04-13 13:24:54 +0200 | [diff] [blame] | 27 | #include <types/applet.h> |
Willy Tarreau | c7e4238 | 2012-08-24 19:22:53 +0200 | [diff] [blame] | 28 | #include <types/stream_interface.h> |
Willy Tarreau | 9186126 | 2007-10-17 17:06:05 +0200 | [diff] [blame] | 29 | |
Willy Tarreau | 295a837 | 2011-03-10 11:25:07 +0100 | [diff] [blame] | 30 | /* Flags for applet.ctx.stats.flags */ |
Willy Tarreau | 354898b | 2012-12-23 18:15:23 +0100 | [diff] [blame] | 31 | #define STAT_FMT_HTML 0x00000001 /* dump the stats in HTML format */ |
Willy Tarreau | cb80912 | 2016-01-11 20:08:42 +0100 | [diff] [blame] | 32 | #define STAT_FMT_TYPED 0x00000002 /* use the typed output format */ |
Willy Tarreau | 39f7e6d | 2008-03-17 21:38:24 +0100 | [diff] [blame] | 33 | #define STAT_HIDE_DOWN 0x00000008 /* hide 'down' servers in the stats page */ |
| 34 | #define STAT_NO_REFRESH 0x00000010 /* do not automatically refresh the stats page */ |
Cyril Bonté | 474be41 | 2010-10-12 00:14:36 +0200 | [diff] [blame] | 35 | #define STAT_ADMIN 0x00000020 /* indicate a stats admin level */ |
Willy Tarreau | af3cf70 | 2014-04-22 22:19:53 +0200 | [diff] [blame] | 36 | #define STAT_CHUNKED 0x00000040 /* use chunked encoding (HTTP/1.1) */ |
Willy Tarreau | 39f7e6d | 2008-03-17 21:38:24 +0100 | [diff] [blame] | 37 | #define STAT_BOUND 0x00800000 /* bound statistics to selected proxies/types/services */ |
Willy Tarreau | 55bb845 | 2007-10-17 18:44:57 +0200 | [diff] [blame] | 38 | |
Krzysztof Piotr Oledzki | 2c6962c | 2008-03-02 02:42:14 +0100 | [diff] [blame] | 39 | #define STATS_TYPE_FE 0 |
| 40 | #define STATS_TYPE_BE 1 |
| 41 | #define STATS_TYPE_SV 2 |
Krzysztof Piotr Oledzki | aeebf9b | 2009-10-04 15:43:17 +0200 | [diff] [blame] | 42 | #define STATS_TYPE_SO 3 |
Krzysztof Piotr Oledzki | 2c6962c | 2008-03-02 02:42:14 +0100 | [diff] [blame] | 43 | |
Willy Tarreau | 96d4491 | 2013-11-22 12:25:24 +0100 | [diff] [blame] | 44 | /* HTTP stats : applet.st0 */ |
| 45 | enum { |
| 46 | STAT_HTTP_DONE = 0, /* finished */ |
Willy Tarreau | 347a35d | 2013-11-22 17:51:09 +0100 | [diff] [blame] | 47 | STAT_HTTP_HEAD, /* send headers before dump */ |
Willy Tarreau | 96d4491 | 2013-11-22 12:25:24 +0100 | [diff] [blame] | 48 | STAT_HTTP_DUMP, /* dumping stats */ |
Willy Tarreau | 347a35d | 2013-11-22 17:51:09 +0100 | [diff] [blame] | 49 | STAT_HTTP_POST, /* waiting post data */ |
| 50 | STAT_HTTP_LAST, /* sending last chunk of response */ |
Willy Tarreau | 96d4491 | 2013-11-22 12:25:24 +0100 | [diff] [blame] | 51 | }; |
| 52 | |
de Lafond Guillaume | 88c278f | 2013-04-15 19:27:10 +0200 | [diff] [blame] | 53 | /* HTML form to limit output scope */ |
| 54 | #define STAT_SCOPE_TXT_MAXLEN 20 /* max len for scope substring */ |
| 55 | #define STAT_SCOPE_INPUT_NAME "scope" /* pattern form scope name <input> in html form */ |
| 56 | #define STAT_SCOPE_PATTERN "?" STAT_SCOPE_INPUT_NAME "=" |
| 57 | |
Willy Tarreau | 8e62c05 | 2016-01-04 17:23:25 +0100 | [diff] [blame] | 58 | /* This level of detail is needed to let the stats consumer know how to |
| 59 | * aggregate them (eg: between processes or cluster nodes). Only a few |
| 60 | * combinations are actually in use, though the mechanism tends to make |
| 61 | * this easy to extend to future uses. |
| 62 | * |
| 63 | * Each reported stats element is typed based on 4 dimensions : |
| 64 | * - the field format : it indicates the validity range of the reported value, |
| 65 | * its limits and how to parse it. 6 types are currently supported : |
| 66 | * empty, signed 32-bit integer, unsigned 32-bit integer, signed 64-bit |
| 67 | * integer, unsigned 64-bit integer, string |
| 68 | * |
| 69 | * - the field origin : how was the value retrieved and what it depends on. |
| 70 | * 5 origins are currently defined : product (eg: haproxy version or |
| 71 | * release date), configuration (eg: a configured limit), key (identifier |
| 72 | * used to group values at a certain level), metric (a measure of something), |
| 73 | * status (something discrete which by definition cannot be averaged nor |
| 74 | * aggregated, such as "listening" versus "full"). |
| 75 | * |
| 76 | * - the field nature : what does the data represent, implying how to aggregate |
| 77 | * it. At least 9 different natures are expected : counter (an increasing |
| 78 | * positive counter that may wrap when its type is overflown such as a byte |
| 79 | * counter), gauge (a measure at any instant that may vary, such as a |
| 80 | * concurrent connection count), a limit (eg: maximum acceptable concurrent |
| 81 | * connections), a minimum (eg: minimum free memory over a period), a |
| 82 | * maximum (eg: highest queue length over a period), an event rate (eg: |
| 83 | * incoming connections per second), a duration that is often aggregated by |
| 84 | * taking the max (eg: service uptime), an age that generally reports the |
| 85 | * last time an event appeared and which generally is aggregated by taking |
| 86 | * the most recent event hence the smallest one, the time which reports a |
| 87 | * discrete instant and cannot obviously be averaged either, a name which |
| 88 | * will generally be the name of an entity (such as a server name or cookie |
| 89 | * name), an output which is mostly used for various unsafe strings that are |
| 90 | * retrieved (eg: last check output, product name, description, etc), and an |
| 91 | * average which indicates that the value is relative and meant to be averaged |
| 92 | * between all nodes (eg: response time, throttling, etc). |
| 93 | * |
| 94 | * - the field scope : if the value is shared with other elements, which ones |
| 95 | * are expected to report the same value. The first scope with the least |
| 96 | * share is the process (most common one) where all data are only relevant |
| 97 | * to the process being consulted. The next one is the service, which is |
| 98 | * valid for all processes launched together (eg: shared SSL cache usage |
| 99 | * among processes). The next one is the system (such as the OS version) |
| 100 | * and which will report the same information for all instances running on |
| 101 | * the same node. The next one is the cluster, which indicates that the |
| 102 | * information are shared with other nodes being part of a same cluster. |
| 103 | * Stick-tables may carry such cluster-wide information. Larger scopes may |
| 104 | * be added in the future such as datacenter, country, continent, planet, |
| 105 | * galaxy, universe, etc. |
| 106 | * |
| 107 | * All these information will be encoded in the field as a bit field so that |
| 108 | * it is easy to pass composite values by simply ORing elements above, and |
| 109 | * to ease the definition of a few field types for the most common field |
| 110 | * combinations. |
| 111 | * |
| 112 | * The enums try to be arranged so that most likely characteristics are |
| 113 | * assigned the value zero, making it easier to add new fields. |
| 114 | * |
| 115 | * Field format has precedence over the other parts of the type. Please avoid |
| 116 | * declaring extra formats unless absolutely needed. The first one, FF_EMPTY, |
| 117 | * must absolutely have value zero so that it is what is returned after a |
| 118 | * memset(0). Furthermore, the producer is responsible for ensuring that when |
| 119 | * this format is set, all other bits of the type as well as the values in the |
| 120 | * union only contain zeroes. This makes it easier for the consumer to use the |
| 121 | * values as the expected type. |
| 122 | */ |
| 123 | |
| 124 | enum field_format { |
| 125 | FF_EMPTY = 0x00000000, |
| 126 | FF_S32 = 0x00000001, |
| 127 | FF_U32 = 0x00000002, |
| 128 | FF_S64 = 0x00000003, |
| 129 | FF_U64 = 0x00000004, |
| 130 | FF_STR = 0x00000005, |
| 131 | FF_MASK = 0x000000FF, |
| 132 | }; |
| 133 | |
| 134 | enum field_origin { |
| 135 | FO_METRIC = 0x00000000, |
| 136 | FO_STATUS = 0x00000100, |
| 137 | FO_KEY = 0x00000200, |
| 138 | FO_CONFIG = 0x00000300, |
| 139 | FO_PRODUCT = 0x00000400, |
| 140 | FO_MASK = 0x0000FF00, |
| 141 | }; |
| 142 | |
| 143 | enum field_nature { |
| 144 | FN_GAUGE = 0x00000000, |
| 145 | FN_LIMIT = 0x00010000, |
| 146 | FN_MIN = 0x00020000, |
| 147 | FN_MAX = 0x00030000, |
| 148 | FN_RATE = 0x00040000, |
| 149 | FN_COUNTER = 0x00050000, |
| 150 | FN_DURATION = 0x00060000, |
| 151 | FN_AGE = 0x00070000, |
| 152 | FN_TIME = 0x00080000, |
| 153 | FN_NAME = 0x00090000, |
| 154 | FN_OUTPUT = 0x000A0000, |
| 155 | FN_AVG = 0x000B0000, |
| 156 | FN_MASK = 0x00FF0000, |
| 157 | }; |
| 158 | |
| 159 | enum field_scope { |
| 160 | FS_PROCESS = 0x00000000, |
| 161 | FS_SERVICE = 0x01000000, |
| 162 | FS_SYSTEM = 0x02000000, |
| 163 | FS_CLUSTER = 0x03000000, |
| 164 | FS_MASK = 0xFF000000, |
| 165 | }; |
| 166 | |
| 167 | struct field { |
| 168 | uint32_t type; |
| 169 | union { |
| 170 | int32_t s32; /* FF_S32 */ |
| 171 | uint32_t u32; /* FF_U32 */ |
| 172 | int64_t s64; /* FF_S64 */ |
| 173 | uint64_t u64; /* FF_U64 */ |
| 174 | const char *str; /* FF_STR */ |
| 175 | } u; |
| 176 | }; |
| 177 | |
| 178 | static inline enum field_format field_format(const struct field *f, int e) |
| 179 | { |
| 180 | return f[e].type & FF_MASK; |
| 181 | } |
| 182 | |
| 183 | static inline enum field_origin field_origin(const struct field *f, int e) |
| 184 | { |
| 185 | return f[e].type & FO_MASK; |
| 186 | } |
| 187 | |
| 188 | static inline enum field_scope field_scope(const struct field *f, int e) |
| 189 | { |
| 190 | return f[e].type & FS_MASK; |
| 191 | } |
| 192 | |
| 193 | static inline enum field_nature field_nature(const struct field *f, int e) |
| 194 | { |
| 195 | return f[e].type & FN_MASK; |
| 196 | } |
| 197 | |
| 198 | static inline const char *field_str(const struct field *f, int e) |
| 199 | { |
| 200 | return (field_format(f, e) == FF_STR) ? f[e].u.str : ""; |
| 201 | } |
| 202 | |
| 203 | static inline struct field mkf_s32(uint32_t type, int32_t value) |
| 204 | { |
| 205 | struct field f = { .type = FF_S32 | type, .u.s32 = value }; |
| 206 | return f; |
| 207 | } |
| 208 | |
| 209 | static inline struct field mkf_u32(uint32_t type, uint32_t value) |
| 210 | { |
| 211 | struct field f = { .type = FF_U32 | type, .u.u32 = value }; |
| 212 | return f; |
| 213 | } |
| 214 | |
| 215 | static inline struct field mkf_s64(uint32_t type, int64_t value) |
| 216 | { |
| 217 | struct field f = { .type = FF_S64 | type, .u.s64 = value }; |
| 218 | return f; |
| 219 | } |
| 220 | |
| 221 | static inline struct field mkf_u64(uint32_t type, uint64_t value) |
| 222 | { |
| 223 | struct field f = { .type = FF_U64 | type, .u.u64 = value }; |
| 224 | return f; |
| 225 | } |
| 226 | |
| 227 | static inline struct field mkf_str(uint32_t type, const char *value) |
| 228 | { |
| 229 | struct field f = { .type = FF_STR | type, .u.str = value }; |
| 230 | return f; |
| 231 | } |
| 232 | |
Willy Tarreau | 3057645 | 2015-04-13 13:50:30 +0200 | [diff] [blame] | 233 | extern struct applet http_stats_applet; |
Willy Tarreau | b1356cf | 2008-12-07 16:06:43 +0100 | [diff] [blame] | 234 | |
Willy Tarreau | 9a42c0d | 2009-09-22 19:31:03 +0200 | [diff] [blame] | 235 | void stats_io_handler(struct stream_interface *si); |
Willy Tarreau | b47785f | 2016-02-24 23:28:31 +0100 | [diff] [blame] | 236 | int stats_emit_raw_data_field(struct chunk *out, const struct field *f); |
| 237 | int stats_emit_typed_data_field(struct chunk *out, const struct field *f); |
| 238 | int stats_emit_field_tags(struct chunk *out, const struct field *f, char delim); |
Willy Tarreau | 9186126 | 2007-10-17 17:06:05 +0200 | [diff] [blame] | 239 | |
| 240 | |
| 241 | #endif /* _PROTO_DUMPSTATS_H */ |
| 242 | |
| 243 | /* |
| 244 | * Local variables: |
| 245 | * c-indent-level: 8 |
| 246 | * c-basic-offset: 8 |
| 247 | * End: |
| 248 | */ |