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  }