feat: added gauge type & some tests
parent
a1049943a4
commit
52fbf8ce5d
|
@ -0,0 +1,2 @@
|
||||||
|
*.c
|
||||||
|
*.so
|
91
collector.v
91
collector.v
|
@ -2,12 +2,12 @@ module metrics
|
||||||
|
|
||||||
import sync.stdatomic
|
import sync.stdatomic
|
||||||
|
|
||||||
struct CounterEntry {
|
struct Counter {
|
||||||
metric Metric
|
metric Metric
|
||||||
index int
|
data u64
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HistogramEntry {
|
struct FloatSeries {
|
||||||
metric Metric
|
metric Metric
|
||||||
pub mut:
|
pub mut:
|
||||||
data shared []f64
|
data shared []f64
|
||||||
|
@ -16,47 +16,41 @@ pub mut:
|
||||||
[heap]
|
[heap]
|
||||||
struct DefaultCollector {
|
struct DefaultCollector {
|
||||||
mut:
|
mut:
|
||||||
// The mutex for counters also applies to counter_indexes. Both data
|
counters shared map[string]&Counter
|
||||||
// structuress are only ever updated together. Note that only registering a
|
histograms shared map[string]&FloatSeries
|
||||||
// new metric actually changes these; all operations on already existing
|
gauges shared map[string]&FloatSeries
|
||||||
// metrics use atomic operations on the elements of the counters array.
|
|
||||||
counters shared []u64
|
|
||||||
counter_indexes map[string]CounterEntry
|
|
||||||
histograms shared map[string]HistogramEntry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_default_collector() &DefaultCollector {
|
pub fn new_default_collector() &DefaultCollector {
|
||||||
return &DefaultCollector{
|
return &DefaultCollector{
|
||||||
counters: []u64{}
|
counters: map[string]&Counter{}
|
||||||
counter_indexes: map[string]CounterEntry{}
|
histograms: map[string]&FloatSeries{}
|
||||||
histograms: map[string]HistogramEntry{}
|
gauges: map[string]&FloatSeries{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c DefaultCollector) counter_register(value u64, metric Metric) {
|
pub fn (mut c DefaultCollector) counter_register(value u64, metric Metric) {
|
||||||
lock c.counters {
|
lock c.counters {
|
||||||
c.counters << value
|
c.counters[metric.str()] = &Counter{
|
||||||
|
|
||||||
c.counter_indexes[metric.str()] = CounterEntry{
|
|
||||||
metric: metric
|
metric: metric
|
||||||
index: c.counters.len - 1
|
data: value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c &DefaultCollector) counter_increment(metric Metric) {
|
pub fn (c &DefaultCollector) counter_increment(metric Metric) {
|
||||||
rlock c.counters {
|
rlock c.counters {
|
||||||
entry := c.counter_indexes[metric.str()]
|
entry := c.counters[metric.str()]
|
||||||
|
|
||||||
stdatomic.add_u64(&c.counters[entry.index], 1)
|
stdatomic.add_u64(&entry.data, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c &DefaultCollector) counter_get(metric Metric) ?u64 {
|
pub fn (c &DefaultCollector) counter_get(metric Metric) ?u64 {
|
||||||
return rlock c.counters {
|
return rlock c.counters {
|
||||||
entry := c.counter_indexes[metric.str()] or { return none }
|
entry := c.counters[metric.str()] or { return none }
|
||||||
|
|
||||||
stdatomic.load_u64(&c.counters[entry.index])
|
stdatomic.load_u64(&entry.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +58,7 @@ pub fn (c &DefaultCollector) counters() []Metric {
|
||||||
mut metrics := []Metric{}
|
mut metrics := []Metric{}
|
||||||
|
|
||||||
rlock c.counters {
|
rlock c.counters {
|
||||||
for _, entry in c.counter_indexes {
|
for _, entry in c.counters {
|
||||||
metrics << entry.metric
|
metrics << entry.metric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,14 +68,14 @@ pub fn (c &DefaultCollector) counters() []Metric {
|
||||||
|
|
||||||
pub fn (mut c DefaultCollector) histogram_register(metric Metric) {
|
pub fn (mut c DefaultCollector) histogram_register(metric Metric) {
|
||||||
lock c.histograms {
|
lock c.histograms {
|
||||||
c.histograms[metric.str()] = HistogramEntry{
|
c.histograms[metric.str()] = &FloatSeries{
|
||||||
metric: metric
|
metric: metric
|
||||||
data: []f64{}
|
data: []f64{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c &DefaultCollector) histogram_add(value f64, metric Metric) {
|
pub fn (c &DefaultCollector) histogram_record(value f64, metric Metric) {
|
||||||
entry := rlock c.histograms {
|
entry := rlock c.histograms {
|
||||||
c.histograms[metric.str()]
|
c.histograms[metric.str()]
|
||||||
}
|
}
|
||||||
|
@ -102,3 +96,52 @@ pub fn (c &DefaultCollector) histogram_get(metric Metric) ?[]f64 {
|
||||||
entry.data.clone()
|
entry.data.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut c DefaultCollector) gauge_register(value f64, metric Metric) {
|
||||||
|
lock c.gauges {
|
||||||
|
c.gauges[metric.str()] = &FloatSeries{
|
||||||
|
metric: metric
|
||||||
|
data: [value]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (c &DefaultCollector) gauge_add(value f64, metric Metric) {
|
||||||
|
entry := rlock c.gauges {
|
||||||
|
c.gauges[metric.str()]
|
||||||
|
}
|
||||||
|
|
||||||
|
lock entry.data {
|
||||||
|
entry.data[0] += value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (c &DefaultCollector) gauge_sub(value f64, metric Metric) {
|
||||||
|
entry := rlock c.gauges {
|
||||||
|
c.gauges[metric.str()]
|
||||||
|
}
|
||||||
|
|
||||||
|
lock entry.data {
|
||||||
|
entry.data[0] -= value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (c &DefaultCollector) gauge_set(value f64, metric Metric) {
|
||||||
|
entry := rlock c.gauges {
|
||||||
|
c.gauges[metric.str()]
|
||||||
|
}
|
||||||
|
|
||||||
|
lock entry.data {
|
||||||
|
entry.data[0] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (c &DefaultCollector) gauge_get(metric Metric) ?f64 {
|
||||||
|
entry := rlock c.gauges {
|
||||||
|
c.gauges[metric.str()]
|
||||||
|
}
|
||||||
|
|
||||||
|
return rlock entry.data {
|
||||||
|
entry.data[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
module metrics
|
||||||
|
|
||||||
|
fn test_implements_interface() {
|
||||||
|
_ := MetricsCollector(new_default_collector())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_null_implements_interface() {
|
||||||
|
_ := MetricsCollector(new_null_collector())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_counter_increment() {
|
||||||
|
mut m := new_default_collector()
|
||||||
|
|
||||||
|
m.counter_register(0, name: 'test')
|
||||||
|
m.counter_increment(name: 'test')
|
||||||
|
assert m.counter_get(name: 'test')? == u64(1)
|
||||||
|
|
||||||
|
m.counter_increment(name: 'test')
|
||||||
|
assert m.counter_get(name: 'test')? == u64(2)
|
||||||
|
|
||||||
|
// Test with labels
|
||||||
|
metric := Metric{
|
||||||
|
name: 'test2'
|
||||||
|
labels: [['hi', 'label']!, ['hi2', 'label2']!]
|
||||||
|
}
|
||||||
|
|
||||||
|
m.counter_register(15, metric)
|
||||||
|
m.counter_increment(metric)
|
||||||
|
assert m.counter_get(metric)? == u64(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_histogram() {
|
||||||
|
mut m := new_default_collector()
|
||||||
|
|
||||||
|
m.histogram_register(name: 'test')
|
||||||
|
m.histogram_record(5.0, name: 'test')
|
||||||
|
assert m.histogram_get(name: 'test')? == [5.0]
|
||||||
|
|
||||||
|
m.histogram_record(7.0, name: 'test')
|
||||||
|
assert m.histogram_get(name: 'test')? == [5.0, 7.0]
|
||||||
|
|
||||||
|
// Test with labels
|
||||||
|
metric := Metric{
|
||||||
|
name: 'test2'
|
||||||
|
labels: [['hi', 'label']!, ['hi2', 'label2']!]
|
||||||
|
}
|
||||||
|
|
||||||
|
m.histogram_register(metric)
|
||||||
|
m.histogram_record(5.0, metric)
|
||||||
|
assert m.histogram_get(metric)? == [5.0]
|
||||||
|
|
||||||
|
m.histogram_record(7.0, metric)
|
||||||
|
assert m.histogram_get(metric)? == [5.0, 7.0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_gauge_add() {
|
||||||
|
mut m := new_default_collector()
|
||||||
|
|
||||||
|
m.gauge_register(0.0, name: 'test')
|
||||||
|
m.gauge_add(5.0, name: 'test')
|
||||||
|
assert m.gauge_get(name: 'test')? == 5.0
|
||||||
|
|
||||||
|
// Test with labels
|
||||||
|
metric := Metric{
|
||||||
|
name: 'test2'
|
||||||
|
labels: [['hi', 'label']!, ['hi2', 'label2']!]
|
||||||
|
}
|
||||||
|
|
||||||
|
m.gauge_register(3.0, metric)
|
||||||
|
m.gauge_add(5.0, metric)
|
||||||
|
assert m.gauge_get(metric)? == 8.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_gauge_sub() {
|
||||||
|
mut m := new_default_collector()
|
||||||
|
|
||||||
|
m.gauge_register(0.0, name: 'test')
|
||||||
|
m.gauge_sub(5.0, name: 'test')
|
||||||
|
assert m.gauge_get(name: 'test')? == -5.0
|
||||||
|
|
||||||
|
// Test with labels
|
||||||
|
metric := Metric{
|
||||||
|
name: 'test2'
|
||||||
|
labels: [['hi', 'label']!, ['hi2', 'label2']!]
|
||||||
|
}
|
||||||
|
|
||||||
|
m.gauge_register(3.0, metric)
|
||||||
|
m.gauge_sub(5.0, metric)
|
||||||
|
assert m.gauge_get(metric)? == -2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_gauge_set() {
|
||||||
|
mut m := new_default_collector()
|
||||||
|
|
||||||
|
m.gauge_register(0.0, name: 'test')
|
||||||
|
m.gauge_set(3.0, name: 'test')
|
||||||
|
assert m.gauge_get(name: 'test')? == 3.0
|
||||||
|
m.gauge_set(5.0, name: 'test')
|
||||||
|
assert m.gauge_get(name: 'test')? == 5.0
|
||||||
|
|
||||||
|
// Test with labels
|
||||||
|
metric := Metric{
|
||||||
|
name: 'test2'
|
||||||
|
labels: [['hi', 'label']!, ['hi2', 'label2']!]
|
||||||
|
}
|
||||||
|
|
||||||
|
m.gauge_register(0.0, metric)
|
||||||
|
m.gauge_set(3.0, metric)
|
||||||
|
assert m.gauge_get(metric)? == 3.0
|
||||||
|
m.gauge_set(5.0, metric)
|
||||||
|
assert m.gauge_get(metric)? == 5.0
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
module metrics
|
|
||||||
|
|
||||||
fn test_counter_increment() {
|
|
||||||
mut m := new_default_collector()
|
|
||||||
m.counter_register(0, name: 'test')
|
|
||||||
|
|
||||||
m.counter_increment(name: 'test')
|
|
||||||
|
|
||||||
assert m.counter_get(name: 'test')? == u64(1)
|
|
||||||
|
|
||||||
m.counter_increment(name: 'test')
|
|
||||||
|
|
||||||
assert m.counter_get(name: 'test')? == u64(2)
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
module exporter
|
||||||
|
|
||||||
|
import io
|
||||||
|
import metrics { MetricsCollector }
|
||||||
|
|
||||||
|
pub interface MetricsExporter {
|
||||||
|
load(collector MetricsCollector)
|
||||||
|
export_to_writer(writer io.Writer) !
|
||||||
|
export_to_string() string !
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
module exporter
|
||||||
|
|
||||||
|
pub struct PrometheusExporter {
|
||||||
|
}
|
12
metrics.v
12
metrics.v
|
@ -20,11 +20,17 @@ pub fn (m &Metric) str() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub interface MetricsCollector {
|
pub interface MetricsCollector {
|
||||||
counter_register(value u64, metric Metric)
|
|
||||||
counter_increment(metric Metric)
|
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
|
||||||
|
gauge_add(value f64, metric Metric)
|
||||||
|
gauge_sub(value f64, metric Metric)
|
||||||
|
gauge_set(value f64, metric Metric)
|
||||||
|
gauge_get(metric Metric) ?f64
|
||||||
|
mut:
|
||||||
|
counter_register(value u64, metric Metric)
|
||||||
histogram_register(metric Metric)
|
histogram_register(metric Metric)
|
||||||
histogram_add(value f64, metric Metric)
|
gauge_register(value f64, metric Metric)
|
||||||
histogram_get(metric Metric) ?
|
|
||||||
}
|
}
|
||||||
|
|
18
null.v
18
null.v
|
@ -15,12 +15,26 @@ pub fn (c &NullCollector) counter_get(metric Metric) ?u64 {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c &NullCollector) counters() []Metric { return [] }
|
pub fn (c &NullCollector) counters() []Metric {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (c &NullCollector) histogram_register(metric Metric) {}
|
pub fn (c &NullCollector) histogram_register(metric Metric) {}
|
||||||
|
|
||||||
pub fn (c &NullCollector) histogram_add(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_sub(value f64, metric Metric) {}
|
||||||
|
|
||||||
|
pub fn (c &NullCollector) gauge_set(value f64, metric Metric) {}
|
||||||
|
|
||||||
|
pub fn (c &NullCollector) gauge_get(metric Metric) ?f64 {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue