module metrics import sync.stdatomic struct Counter { metric Metric data u64 } struct FloatSeries { metric Metric pub mut: data shared []f64 } [heap] struct DefaultCollector { mut: counters shared map[string]&Counter histograms shared map[string]&FloatSeries gauges shared map[string]&FloatSeries } pub fn new_default_collector() &DefaultCollector { return &DefaultCollector{ 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[metric.str()] = &Counter{ metric: metric data: value } } } pub fn (c &DefaultCollector) counter_increment(metric Metric) { rlock c.counters { entry := c.counters[metric.str()] stdatomic.add_u64(&entry.data, 1) } } pub fn (c &DefaultCollector) counter_get(metric Metric) ?u64 { return rlock c.counters { entry := c.counters[metric.str()] or { return none } stdatomic.load_u64(&entry.data) } } pub fn (c &DefaultCollector) counters() []Metric { mut metrics := []Metric{} rlock c.counters { for _, entry in c.counters { metrics << entry.metric } } return metrics } pub fn (mut c DefaultCollector) histogram_register(metric Metric) { lock c.histograms { c.histograms[metric.str()] = &FloatSeries{ metric: metric data: []f64{} } } } pub fn (c &DefaultCollector) histogram_record(value f64, metric Metric) { entry := rlock c.histograms { c.histograms[metric.str()] } lock entry.data { entry.data << value } } pub fn (c &DefaultCollector) histogram_get(metric Metric) ?[]f64 { entry := rlock c.histograms { c.histograms[metric.str()] or { return none } } return rlock entry.data { // Return a clone of the data to prevent user from altering // internal structure 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] } }