feat: added gauge type & some tests
parent
a1049943a4
commit
52fbf8ce5d
|
@ -0,0 +1,2 @@
|
|||
*.c
|
||||
*.so
|
103
collector.v
103
collector.v
|
@ -2,12 +2,12 @@ module metrics
|
|||
|
||||
import sync.stdatomic
|
||||
|
||||
struct CounterEntry {
|
||||
struct Counter {
|
||||
metric Metric
|
||||
index int
|
||||
data u64
|
||||
}
|
||||
|
||||
struct HistogramEntry {
|
||||
struct FloatSeries {
|
||||
metric Metric
|
||||
pub mut:
|
||||
data shared []f64
|
||||
|
@ -16,72 +16,66 @@ pub mut:
|
|||
[heap]
|
||||
struct DefaultCollector {
|
||||
mut:
|
||||
// The mutex for counters also applies to counter_indexes. Both data
|
||||
// structuress are only ever updated together. Note that only registering a
|
||||
// new metric actually changes these; all operations on already existing
|
||||
// metrics use atomic operations on the elements of the counters array.
|
||||
counters shared []u64
|
||||
counter_indexes map[string]CounterEntry
|
||||
histograms shared map[string]HistogramEntry
|
||||
counters shared map[string]&Counter
|
||||
histograms shared map[string]&FloatSeries
|
||||
gauges shared map[string]&FloatSeries
|
||||
}
|
||||
|
||||
pub fn new_default_collector() &DefaultCollector {
|
||||
return &DefaultCollector{
|
||||
counters: []u64{}
|
||||
counter_indexes: map[string]CounterEntry{}
|
||||
histograms: map[string]HistogramEntry{}
|
||||
counters: map[string]&Counter{}
|
||||
histograms: map[string]&FloatSeries{}
|
||||
gauges: map[string]&FloatSeries{}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut c DefaultCollector) counter_register(value u64, metric Metric) {
|
||||
lock c.counters {
|
||||
c.counters << value
|
||||
|
||||
c.counter_indexes[metric.str()] = CounterEntry{
|
||||
c.counters[metric.str()] = &Counter{
|
||||
metric: metric
|
||||
index: c.counters.len - 1
|
||||
data: value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (c &DefaultCollector) counter_increment(metric Metric) {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (c &DefaultCollector) counters() []Metric {
|
||||
mut metrics := []Metric{}
|
||||
mut metrics := []Metric{}
|
||||
|
||||
rlock c.counters {
|
||||
for _, entry in c.counter_indexes {
|
||||
metrics << entry.metric
|
||||
}
|
||||
}
|
||||
rlock c.counters {
|
||||
for _, entry in c.counters {
|
||||
metrics << entry.metric
|
||||
}
|
||||
}
|
||||
|
||||
return metrics
|
||||
return metrics
|
||||
}
|
||||
|
||||
pub fn (mut c DefaultCollector) histogram_register(metric Metric) {
|
||||
lock c.histograms {
|
||||
c.histograms[metric.str()] = HistogramEntry{
|
||||
c.histograms[metric.str()] = &FloatSeries{
|
||||
metric: metric
|
||||
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 {
|
||||
c.histograms[metric.str()]
|
||||
}
|
||||
|
@ -102,3 +96,52 @@ pub fn (c &DefaultCollector) histogram_get(metric Metric) ?[]f64 {
|
|||
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 {
|
||||
}
|
14
metrics.v
14
metrics.v
|
@ -20,11 +20,17 @@ pub fn (m &Metric) str() string {
|
|||
}
|
||||
|
||||
pub interface MetricsCollector {
|
||||
counter_register(value u64, metric Metric)
|
||||
counter_increment(metric Metric)
|
||||
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_add(value f64, metric Metric)
|
||||
histogram_get(metric Metric) ?
|
||||
gauge_register(value f64, metric Metric)
|
||||
}
|
||||
|
|
18
null.v
18
null.v
|
@ -15,12 +15,26 @@ pub fn (c &NullCollector) counter_get(metric Metric) ?u64 {
|
|||
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_add(value f64, metric Metric) {}
|
||||
pub fn (c &NullCollector) histogram_record(value f64, metric Metric) {}
|
||||
|
||||
pub fn (c &NullCollector) histogram_get(metric Metric) ?[]f64 {
|
||||
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