76
reporter.go
Normal file
76
reporter.go
Normal file
@@ -0,0 +1,76 @@
|
||||
// +build ignore
|
||||
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/unistack-org/micro/v3/logger"
|
||||
"github.com/unistack-org/micro/v3/metadata"
|
||||
"github.com/unistack-org/micro/v3/meter"
|
||||
)
|
||||
|
||||
// Reporter is an implementation of meter.Reporter:
|
||||
type Reporter struct {
|
||||
options meter.Options
|
||||
prometheusRegistry *prometheus.Registry
|
||||
metrics metricFamily
|
||||
}
|
||||
|
||||
// New returns a configured prometheus reporter:
|
||||
func New(opts ...meter.Option) (meter.Reporter, error) {
|
||||
options := meter.NewOptions(opts...)
|
||||
|
||||
// Make a prometheus registry (this keeps track of any metrics we generate):
|
||||
prometheusRegistry := prometheus.NewRegistry()
|
||||
prometheusRegistry.Register(prometheus.NewGoCollector())
|
||||
prometheusRegistry.Register(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{Namespace: "goruntime"}))
|
||||
|
||||
// Make a new Reporter:
|
||||
newReporter := &Reporter{
|
||||
options: options,
|
||||
prometheusRegistry: prometheusRegistry,
|
||||
}
|
||||
|
||||
// Add metrics families for each type:
|
||||
newReporter.metrics = newReporter.newMetricFamily()
|
||||
|
||||
// Handle the metrics endpoint with prometheus:
|
||||
logger.Infof(options.Context, "Metrics/Prometheus [http] Listening on %s%s", options.Address, options.Path)
|
||||
http.Handle(options.Path, promhttp.HandlerFor(prometheusRegistry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}))
|
||||
go http.ListenAndServe(options.Address, nil)
|
||||
|
||||
return newReporter, nil
|
||||
}
|
||||
|
||||
func (r *Reporter) Init(...meter.Option) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// convertTags turns Tags into prometheus labels:
|
||||
func (r *Reporter) convertTags(tags metadata.Metadata) prometheus.Labels {
|
||||
labels := prometheus.Labels{}
|
||||
for key, value := range tags {
|
||||
labels[key] = r.stripUnsupportedCharacters(value)
|
||||
}
|
||||
return labels
|
||||
}
|
||||
|
||||
// listTagKeys returns a list of tag keys (we need to provide this to the Prometheus client):
|
||||
func (r *Reporter) listTagKeys(tags metadata.Metadata) (labelKeys []string) {
|
||||
for key := range tags {
|
||||
labelKeys = append(labelKeys, key)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// stripUnsupportedCharacters cleans up a metrics key or value:
|
||||
func (r *Reporter) stripUnsupportedCharacters(metricName string) string {
|
||||
valueWithoutDots := strings.Replace(metricName, ".", "_", -1)
|
||||
valueWithoutCommas := strings.Replace(valueWithoutDots, ",", "_", -1)
|
||||
valueWIthoutSpaces := strings.Replace(valueWithoutCommas, " ", "", -1)
|
||||
return valueWIthoutSpaces
|
||||
}
|
Reference in New Issue
Block a user