61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// PrometheusExporter exports metrics in Prometheus format
|
|
type PrometheusExporter struct {
|
|
Collectors []Collector
|
|
}
|
|
|
|
func NewPrometheusExporter(collectors ...Collector) *PrometheusExporter {
|
|
return &PrometheusExporter{Collectors: collectors}
|
|
}
|
|
|
|
// Export collects all metrics and formats them as Prometheus text format
|
|
func (e *PrometheusExporter) Export(ctx context.Context) string {
|
|
var builder strings.Builder
|
|
allErrors := []string{}
|
|
|
|
for _, collector := range e.Collectors {
|
|
collection := collector.Collect(ctx)
|
|
allErrors = append(allErrors, collection.Errors...)
|
|
|
|
for _, metric := range collection.Metrics {
|
|
// Format: metric_name{label1="value1",label2="value2"} value
|
|
builder.WriteString(metric.Name)
|
|
if len(metric.Labels) > 0 {
|
|
builder.WriteString("{")
|
|
first := true
|
|
for k, v := range metric.Labels {
|
|
if !first {
|
|
builder.WriteString(",")
|
|
}
|
|
builder.WriteString(fmt.Sprintf(`%s="%s"`, k, escapeLabelValue(v)))
|
|
first = false
|
|
}
|
|
builder.WriteString("}")
|
|
}
|
|
builder.WriteString(fmt.Sprintf(" %v\n", metric.Value))
|
|
}
|
|
}
|
|
|
|
// Add error metrics if any
|
|
if len(allErrors) > 0 {
|
|
builder.WriteString(fmt.Sprintf("monitoring_collector_errors_total %d\n", len(allErrors)))
|
|
}
|
|
|
|
return builder.String()
|
|
}
|
|
|
|
func escapeLabelValue(v string) string {
|
|
v = strings.ReplaceAll(v, "\\", "\\\\")
|
|
v = strings.ReplaceAll(v, "\"", "\\\"")
|
|
v = strings.ReplaceAll(v, "\n", "\\n")
|
|
return v
|
|
}
|
|
|