Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

Commit

Permalink
server: add prometheus format option to metrics endpoint.
Browse files Browse the repository at this point in the history
Previously the metrics endpoint exposed metrics in a format which
was not consumable by prometheus. This update allows users to
configure the telemetry setup to expose metrics in a prometheus
friendly manner. In metrics endpoint now also accepts a format
query param for use by Prometheus when scrapping to ensure metrics
are in the desired format.
  • Loading branch information
jrasell committed Nov 5, 2019
1 parent 178e906 commit 7566ad3
Show file tree
Hide file tree
Showing 133 changed files with 32,777 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ dist/

# The Makefile build binary
sherpa

.DS_Store
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ require (
github.com/gorilla/mux v1.7.1
github.com/hashicorp/consul/api v1.1.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-immutable-radix v1.1.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.0
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/hashicorp/nomad/api v0.0.0-20190508234936-7ba2378a159e
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/mattn/go-isatty v0.0.7
github.com/oklog/run v1.0.0
github.com/panjf2000/ants/v2 v2.1.1
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v0.9.2
github.com/rs/zerolog v1.14.3
github.com/ryanuber/columnize v2.1.0+incompatible
github.com/sean-/sysexits v0.0.0-20171026162210-598690305aaa
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
Expand All @@ -26,6 +27,7 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
Expand All @@ -44,6 +46,8 @@ github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVo
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc=
github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
Expand All @@ -62,6 +66,8 @@ github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCO
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
Expand All @@ -85,6 +91,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
Expand Down Expand Up @@ -112,9 +119,13 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.14.3 h1:4EGfSkR2hJDB0s3oFfrlPqjU1e4WLncergLil3nEKW0=
Expand Down
19 changes: 18 additions & 1 deletion pkg/config/server/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
const (
configKeyTelemetryStatsiteAddress = "telemetry-statsite-address"
configKeyTelemetryStatsdAddress = "telemetry-statsd-address"
configKeyTelemetryPrometheus = "telemetry-prometheus"
)

// TelemetryConfig is the server Telemetry configuration struct.
type TelemetryConfig struct {
Prometheus bool
StatsiteAddr string
StatsdAddr string
}
Expand All @@ -21,14 +23,16 @@ type TelemetryConfig struct {
// object.
func (c *TelemetryConfig) MarshalZerologObject(e *zerolog.Event) {
e.Str(configKeyTelemetryStatsiteAddress, c.StatsiteAddr).
Str(configKeyTelemetryStatsdAddress, c.StatsdAddr)
Str(configKeyTelemetryStatsdAddress, c.StatsdAddr).
Bool(configKeyTelemetryPrometheus, c.Prometheus)
}

// GetTelemetryConfig hydrates the telemetry config struct.
func GetTelemetryConfig() TelemetryConfig {
return TelemetryConfig{
StatsiteAddr: viper.GetString(configKeyTelemetryStatsiteAddress),
StatsdAddr: viper.GetString(configKeyTelemetryStatsdAddress),
Prometheus: viper.GetBool(configKeyTelemetryPrometheus),
}
}

Expand Down Expand Up @@ -62,4 +66,17 @@ func RegisterTelemetryConfig(cmd *cobra.Command) {
_ = viper.BindPFlag(key, flags.Lookup(longOpt))
viper.SetDefault(key, defaultValue)
}

{
const (
key = configKeyTelemetryPrometheus
longOpt = "telemetry-prometheus"
defaultValue = false
description = "Specifies whether Prometheus formatted metrics are available"
)

flags.Bool(longOpt, defaultValue, description)
_ = viper.BindPFlag(key, flags.Lookup(longOpt))
viper.SetDefault(key, defaultValue)
}
}
24 changes: 24 additions & 0 deletions pkg/server/endpoints/v1/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package v1
import (
"encoding/json"
"net/http"
"sync"

metrics "github.com/armon/go-metrics"
"github.com/gofrs/uuid"
"github.com/hashicorp/nomad/api"
serverCfg "github.com/jrasell/sherpa/pkg/config/server"
"github.com/jrasell/sherpa/pkg/server/cluster"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
Expand All @@ -25,6 +28,11 @@ const (
defaultStorageBackendConsul = "Consul"
)

var (
promHandler http.Handler
promOnce sync.Once
)

type SystemServer struct {
logger zerolog.Logger
member *cluster.Member
Expand Down Expand Up @@ -128,6 +136,11 @@ func (s *SystemServer) GetLeader(w http.ResponseWriter, r *http.Request) {
}

func (s *SystemServer) GetMetrics(w http.ResponseWriter, r *http.Request) {
if format := r.URL.Query().Get("format"); format == "prometheus" {
s.prometheusHandler().ServeHTTP(w, r)
return
}

metricData, err := s.telemetry.DisplayMetrics(w, r)
if err != nil {
s.logger.Error().Err(err).Msg("failed to get latest telemetry data")
Expand All @@ -145,6 +158,17 @@ func (s *SystemServer) GetMetrics(w http.ResponseWriter, r *http.Request) {
writeJSONResponse(w, out)
}

func (s *SystemServer) prometheusHandler() http.Handler {
promOnce.Do(func() {
handlerOptions := promhttp.HandlerOpts{
ErrorHandling: promhttp.ContinueOnError,
DisableCompression: true,
}
promHandler = promhttp.HandlerFor(prometheus.DefaultGatherer, handlerOptions)
})
return promHandler
}

func writeJSONResponse(w http.ResponseWriter, bytes []byte) {
w.Header().Set(headerKeyContentType, headerValueContentTypeJSON)
w.WriteHeader(http.StatusOK)
Expand Down
10 changes: 10 additions & 0 deletions pkg/server/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

metrics "github.com/armon/go-metrics"
"github.com/armon/go-metrics/prometheus"
"github.com/jrasell/sherpa/pkg/build"
)

Expand Down Expand Up @@ -34,6 +35,15 @@ func (h *HTTPServer) setupTelemetry() error {
fanout = append(fanout, sink)
}

// Configure prometheus formatted metrics.
if h.cfg.Telemetry.Prometheus {
promSink, err := prometheus.NewPrometheusSink()
if err != nil {
return err
}
fanout = append(fanout, promSink)
}

// Initialize the global sink
if len(fanout) > 0 {
fanout = append(fanout, inm)
Expand Down
Loading

0 comments on commit 7566ad3

Please sign in to comment.