summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/prometheus/client_golang/prometheus/push/push.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/prometheus/client_golang/prometheus/push/push.go')
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/push/push.go244
1 files changed, 154 insertions, 90 deletions
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/push/push.go b/vendor/github.com/prometheus/client_golang/prometheus/push/push.go
index 8fb6f5f17..02be52c38 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/push/push.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/push/push.go
@@ -11,20 +11,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Copyright (c) 2013, The Prometheus Authors
-// All rights reserved.
+// Package push provides functions to push metrics to a Pushgateway. It uses a
+// builder approach. Create a Pusher with New and then add the various options
+// by using its methods, finally calling Add or Push, like this:
//
-// Use of this source code is governed by a BSD-style license that can be found
-// in the LICENSE file.
-
-// Package push provides functions to push metrics to a Pushgateway. The metrics
-// to push are either collected from a provided registry, or from explicitly
-// listed collectors.
+// // Easy case:
+// push.New("http://example.org/metrics", "my_job").Gatherer(myRegistry).Push()
+//
+// // Complex case:
+// push.New("http://example.org/metrics", "my_job").
+// Collector(myCollector1).
+// Collector(myCollector2).
+// Grouping("zone", "xy").
+// Client(&myHTTPClient).
+// BasicAuth("top", "secret").
+// Add()
+//
+// See the examples section for more detailed examples.
//
-// See the documentation of the Pushgateway to understand the meaning of the
-// grouping parameters and the differences between push.Registry and
-// push.Collectors on the one hand and push.AddRegistry and push.AddCollectors
-// on the other hand: https://github.com/prometheus/pushgateway
+// See the documentation of the Pushgateway to understand the meaning of
+// the grouping key and the differences between Push and Add:
+// https://github.com/prometheus/pushgateway
package push
import (
@@ -33,7 +40,6 @@ import (
"io/ioutil"
"net/http"
"net/url"
- "os"
"strings"
"github.com/prometheus/common/expfmt"
@@ -44,57 +50,149 @@ import (
const contentTypeHeader = "Content-Type"
-// FromGatherer triggers a metric collection by the provided Gatherer (which is
-// usually implemented by a prometheus.Registry) and pushes all gathered metrics
-// to the Pushgateway specified by url, using the provided job name and the
-// (optional) further grouping labels (the grouping map may be nil). See the
-// Pushgateway documentation for detailed implications of the job and other
-// grouping labels. Neither the job name nor any grouping label value may
-// contain a "/". The metrics pushed must not contain a job label of their own
-// nor any of the grouping labels.
+// Pusher manages a push to the Pushgateway. Use New to create one, configure it
+// with its methods, and finally use the Add or Push method to push.
+type Pusher struct {
+ error error
+
+ url, job string
+ grouping map[string]string
+
+ gatherers prometheus.Gatherers
+ registerer prometheus.Registerer
+
+ client *http.Client
+ useBasicAuth bool
+ username, password string
+}
+
+// New creates a new Pusher to push to the provided URL withe the provided job
+// name. You can use just host:port or ip:port as url, in which case “http://”
+// is added automatically. Alternatively, include the schema in the
+// URL. However, do not include the “/metrics/jobs/…” part.
//
-// You can use just host:port or ip:port as url, in which case 'http://' is
-// added automatically. You can also include the schema in the URL. However, do
-// not include the '/metrics/jobs/...' part.
+// Note that until https://github.com/prometheus/pushgateway/issues/97 is
+// resolved, a “/” character in the job name is prohibited.
+func New(url, job string) *Pusher {
+ var (
+ reg = prometheus.NewRegistry()
+ err error
+ )
+ if !strings.Contains(url, "://") {
+ url = "http://" + url
+ }
+ if strings.HasSuffix(url, "/") {
+ url = url[:len(url)-1]
+ }
+ if strings.Contains(job, "/") {
+ err = fmt.Errorf("job contains '/': %s", job)
+ }
+
+ return &Pusher{
+ error: err,
+ url: url,
+ job: job,
+ grouping: map[string]string{},
+ gatherers: prometheus.Gatherers{reg},
+ registerer: reg,
+ client: &http.Client{},
+ }
+}
+
+// Push collects/gathers all metrics from all Collectors and Gatherers added to
+// this Pusher. Then, it pushes them to the Pushgateway configured while
+// creating this Pusher, using the configured job name and any added grouping
+// labels as grouping key. All previously pushed metrics with the same job and
+// other grouping labels will be replaced with the metrics pushed by this
+// call. (It uses HTTP method “PUT” to push to the Pushgateway.)
//
-// Note that all previously pushed metrics with the same job and other grouping
-// labels will be replaced with the metrics pushed by this call. (It uses HTTP
-// method 'PUT' to push to the Pushgateway.)
-func FromGatherer(job string, grouping map[string]string, url string, g prometheus.Gatherer) error {
- return push(job, grouping, url, g, "PUT")
+// Push returns the first error encountered by any method call (including this
+// one) in the lifetime of the Pusher.
+func (p *Pusher) Push() error {
+ return p.push("PUT")
}
-// AddFromGatherer works like FromGatherer, but only previously pushed metrics
-// with the same name (and the same job and other grouping labels) will be
-// replaced. (It uses HTTP method 'POST' to push to the Pushgateway.)
-func AddFromGatherer(job string, grouping map[string]string, url string, g prometheus.Gatherer) error {
- return push(job, grouping, url, g, "POST")
+// Add works like push, but only previously pushed metrics with the same name
+// (and the same job and other grouping labels) will be replaced. (It uses HTTP
+// method “POST” to push to the Pushgateway.)
+func (p *Pusher) Add() error {
+ return p.push("POST")
}
-func push(job string, grouping map[string]string, pushURL string, g prometheus.Gatherer, method string) error {
- if !strings.Contains(pushURL, "://") {
- pushURL = "http://" + pushURL
- }
- if strings.HasSuffix(pushURL, "/") {
- pushURL = pushURL[:len(pushURL)-1]
- }
+// Gatherer adds a Gatherer to the Pusher, from which metrics will be gathered
+// to push them to the Pushgateway. The gathered metrics must not contain a job
+// label of their own.
+//
+// For convenience, this method returns a pointer to the Pusher itself.
+func (p *Pusher) Gatherer(g prometheus.Gatherer) *Pusher {
+ p.gatherers = append(p.gatherers, g)
+ return p
+}
- if strings.Contains(job, "/") {
- return fmt.Errorf("job contains '/': %s", job)
+// Collector adds a Collector to the Pusher, from which metrics will be
+// collected to push them to the Pushgateway. The collected metrics must not
+// contain a job label of their own.
+//
+// For convenience, this method returns a pointer to the Pusher itself.
+func (p *Pusher) Collector(c prometheus.Collector) *Pusher {
+ if p.error == nil {
+ p.error = p.registerer.Register(c)
}
- urlComponents := []string{url.QueryEscape(job)}
- for ln, lv := range grouping {
- if !model.LabelName(ln).IsValid() {
- return fmt.Errorf("grouping label has invalid name: %s", ln)
+ return p
+}
+
+// Grouping adds a label pair to the grouping key of the Pusher, replacing any
+// previously added label pair with the same label name. Note that setting any
+// labels in the grouping key that are already contained in the metrics to push
+// will lead to an error.
+//
+// For convenience, this method returns a pointer to the Pusher itself.
+//
+// Note that until https://github.com/prometheus/pushgateway/issues/97 is
+// resolved, this method does not allow a “/” character in the label value.
+func (p *Pusher) Grouping(name, value string) *Pusher {
+ if p.error == nil {
+ if !model.LabelName(name).IsValid() {
+ p.error = fmt.Errorf("grouping label has invalid name: %s", name)
+ return p
}
- if strings.Contains(lv, "/") {
- return fmt.Errorf("value of grouping label %s contains '/': %s", ln, lv)
+ if strings.Contains(value, "/") {
+ p.error = fmt.Errorf("value of grouping label %s contains '/': %s", name, value)
+ return p
}
+ p.grouping[name] = value
+ }
+ return p
+}
+
+// Client sets a custom HTTP client for the Pusher. For convenience, this method
+// returns a pointer to the Pusher itself.
+func (p *Pusher) Client(c *http.Client) *Pusher {
+ p.client = c
+ return p
+}
+
+// BasicAuth configures the Pusher to use HTTP Basic Authentication with the
+// provided username and password. For convenience, this method returns a
+// pointer to the Pusher itself.
+func (p *Pusher) BasicAuth(username, password string) *Pusher {
+ p.useBasicAuth = true
+ p.username = username
+ p.password = password
+ return p
+}
+
+func (p *Pusher) push(method string) error {
+ if p.error != nil {
+ return p.error
+ }
+ urlComponents := []string{url.QueryEscape(p.job)}
+ for ln, lv := range p.grouping {
urlComponents = append(urlComponents, ln, lv)
}
- pushURL = fmt.Sprintf("%s/metrics/job/%s", pushURL, strings.Join(urlComponents, "/"))
+ pushURL := fmt.Sprintf("%s/metrics/job/%s", p.url, strings.Join(urlComponents, "/"))
- mfs, err := g.Gather()
+ mfs, err := p.gatherers.Gather()
if err != nil {
return err
}
@@ -107,7 +205,7 @@ func push(job string, grouping map[string]string, pushURL string, g prometheus.G
if l.GetName() == "job" {
return fmt.Errorf("pushed metric %s (%s) already contains a job label", mf.GetName(), m)
}
- if _, ok := grouping[l.GetName()]; ok {
+ if _, ok := p.grouping[l.GetName()]; ok {
return fmt.Errorf(
"pushed metric %s (%s) already contains grouping label %s",
mf.GetName(), m, l.GetName(),
@@ -121,8 +219,11 @@ func push(job string, grouping map[string]string, pushURL string, g prometheus.G
if err != nil {
return err
}
+ if p.useBasicAuth {
+ req.SetBasicAuth(p.username, p.password)
+ }
req.Header.Set(contentTypeHeader, string(expfmt.FmtProtoDelim))
- resp, err := http.DefaultClient.Do(req)
+ resp, err := p.client.Do(req)
if err != nil {
return err
}
@@ -133,40 +234,3 @@ func push(job string, grouping map[string]string, pushURL string, g prometheus.G
}
return nil
}
-
-// Collectors works like FromGatherer, but it does not use a Gatherer. Instead,
-// it collects from the provided collectors directly. It is a convenient way to
-// push only a few metrics.
-func Collectors(job string, grouping map[string]string, url string, collectors ...prometheus.Collector) error {
- return pushCollectors(job, grouping, url, "PUT", collectors...)
-}
-
-// AddCollectors works like AddFromGatherer, but it does not use a Gatherer.
-// Instead, it collects from the provided collectors directly. It is a
-// convenient way to push only a few metrics.
-func AddCollectors(job string, grouping map[string]string, url string, collectors ...prometheus.Collector) error {
- return pushCollectors(job, grouping, url, "POST", collectors...)
-}
-
-func pushCollectors(job string, grouping map[string]string, url, method string, collectors ...prometheus.Collector) error {
- r := prometheus.NewRegistry()
- for _, collector := range collectors {
- if err := r.Register(collector); err != nil {
- return err
- }
- }
- return push(job, grouping, url, r, method)
-}
-
-// HostnameGroupingKey returns a label map with the only entry
-// {instance="<hostname>"}. This can be conveniently used as the grouping
-// parameter if metrics should be pushed with the hostname as label. The
-// returned map is created upon each call so that the caller is free to add more
-// labels to the map.
-func HostnameGroupingKey() map[string]string {
- hostname, err := os.Hostname()
- if err != nil {
- return map[string]string{"instance": "unknown"}
- }
- return map[string]string{"instance": hostname}
-}