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