enum openmetrics_metric_type {
OPENMETRICS_METRIC_TYPE_COUNT,
OPENMETRICS_METRIC_TYPE_DURATION,
+ OPENMETRICS_METRIC_TYPE_FIELD,
OPENMETRICS_METRIC_TYPE_HISTOGRAM,
};
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;
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);
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();
}
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();
}
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,
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_");
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;
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;
/* 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;
}
}