Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update examples to use custom registry #1152

Merged
merged 4 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 40 additions & 26 deletions examples/random/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,45 +30,57 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
var (
addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
uniformDomain = flag.Float64("uniform.domain", 0.0002, "The domain for the uniform distribution.")
normDomain = flag.Float64("normal.domain", 0.0002, "The domain for the normal distribution.")
normMean = flag.Float64("normal.mean", 0.00001, "The mean for the normal distribution.")
oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.")
)

flag.Parse()
type metrics struct {
rpcDurations *prometheus.SummaryVec
rpcDurationsHistogram prometheus.Histogram
}

var (
// Create a summary to track fictional interservice RPC latencies for three
func NewMetrics(reg prometheus.Registerer, normMean, normDomain float64) *metrics {
m := &metrics{
// Create a summary to track fictional inter service RPC latencies for three
// distinct services with different latency distributions. These services are
// differentiated via a "service" label.
rpcDurations = prometheus.NewSummaryVec(
rpcDurations: prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "rpc_durations_seconds",
Help: "RPC latency distributions.",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
},
[]string{"service"},
)
),
// The same as above, but now as a histogram, and only for the normal
// distribution. The buckets are targeted to the parameters of the
// normal distribution, with 20 buckets centered on the mean, each
// half-sigma wide.
rpcDurationsHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{
rpcDurationsHistogram: prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "rpc_durations_histogram_seconds",
Help: "RPC latency distributions.",
Buckets: prometheus.LinearBuckets(*normMean-5**normDomain, .5**normDomain, 20),
})
Buckets: prometheus.LinearBuckets(normMean-5*normDomain, .5*normDomain, 20),
}),
}
reg.MustRegister(m.rpcDurations)
reg.MustRegister(m.rpcDurationsHistogram)
return m
}

func main() {
var (
addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
uniformDomain = flag.Float64("uniform.domain", 0.0002, "The domain for the uniform distribution.")
normDomain = flag.Float64("normal.domain", 0.0002, "The domain for the normal distribution.")
normMean = flag.Float64("normal.mean", 0.00001, "The mean for the normal distribution.")
oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.")
)

// Register the summary and the histogram with Prometheus's default registry.
prometheus.MustRegister(rpcDurations)
prometheus.MustRegister(rpcDurationsHistogram)
flag.Parse()

// Create a non-global registry.
reg := prometheus.NewRegistry()

// Create new metrics and register them using the custom registry.
m := NewMetrics(reg, *normMean, *normDomain)
// Add Go module build info.
prometheus.MustRegister(collectors.NewBuildInfoCollector())
reg.MustRegister(collectors.NewBuildInfoCollector())

start := time.Now()

Expand All @@ -80,22 +92,22 @@ func main() {
go func() {
for {
v := rand.Float64() * *uniformDomain
rpcDurations.WithLabelValues("uniform").Observe(v)
m.rpcDurations.WithLabelValues("uniform").Observe(v)
time.Sleep(time.Duration(100*oscillationFactor()) * time.Millisecond)
}
}()

go func() {
for {
v := (rand.NormFloat64() * *normDomain) + *normMean
rpcDurations.WithLabelValues("normal").Observe(v)
m.rpcDurations.WithLabelValues("normal").Observe(v)
// Demonstrate exemplar support with a dummy ID. This
// would be something like a trace ID in a real
// application. Note the necessary type assertion. We
// already know that rpcDurationsHistogram implements
// the ExemplarObserver interface and thus don't need to
// check the outcome of the type assertion.
rpcDurationsHistogram.(prometheus.ExemplarObserver).ObserveWithExemplar(
m.rpcDurationsHistogram.(prometheus.ExemplarObserver).ObserveWithExemplar(
v, prometheus.Labels{"dummyID": fmt.Sprint(rand.Intn(100000))},
)
time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond)
Expand All @@ -105,17 +117,19 @@ func main() {
go func() {
for {
v := rand.ExpFloat64() / 1e6
rpcDurations.WithLabelValues("exponential").Observe(v)
m.rpcDurations.WithLabelValues("exponential").Observe(v)
time.Sleep(time.Duration(50*oscillationFactor()) * time.Millisecond)
}
}()

// Expose the registered metrics via HTTP.
http.Handle("/metrics", promhttp.HandlerFor(
prometheus.DefaultGatherer,
reg,
promhttp.HandlerOpts{
// Opt into OpenMetrics to support exemplars.
EnableOpenMetrics: true,
// Pass custom registry
Registry: reg,
},
))
log.Fatal(http.ListenAndServe(*addr, nil))
Expand Down
8 changes: 7 additions & 1 deletion examples/simple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ import (
"log"
"net/http"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")

func main() {
flag.Parse()
http.Handle("/metrics", promhttp.Handler())

// Create non-global registry.
reg := prometheus.NewRegistry()

// Expose /metrics HTTP endpoint using the created custom registry.
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if here we want to expose more metrics (currently this exposes only promhttp_metric_handler_errors_total) - though it may be the simplest example with metrics we can get - wdyt?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is illustrative (in a test), the metric you have picked LGTM

log.Fatal(http.ListenAndServe(*addr, nil))
}
58 changes: 35 additions & 23 deletions prometheus/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,51 @@
// "github.com/prometheus/client_golang/prometheus/promhttp"
// )
//
// var (
// cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{
// Name: "cpu_temperature_celsius",
// Help: "Current temperature of the CPU.",
// })
// hdFailures = prometheus.NewCounterVec(
// prometheus.CounterOpts{
// Name: "hd_errors_total",
// Help: "Number of hard-disk errors.",
// },
// []string{"device"},
// )
// )
// type metrics struct {
// cpuTemp prometheus.Gauge
// hdFailures *prometheus.CounterVec
// }
//
// func init() {
// // Metrics have to be registered to be exposed:
// prometheus.MustRegister(cpuTemp)
// prometheus.MustRegister(hdFailures)
// func NewMetrics(reg prometheus.Registerer) *metrics {
// m := &metrics{
// cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{
// Name: "cpu_temperature_celsius",
// Help: "Current temperature of the CPU.",
// }),
// hdFailures: prometheus.NewCounterVec(
// prometheus.CounterOpts{
// Name: "hd_errors_total",
// Help: "Number of hard-disk errors.",
// },
// []string{"device"},
// ),
// }
// reg.MustRegister(m.cpuTemp)
// reg.MustRegister(m.hdFailures)
// return m
// }
//
// func main() {
// cpuTemp.Set(65.3)
// hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()
//
// // The Handler function provides a default handler to expose metrics
// // via an HTTP server. "/metrics" is the usual endpoint for that.
// http.Handle("/metrics", promhttp.Handler())
// // Create a non-global registry.
// reg := prometheus.NewRegistry()
//
// // Create new metrics and register them using the custom registry.
// m := NewMetrics(reg)
// // Set values for the new created metrics.
// m.cpuTemp.Set(65.3)
// m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()
//
// // Expose metrics and custom registry via an HTTP server
// // using the HandleFor function. "/metrics" is the usual endpoint for that.
// http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))
// log.Fatal(http.ListenAndServe(":8080", nil))
// }
//
//
// This is a complete program that exports two metrics, a Gauge and a Counter,
// the latter with a label attached to turn it into a (one-dimensional) vector.
// It register the metrics using a custom registry and exposes them via an HTTP server
// on the /metrics endpoint.
//
// Metrics
//
Expand Down