MINOR: stats: prepare stats-file support for values other than FN_COUNTER
Currently, only FN_COUNTER are dumped and preloaded via a stats-file. Thus in several places we relied on the assumption that only FN_COUNTER are valid in stats-file context. New stats types will soon be implemented as they are also eligilible to statistics reloading on process startup. Thus, prepare stats-file functions to remove any FN_COUNTER restriction. As one of this change, generate_stat_tree() now uses stcol_is_generic() for stats name tree indexing before stats-file parsing. Also related to stats-file parsing, individual counter preloading step as been extracted from line parsing in a dedicated new function load_ctr(). This will allow to extend it to support multiple mechanism of counter preloading depending on the stats type.
This commit is contained in:
parent
933b4ae27d
commit
4e9e841878
@ -74,6 +74,12 @@ int stats_emit_field_tags(struct buffer *out, const struct field *f,
|
|||||||
char delim);
|
char delim);
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns true if <col> is fully defined, false if only used as name-desc. */
|
||||||
|
static inline int stcol_is_generic(const struct stat_col *col)
|
||||||
|
{
|
||||||
|
return !!(col->cap);
|
||||||
|
}
|
||||||
|
|
||||||
static inline enum field_format stcol_format(const struct stat_col *col)
|
static inline enum field_format stcol_format(const struct stat_col *col)
|
||||||
{
|
{
|
||||||
return col->type & FF_MASK;
|
return col->type & FF_MASK;
|
||||||
|
@ -85,16 +85,20 @@ void stats_dump_file_header(int type, struct buffer *out)
|
|||||||
chunk_strcat(out, "#fe guid,");
|
chunk_strcat(out, "#fe guid,");
|
||||||
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
||||||
col = &stat_cols_px[i];
|
col = &stat_cols_px[i];
|
||||||
if (stcol_nature(col) == FN_COUNTER && (col->cap & (STATS_PX_CAP_FE|STATS_PX_CAP_LI)))
|
if (stcol_is_generic(col) &&
|
||||||
|
col->cap & (STATS_PX_CAP_FE|STATS_PX_CAP_LI)) {
|
||||||
chunk_appendf(out, "%s,", col->name);
|
chunk_appendf(out, "%s,", col->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
chunk_appendf(out, "#be guid,");
|
chunk_appendf(out, "#be guid,");
|
||||||
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
||||||
col = &stat_cols_px[i];
|
col = &stat_cols_px[i];
|
||||||
if (stcol_nature(col) == FN_COUNTER && (col->cap & (STATS_PX_CAP_BE|STATS_PX_CAP_SRV)))
|
if (stcol_is_generic(col) &&
|
||||||
|
col->cap & (STATS_PX_CAP_BE|STATS_PX_CAP_SRV)) {
|
||||||
chunk_appendf(out, "%s,", col->name);
|
chunk_appendf(out, "%s,", col->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +193,44 @@ static int parse_header_line(struct ist header, struct eb_root *st_tree,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Preload an individual counter instance stored at <counter> with <token>
|
||||||
|
* value> for the <col> stat column.
|
||||||
|
*
|
||||||
|
* Returns 0 on success else non-zero if counter was not updated.
|
||||||
|
*/
|
||||||
|
static int load_ctr(const struct stat_col *col, const struct ist token,
|
||||||
|
void* counter)
|
||||||
|
{
|
||||||
|
const enum field_nature fn = stcol_nature(col);
|
||||||
|
const enum field_format ff = stcol_format(col);
|
||||||
|
const char *ptr = istptr(token);
|
||||||
|
struct field value;
|
||||||
|
|
||||||
|
switch (ff) {
|
||||||
|
case FF_U64:
|
||||||
|
value.u.u64 = read_uint64(&ptr, istend(token));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Unsupported field nature. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do not load value if non numeric characters present. */
|
||||||
|
if (ptr != istend(token))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (fn == FN_COUNTER && ff == FF_U64) {
|
||||||
|
*(uint64_t *)counter = value.u.u64;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Unsupported field format/nature combination. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a non header stats-file line <line>. Specify current parsing <domain>
|
/* Parse a non header stats-file line <line>. Specify current parsing <domain>
|
||||||
* and <cols> stats column matrix derived from the last header line.
|
* and <cols> stats column matrix derived from the last header line.
|
||||||
*
|
*
|
||||||
@ -269,7 +311,6 @@ static int parse_stat_line(struct ist line,
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (istlen(line) && i < STAT_FILE_MAX_COL_COUNT) {
|
while (istlen(line) && i < STAT_FILE_MAX_COL_COUNT) {
|
||||||
const struct stat_col *col = cols[i++];
|
const struct stat_col *col = cols[i++];
|
||||||
enum field_format ff;
|
|
||||||
|
|
||||||
token = istsplit(&line, ',');
|
token = istsplit(&line, ',');
|
||||||
if (!istlen(token))
|
if (!istlen(token))
|
||||||
@ -278,19 +319,7 @@ static int parse_stat_line(struct ist line,
|
|||||||
if (!col)
|
if (!col)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ff = stcol_format(col);
|
load_ctr(col, token, base_off + col->metric.offset[off]);
|
||||||
if (ff == FF_U64) {
|
|
||||||
uint64_t *offset, value;
|
|
||||||
const char *ptr;
|
|
||||||
|
|
||||||
ptr = istptr(token);
|
|
||||||
value = read_uint64(&ptr, istend(token));
|
|
||||||
/* Do not load value if non numeric characters present. */
|
|
||||||
if (ptr == istend(token)) {
|
|
||||||
offset = (uint64_t *)(base_off + col->metric.offset[off]);
|
|
||||||
*offset = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
31
src/stats.c
31
src/stats.c
@ -92,12 +92,6 @@
|
|||||||
.cap = (cap_f), \
|
.cap = (cap_f), \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if <col> is fully defined, false if only used as name-desc. */
|
|
||||||
static int stcol_is_generic(const struct stat_col *col)
|
|
||||||
{
|
|
||||||
return !!(col->cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert stat_col <col> to old-style <name> as name_desc. */
|
/* Convert stat_col <col> to old-style <name> as name_desc. */
|
||||||
static void stcol2ndesc(struct name_desc *name, const struct stat_col *col)
|
static void stcol2ndesc(struct name_desc *name, const struct stat_col *col)
|
||||||
{
|
{
|
||||||
@ -338,7 +332,7 @@ 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. */
|
/* Insert <cols> generic stat columns into <st_tree> indexed by their name. */
|
||||||
int generate_stat_tree(struct eb_root *st_tree, const struct stat_col cols[])
|
int generate_stat_tree(struct eb_root *st_tree, const struct stat_col cols[])
|
||||||
{
|
{
|
||||||
const struct stat_col *col;
|
const struct stat_col *col;
|
||||||
@ -348,7 +342,8 @@ int generate_stat_tree(struct eb_root *st_tree, const struct stat_col cols[])
|
|||||||
|
|
||||||
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
for (i = 0; i < ST_I_PX_MAX; ++i) {
|
||||||
col = &cols[i];
|
col = &cols[i];
|
||||||
if (stcol_nature(col) == FN_COUNTER) {
|
|
||||||
|
if (stcol_is_generic(col)) {
|
||||||
len = strlen(col->name);
|
len = strlen(col->name);
|
||||||
node = malloc(sizeof(struct stcol_node) + len + 1);
|
node = malloc(sizeof(struct stcol_node) + len + 1);
|
||||||
if (!node)
|
if (!node)
|
||||||
@ -739,6 +734,7 @@ static struct field me_generate_field(const struct stat_col *col,
|
|||||||
const void *counters, uint8_t cap,
|
const void *counters, uint8_t cap,
|
||||||
int stat_file)
|
int stat_file)
|
||||||
{
|
{
|
||||||
|
enum field_nature fn;
|
||||||
struct field value;
|
struct field value;
|
||||||
void *counter = NULL;
|
void *counter = NULL;
|
||||||
int wrong_side = 0;
|
int wrong_side = 0;
|
||||||
@ -794,12 +790,19 @@ static struct field me_generate_field(const struct stat_col *col,
|
|||||||
return (struct field){ .type = FF_EMPTY };
|
return (struct field){ .type = FF_EMPTY };
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (stcol_format(col)) {
|
fn = stcol_nature(col);
|
||||||
case FF_U64:
|
if (fn == FN_COUNTER) {
|
||||||
value = mkf_u64(stcol_nature(col), *(uint64_t *)counter);
|
switch (stcol_format(col)) {
|
||||||
break;
|
case FF_U64:
|
||||||
default:
|
value = mkf_u64(FN_COUNTER, *(uint64_t *)counter);
|
||||||
/* only FF_U64 counters currently use generic metric calculation */
|
break;
|
||||||
|
default:
|
||||||
|
/* only FF_U64 counters currently use generic metric calculation */
|
||||||
|
ABORT_NOW();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* No generic column available for other field nature. */
|
||||||
ABORT_NOW();
|
ABORT_NOW();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user