package metrics import ( "context" "fmt" "time" ) // Collector collects and exposes metrics type Collector struct { metrics map[string]Metric } // NewCollector creates a new metrics collector func NewCollector() *Collector { return &Collector{ metrics: make(map[string]Metric), } } // Metric represents a metric type Metric struct { Name string Value float64 Type string // "counter", "gauge", "histogram" Labels map[string]string Timestamp time.Time } // IncrementCounter increments a counter metric func (c *Collector) IncrementCounter(ctx context.Context, name string, labels map[string]string) { key := c.metricKey(name, labels) if metric, ok := c.metrics[key]; ok { metric.Value++ metric.Timestamp = time.Now() c.metrics[key] = metric } else { c.metrics[key] = Metric{ Name: name, Value: 1, Type: "counter", Labels: labels, Timestamp: time.Now(), } } } // SetGauge sets a gauge metric func (c *Collector) SetGauge(ctx context.Context, name string, value float64, labels map[string]string) { key := c.metricKey(name, labels) c.metrics[key] = Metric{ Name: name, Value: value, Type: "gauge", Labels: labels, Timestamp: time.Now(), } } // GetMetrics gets all metrics func (c *Collector) GetMetrics() map[string]Metric { return c.metrics } // metricKey creates a key for a metric func (c *Collector) metricKey(name string, labels map[string]string) string { key := name for k, v := range labels { key += fmt.Sprintf(":%s=%s", k, v) } return key }