github.com/anycable/anycable-go@v1.5.1/metrics/prometheus.go (about) 1 package metrics 2 3 import ( 4 "fmt" 5 "net/http" 6 "strconv" 7 "strings" 8 ) 9 10 const ( 11 prometheusNamespace = "anycable_go" 12 ) 13 14 // Prometheus returns metrics info in Prometheus format 15 func (m *Metrics) Prometheus() string { 16 var buf strings.Builder 17 18 tags := toPromTags(m.tags) 19 20 m.EachCounter(func(counter *Counter) { 21 name := prometheusNamespace + `_` + counter.Name() 22 23 buf.WriteString( 24 "\n# HELP " + name + " " + counter.Desc() + "\n", 25 ) 26 buf.WriteString("# TYPE " + name + " counter\n") 27 buf.WriteString(name + tags + " " + strconv.FormatUint(counter.Value(), 10) + "\n") 28 }) 29 30 m.EachGauge(func(gauge *Gauge) { 31 name := prometheusNamespace + `_` + gauge.Name() 32 33 buf.WriteString( 34 "\n# HELP " + name + " " + gauge.Desc() + "\n", 35 ) 36 buf.WriteString("# TYPE " + name + " gauge\n") 37 buf.WriteString(name + tags + " " + strconv.FormatUint(gauge.Value(), 10) + "\n") 38 }) 39 40 return buf.String() 41 } 42 43 // PrometheusHandler is provide metrics to the world 44 func (m *Metrics) PrometheusHandler(w http.ResponseWriter, r *http.Request) { 45 metricsData := m.Prometheus() 46 47 fmt.Fprint(w, metricsData) 48 } 49 50 func toPromTags(tags map[string]string) string { 51 if tags == nil { 52 return "" 53 } 54 55 buf := make([]string, len(tags)) 56 i := 0 57 58 for k, v := range tags { 59 buf[i] = fmt.Sprintf("%s=\"%s\"", k, v) 60 i++ 61 } 62 63 return fmt.Sprintf("{%s}", strings.Join(buf, ", ")) 64 }