102 lines
2.3 KiB
V
102 lines
2.3 KiB
V
module metrics
|
|
|
|
import strings
|
|
import io
|
|
|
|
pub struct PrometheusExporter {
|
|
mut:
|
|
prefix string
|
|
collector &MetricsCollector = unsafe { nil }
|
|
}
|
|
|
|
pub fn new_prometheus_exporter() PrometheusExporter {
|
|
return PrometheusExporter{}
|
|
}
|
|
|
|
pub fn (mut e PrometheusExporter) load(prefix string, collector &MetricsCollector) {
|
|
unsafe {
|
|
e.collector = collector
|
|
}
|
|
e.prefix = prefix
|
|
}
|
|
|
|
[inline]
|
|
fn join_two_array(arr [2]string) string {
|
|
return '${arr[0]}="${arr[1]}"'
|
|
}
|
|
|
|
pub fn (e &PrometheusExporter) serialize_metric(metric Metric) string {
|
|
if metric.labels.len == 0 {
|
|
return '$e.prefix$metric.name'
|
|
}
|
|
|
|
return '$e.prefix$metric.name{${metric.labels.map(join_two_array(it)).join(',')}}'
|
|
}
|
|
|
|
pub fn (mut e PrometheusExporter) export_to_string() !string {
|
|
mut builder := strings.new_builder(64)
|
|
|
|
e.export_to_writer(mut builder)!
|
|
|
|
return builder.str()
|
|
}
|
|
|
|
pub fn (mut e PrometheusExporter) export_to_writer(mut writer io.Writer) ! {
|
|
for counter in e.collector.counters() {
|
|
val := e.collector.counter_get(counter) or { return error("This can't happen.") }
|
|
line := '${e.serialize_metric(counter)} $val\n'
|
|
|
|
writer.write(line.bytes())!
|
|
}
|
|
|
|
for gauge in e.collector.gauges() {
|
|
val := e.collector.gauge_get(gauge) or { return error("This can't happen.") }
|
|
line := '${e.serialize_metric(gauge)} $val\n'
|
|
|
|
writer.write(line.bytes())!
|
|
}
|
|
|
|
for hist in e.collector.histograms() {
|
|
hist_data := e.collector.histogram_get(hist) or { return error("This can't happen.") }
|
|
|
|
mut m := Metric{
|
|
...hist
|
|
name: '${hist.name}_count'
|
|
}
|
|
writer.write('${e.serialize_metric(m)} $hist_data.total_count\n'.bytes())!
|
|
|
|
m = Metric{
|
|
...hist
|
|
name: '${hist.name}_sum'
|
|
}
|
|
writer.write('${e.serialize_metric(m)} $hist_data.sum\n'.bytes())!
|
|
|
|
mut le_labels := [][2]string{}
|
|
le_labels.prepend(hist.labels)
|
|
le_labels << ['le', '']!
|
|
|
|
for j, bucket in hist_data.buckets {
|
|
le_labels[le_labels.len - 1][1] = bucket.str()
|
|
|
|
m = Metric{
|
|
name: '${hist.name}_bucket'
|
|
labels: le_labels
|
|
}
|
|
|
|
writer.write('${e.serialize_metric(m)} ${hist_data.bucket_counts[j]}\n'.bytes())!
|
|
}
|
|
|
|
// Always output the +Inf bucket
|
|
le_labels[le_labels.len - 1][1] = '+Inf'
|
|
|
|
if hist_data.buckets.len > 0 {
|
|
m = Metric{
|
|
name: '${hist.name}_bucket'
|
|
labels: le_labels
|
|
}
|
|
|
|
writer.write('${e.serialize_metric(m)} $hist_data.total_count\n'.bytes())!
|
|
}
|
|
}
|
|
}
|