refactor: simplify design; create metrics on first use

mem-usage
Jef Roosens 2022-12-27 09:03:41 +01:00
parent 80de5ba437
commit a744c02df4
5 changed files with 86 additions and 85 deletions

View File

@ -1,16 +1,15 @@
module metrics module metrics
import sync.stdatomic
struct Counter { struct Counter {
metric Metric metric Metric
mut:
data u64 data u64
} }
struct FloatSeries { struct FloatSeries {
metric Metric metric Metric
pub mut: pub mut:
data shared []f64 data []f64
} }
[heap] [heap]
@ -29,20 +28,35 @@ pub fn new_default_collector() &DefaultCollector {
} }
} }
pub fn (mut c DefaultCollector) counter_register(value u64, metric Metric) { pub fn (mut c DefaultCollector) counter_increment(metric Metric) {
lock c.counters { lock c.counters {
c.counters[metric.str()] = &Counter{ mut entry := c.counters[metric.str()] or {
counter := &Counter{
metric: metric metric: metric
data: value data: 0
} }
c.counters[metric.str()] = counter
counter
}
entry.data += 1
} }
} }
pub fn (c &DefaultCollector) counter_increment(metric Metric) { pub fn (mut c DefaultCollector) counter_set(value u64, metric Metric) {
rlock c.counters { lock c.counters {
entry := c.counters[metric.str()] mut entry := c.counters[metric.str()] or {
counter := &Counter{
metric: metric
data: 0
}
c.counters[metric.str()] = counter
stdatomic.add_u64(&entry.data, 1) counter
}
entry.data = value
} }
} }
@ -50,7 +64,7 @@ pub fn (c &DefaultCollector) counter_get(metric Metric) ?u64 {
return rlock c.counters { return rlock c.counters {
entry := c.counters[metric.str()] or { return none } entry := c.counters[metric.str()] or { return none }
stdatomic.load_u64(&entry.data) entry.data
} }
} }
@ -66,82 +80,87 @@ pub fn (c &DefaultCollector) counters() []Metric {
return metrics return metrics
} }
pub fn (mut c DefaultCollector) histogram_register(metric Metric) { pub fn (c &DefaultCollector) histogram_record(value f64, metric Metric) {
lock c.histograms { lock c.histograms {
c.histograms[metric.str()] = &FloatSeries{ mut entry := c.histograms[metric.str()] or {
hist := &FloatSeries{
metric: metric metric: metric
data: []f64{} data: []f64{}
} }
} c.histograms[metric.str()] = hist
hist
} }
pub fn (c &DefaultCollector) histogram_record(value f64, metric Metric) {
entry := rlock c.histograms {
c.histograms[metric.str()]
}
lock entry.data {
entry.data << value entry.data << value
} }
} }
pub fn (c &DefaultCollector) histogram_get(metric Metric) ?[]f64 { pub fn (c &DefaultCollector) histogram_get(metric Metric) ?[]f64 {
entry := rlock c.histograms { return rlock c.histograms {
c.histograms[metric.str()] or { return none } entry := c.histograms[metric.str()] or { return none }
}
return rlock entry.data {
// Return a clone of the data to prevent user from altering // Return a clone of the data to prevent user from altering
// internal structure // internal structure
entry.data.clone() entry.data.clone()
} }
} }
pub fn (mut c DefaultCollector) gauge_register(value f64, metric Metric) { pub fn (mut c DefaultCollector) gauge_add(value f64, metric Metric) {
lock c.gauges { lock c.gauges {
c.gauges[metric.str()] = &FloatSeries{ mut entry := c.gauges[metric.str()] or {
gauge := &FloatSeries{
metric: metric metric: metric
data: [value] data: [0.0]
}
}
} }
pub fn (c &DefaultCollector) gauge_add(value f64, metric Metric) { c.gauges[metric.str()] = gauge
entry := rlock c.gauges {
c.gauges[metric.str()] gauge
} }
lock entry.data {
entry.data[0] += value entry.data[0] += value
} }
} }
pub fn (c &DefaultCollector) gauge_sub(value f64, metric Metric) { pub fn (mut c DefaultCollector) gauge_sub(value f64, metric Metric) {
entry := rlock c.gauges { lock c.gauges {
c.gauges[metric.str()] mut entry := c.gauges[metric.str()] or {
gauge := &FloatSeries{
metric: metric
data: [0.0]
}
c.gauges[metric.str()] = gauge
gauge
} }
lock entry.data {
entry.data[0] -= value entry.data[0] -= value
} }
} }
pub fn (c &DefaultCollector) gauge_set(value f64, metric Metric) { pub fn (mut c DefaultCollector) gauge_set(value f64, metric Metric) {
entry := rlock c.gauges { lock c.gauges {
c.gauges[metric.str()] mut entry := c.gauges[metric.str()] or {
gauge := &FloatSeries{
metric: metric
data: [0.0]
}
c.gauges[metric.str()] = gauge
gauge
} }
lock entry.data {
entry.data[0] = value entry.data[0] = value
} }
} }
pub fn (c &DefaultCollector) gauge_get(metric Metric) ?f64 { pub fn (c &DefaultCollector) gauge_get(metric Metric) ?f64 {
entry := rlock c.gauges { return rlock c.gauges {
c.gauges[metric.str()] entry := c.gauges[metric.str()] or { return none }
}
return rlock entry.data {
entry.data[0] entry.data[0]
} }
} }

View File

@ -11,7 +11,6 @@ fn test_null_implements_interface() {
fn test_counter_increment() { fn test_counter_increment() {
mut m := new_default_collector() mut m := new_default_collector()
m.counter_register(0, name: 'test')
m.counter_increment(name: 'test') m.counter_increment(name: 'test')
assert m.counter_get(name: 'test')? == u64(1) assert m.counter_get(name: 'test')? == u64(1)
@ -24,7 +23,7 @@ fn test_counter_increment() {
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.counter_register(15, metric) m.counter_set(15, metric)
m.counter_increment(metric) m.counter_increment(metric)
assert m.counter_get(metric)? == u64(16) assert m.counter_get(metric)? == u64(16)
} }
@ -32,7 +31,6 @@ fn test_counter_increment() {
fn test_histogram() { fn test_histogram() {
mut m := new_default_collector() mut m := new_default_collector()
m.histogram_register(name: 'test')
m.histogram_record(5.0, name: 'test') m.histogram_record(5.0, name: 'test')
assert m.histogram_get(name: 'test')? == [5.0] assert m.histogram_get(name: 'test')? == [5.0]
@ -45,7 +43,6 @@ fn test_histogram() {
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.histogram_register(metric)
m.histogram_record(5.0, metric) m.histogram_record(5.0, metric)
assert m.histogram_get(metric)? == [5.0] assert m.histogram_get(metric)? == [5.0]
@ -56,7 +53,6 @@ fn test_histogram() {
fn test_gauge_add() { fn test_gauge_add() {
mut m := new_default_collector() mut m := new_default_collector()
m.gauge_register(0.0, name: 'test')
m.gauge_add(5.0, name: 'test') m.gauge_add(5.0, name: 'test')
assert m.gauge_get(name: 'test')? == 5.0 assert m.gauge_get(name: 'test')? == 5.0
@ -66,7 +62,7 @@ fn test_gauge_add() {
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.gauge_register(3.0, metric) m.gauge_set(3.0, metric)
m.gauge_add(5.0, metric) m.gauge_add(5.0, metric)
assert m.gauge_get(metric)? == 8.0 assert m.gauge_get(metric)? == 8.0
} }
@ -74,7 +70,6 @@ fn test_gauge_add() {
fn test_gauge_sub() { fn test_gauge_sub() {
mut m := new_default_collector() mut m := new_default_collector()
m.gauge_register(0.0, name: 'test')
m.gauge_sub(5.0, name: 'test') m.gauge_sub(5.0, name: 'test')
assert m.gauge_get(name: 'test')? == -5.0 assert m.gauge_get(name: 'test')? == -5.0
@ -84,7 +79,7 @@ fn test_gauge_sub() {
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.gauge_register(3.0, metric) m.gauge_set(3.0, metric)
m.gauge_sub(5.0, metric) m.gauge_sub(5.0, metric)
assert m.gauge_get(metric)? == -2.0 assert m.gauge_get(metric)? == -2.0
} }
@ -92,7 +87,6 @@ fn test_gauge_sub() {
fn test_gauge_set() { fn test_gauge_set() {
mut m := new_default_collector() mut m := new_default_collector()
m.gauge_register(0.0, name: 'test')
m.gauge_set(3.0, name: 'test') m.gauge_set(3.0, name: 'test')
assert m.gauge_get(name: 'test')? == 3.0 assert m.gauge_get(name: 'test')? == 3.0
m.gauge_set(5.0, name: 'test') m.gauge_set(5.0, name: 'test')
@ -104,7 +98,6 @@ fn test_gauge_set() {
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.gauge_register(0.0, metric)
m.gauge_set(3.0, metric) m.gauge_set(3.0, metric)
assert m.gauge_get(metric)? == 3.0 assert m.gauge_get(metric)? == 3.0
m.gauge_set(5.0, metric) m.gauge_set(5.0, metric)

View File

@ -22,21 +22,19 @@ pub fn (m &Metric) str() string {
} }
pub interface MetricsCollector { pub interface MetricsCollector {
counter_increment(metric Metric)
counter_get(metric Metric) ?u64 counter_get(metric Metric) ?u64
counters() []Metric counters() []Metric
histogram_record(value f64, metric Metric)
histogram_get(metric Metric) ?[]f64 histogram_get(metric Metric) ?[]f64
histograms() []Metric histograms() []Metric
gauge_add(value f64, metric Metric)
gauge_sub(value f64, metric Metric)
gauge_set(value f64, metric Metric)
gauge_get(metric Metric) ?f64 gauge_get(metric Metric) ?f64
gauges() []Metric gauges() []Metric
mut: mut:
counter_register(value u64, metric Metric) counter_set(val u64, metric Metric)
histogram_register(metric Metric) counter_increment(metric Metric)
gauge_register(value f64, metric Metric) histogram_record(value f64, metric Metric)
gauge_set(value f64, metric Metric)
gauge_add(value f64, metric Metric)
gauge_sub(value f64, metric Metric)
} }
pub interface MetricsExporter { pub interface MetricsExporter {

8
null.v
View File

@ -7,10 +7,10 @@ pub fn new_null_collector() &NullCollector {
return &NullCollector{} return &NullCollector{}
} }
pub fn (c &NullCollector) counter_register(value u64, metric Metric) {}
pub fn (c &NullCollector) counter_increment(metric Metric) {} pub fn (c &NullCollector) counter_increment(metric Metric) {}
pub fn (c &NullCollector) counter_set(value u64, metric Metric) {}
pub fn (c &NullCollector) counter_get(metric Metric) ?u64 { pub fn (c &NullCollector) counter_get(metric Metric) ?u64 {
return none return none
} }
@ -19,16 +19,12 @@ pub fn (c &NullCollector) counters() []Metric {
return [] return []
} }
pub fn (c &NullCollector) histogram_register(metric Metric) {}
pub fn (c &NullCollector) histogram_record(value f64, metric Metric) {} pub fn (c &NullCollector) histogram_record(value f64, metric Metric) {}
pub fn (c &NullCollector) histogram_get(metric Metric) ?[]f64 { pub fn (c &NullCollector) histogram_get(metric Metric) ?[]f64 {
return none return none
} }
pub fn (c &NullCollector) gauge_register(value f64, metric Metric) {}
pub fn (c &NullCollector) gauge_add(value f64, metric Metric) {} pub fn (c &NullCollector) gauge_add(value f64, metric Metric) {}
pub fn (c &NullCollector) gauge_sub(value f64, metric Metric) {} pub fn (c &NullCollector) gauge_sub(value f64, metric Metric) {}

View File

@ -2,7 +2,6 @@ module metrics
fn test_only_counters() { fn test_only_counters() {
mut m := new_default_collector() mut m := new_default_collector()
m.counter_register(0, name: 'test')
m.counter_increment(name: 'test') m.counter_increment(name: 'test')
mut e := new_prometheus_exporter([]) mut e := new_prometheus_exporter([])
@ -14,7 +13,6 @@ fn test_only_counters() {
name: 'test2' name: 'test2'
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.counter_register(0, metric)
m.counter_increment(metric) m.counter_increment(metric)
m.counter_increment(metric) m.counter_increment(metric)
@ -23,7 +21,6 @@ fn test_only_counters() {
fn test_only_gauges() { fn test_only_gauges() {
mut m := new_default_collector() mut m := new_default_collector()
m.gauge_register(0.0, name: 'test')
m.gauge_set(3.25, name: 'test') m.gauge_set(3.25, name: 'test')
mut e := new_prometheus_exporter([]) mut e := new_prometheus_exporter([])
@ -35,7 +32,6 @@ fn test_only_gauges() {
name: 'test2' name: 'test2'
labels: [['hi', 'label']!, ['hi2', 'label2']!] labels: [['hi', 'label']!, ['hi2', 'label2']!]
} }
m.gauge_register(0.0, metric)
m.gauge_add(2.5, metric) m.gauge_add(2.5, metric)
assert e.export_to_string()! == 'test 3.25\ntest2{hi="label",hi2="label2"} 2.5\n' assert e.export_to_string()! == 'test 3.25\ntest2{hi="label",hi2="label2"} 2.5\n'
@ -44,7 +40,6 @@ fn test_only_gauges() {
fn test_single_histogram() { fn test_single_histogram() {
mut m := new_default_collector() mut m := new_default_collector()
m.histogram_register(name: 'test')
m.histogram_record(5.0, name: 'test') m.histogram_record(5.0, name: 'test')
mut e := new_prometheus_exporter([0.5, 5.0]) mut e := new_prometheus_exporter([0.5, 5.0])