From: Aki Tuomi Date: Thu, 26 Jan 2023 06:15:29 +0000 (+0200) Subject: stats: openmetrics - Create metrics for all specified fields X-Git-Tag: 2.3.21~94 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8aef0ce5eab28422ea75da9f47809d20acab367d;p=thirdparty%2Fdovecot%2Fcore.git stats: openmetrics - Create metrics for all specified fields --- diff --git a/src/stats/stats-service-openmetrics.c b/src/stats/stats-service-openmetrics.c index c286c67d53..f149894f75 100644 --- a/src/stats/stats-service-openmetrics.c +++ b/src/stats/stats-service-openmetrics.c @@ -28,6 +28,7 @@ enum openmetrics_metric_type { OPENMETRICS_METRIC_TYPE_COUNT, OPENMETRICS_METRIC_TYPE_DURATION, + OPENMETRICS_METRIC_TYPE_FIELD, OPENMETRICS_METRIC_TYPE_HISTOGRAM, }; @@ -55,6 +56,7 @@ struct openmetrics_request { enum openmetrics_metric_type metric_type; string_t *labels; size_t labels_pos; + unsigned int field_pos; ARRAY(struct openmetrics_request_sub_metric) sub_metric_stack; bool has_submetric:1; @@ -118,6 +120,7 @@ static void openmetrics_export_metric_value(struct openmetrics_request *req, string_t *out, const struct metric *metric) { + const struct metric_field *field; /* Metric name */ str_append(out, "dovecot_"); str_append(out, req->metric->name); @@ -134,6 +137,13 @@ openmetrics_export_metric_value(struct openmetrics_request *req, string_t *out, else str_append(out, "_duration_seconds_total"); break; + case OPENMETRICS_METRIC_TYPE_FIELD: + field = &metric->fields[req->field_pos]; + if (req->metric->group_by != NULL && str_len(req->labels) == 0) + str_printfa(out, "_%s_sum", field->field_key); + else + str_printfa(out, "_%s_total", field->field_key); + break; case OPENMETRICS_METRIC_TYPE_HISTOGRAM: i_unreached(); } @@ -154,6 +164,10 @@ openmetrics_export_metric_value(struct openmetrics_request *req, string_t *out, str_printfa(out, " %.6f\n", stats_dist_get_sum(metric->duration_stats)/1e6F); break; + case OPENMETRICS_METRIC_TYPE_FIELD: + str_printfa(out, " %"PRIu64"\n", + stats_dist_get_sum(field->stats)); + break; case OPENMETRICS_METRIC_TYPE_HISTOGRAM: i_unreached(); } @@ -222,8 +236,7 @@ openmetrics_export_histogram(struct openmetrics_request *req, string_t *out, if (sub_metric != NULL) { sum += stats_dist_get_sum(sub_metric->duration_stats); - count += stats_dist_get_count( - sub_metric->duration_stats); + count += stats_dist_get_count(sub_metric->duration_stats); } openmetrics_export_histogram_bucket(req, out, metric, @@ -270,6 +283,7 @@ static void openmetrics_export_metric_header(struct openmetrics_request *req, string_t *out) { const struct metric *metric = req->metric; + const struct metric_field *field; /* Description */ str_append(out, "# HELP dovecot_"); @@ -281,6 +295,11 @@ openmetrics_export_metric_header(struct openmetrics_request *req, string_t *out) case OPENMETRICS_METRIC_TYPE_DURATION: str_append(out, "_duration_seconds Total duration of all events of this kind"); break; + case OPENMETRICS_METRIC_TYPE_FIELD: + field = &metric->fields[req->field_pos]; + str_printfa(out, "_%s Total of field value for events of this kind", + field->field_key); + break; case OPENMETRICS_METRIC_TYPE_HISTOGRAM: str_append(out, " Histogram"); break; @@ -300,6 +319,9 @@ openmetrics_export_metric_header(struct openmetrics_request *req, string_t *out) case OPENMETRICS_METRIC_TYPE_DURATION: str_append(out, "_duration_seconds counter\n"); break; + case OPENMETRICS_METRIC_TYPE_FIELD: + str_printfa(out, "_%s counter\n", field->field_key); + break; case OPENMETRICS_METRIC_TYPE_HISTOGRAM: str_append(out, " histogram\n"); break; @@ -540,14 +562,35 @@ static void openmetrics_export_next(struct openmetrics_request *req) /* Continue with histogram output for this metric. */ req->metric_type = OPENMETRICS_METRIC_TYPE_HISTOGRAM; req->state = OPENMETRICS_REQUEST_STATE_METRIC_HEADER; + } else if (req->metric->fields_count > 0) { + req->field_pos = 0; + req->metric_type = OPENMETRICS_METRIC_TYPE_FIELD; + req->state = OPENMETRICS_REQUEST_STATE_METRIC_HEADER; } else { /* No histogram; continue with next metric */ req->state = OPENMETRICS_REQUEST_STATE_METRIC; } break; + case OPENMETRICS_METRIC_TYPE_FIELD: + req->field_pos++; + if (req->field_pos < req->metric->fields_count) { + req->metric_type = OPENMETRICS_METRIC_TYPE_FIELD; + req->state = OPENMETRICS_REQUEST_STATE_METRIC_HEADER; + } else { + /* all fields consumed */ + req->state = OPENMETRICS_REQUEST_STATE_METRIC; + } + break; case OPENMETRICS_METRIC_TYPE_HISTOGRAM: - /* Continue with next metric */ - req->state = OPENMETRICS_REQUEST_STATE_METRIC; + if (req->metric->fields_count > 0) { + /* Continue with fields */ + req->field_pos = 0; + req->metric_type = OPENMETRICS_METRIC_TYPE_FIELD; + req->state = OPENMETRICS_REQUEST_STATE_METRIC_HEADER; + } else { + /* Continue with next metric */ + req->state = OPENMETRICS_REQUEST_STATE_METRIC; + } break; } }