Add proxy_url parameter to allow specifying per-job HTTP proxy servers

Allow scrape_configs to have an optional proxy_url option which specifies
a proxy to be used for all connections to hosts in that config.

Internally this modifies the various client functions to take a *url.URL pointer
which currently must point to an HTTP proxy (but has been left open-ended to
allow the url format to be extended to support others, such as maybe SOCKS if
needed).
This commit is contained in:
Will Rouesnel 2015-08-07 02:12:55 +10:00
parent a2d382627a
commit 7810448dbe
7 changed files with 41 additions and 8 deletions

View file

@ -100,6 +100,34 @@ var (
}
)
// This custom URL type allows validating at configuration load time.
type URL struct {
*url.URL
}
// UnmarshalYAML implements the yaml.Unmarshaler interface for URLs.
func (u *URL) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
if err := unmarshal(&s); err != nil {
return err
}
urlp, err := url.Parse(s)
if err != nil {
return err
}
u.URL = urlp
return nil
}
// MarshalYAML implements the yaml.Marshaler interface for URLs.
func (u URL) MarshalYAML() (interface{}, error) {
if u.URL != nil {
return u.String(), nil
}
return nil, nil
}
// Config is the top-level configuration for Prometheus's config files.
type Config struct {
GlobalConfig GlobalConfig `yaml:"global"`
@ -237,6 +265,8 @@ type ScrapeConfig struct {
CACert string `yaml:"ca_cert,omitempty"`
// The client cert authentication credentials for the targets.
ClientCert *ClientCert `yaml:"client_cert,omitempty"`
// HTTP proxy server to use to connect to the targets.
ProxyURL URL `yaml:"proxy_url,omitempty"`
// List of labeled target groups for this job.
TargetGroups []*TargetGroup `yaml:"target_groups,omitempty"`

View file

@ -103,7 +103,7 @@ func NewNotificationHandler(o *NotificationHandlerOptions) *NotificationHandler
alertmanagerURL: strings.TrimRight(o.AlertmanagerURL, "/"),
pendingNotifications: make(chan NotificationReqs, o.QueueCapacity),
httpClient: httputil.NewDeadlineClient(o.Deadline),
httpClient: httputil.NewDeadlineClient(o.Deadline, nil),
notificationLatency: prometheus.NewSummary(prometheus.SummaryOpts{
Namespace: namespace,

View file

@ -272,7 +272,7 @@ func newHTTPClient(cfg *config.ScrapeConfig) (*http.Client, error) {
tlsConfig.BuildNameToCertificate()
// Get a default roundtripper with the scrape timeout.
rt := httputil.NewDeadlineRoundTripper(time.Duration(cfg.ScrapeTimeout))
rt := httputil.NewDeadlineRoundTripper(time.Duration(cfg.ScrapeTimeout), cfg.ProxyURL.URL)
tr := rt.(*http.Transport)
// Set the TLS config from above
tr.TLSClientConfig = tlsConfig

View file

@ -447,7 +447,7 @@ func newTestTarget(targetURL string, deadline time.Duration, baseLabels clientmo
deadline: deadline,
status: &TargetStatus{},
scrapeInterval: 1 * time.Millisecond,
httpClient: httputil.NewDeadlineClient(deadline),
httpClient: httputil.NewDeadlineClient(deadline, nil),
scraperStopping: make(chan struct{}),
scraperStopped: make(chan struct{}),
}

View file

@ -47,7 +47,7 @@ type Client struct {
func NewClient(url string, timeout time.Duration, database, retentionPolicy string) *Client {
return &Client{
url: url,
httpClient: httputil.NewDeadlineClient(timeout),
httpClient: httputil.NewDeadlineClient(timeout, nil),
retentionPolicy: retentionPolicy,
database: database,
}

View file

@ -50,7 +50,7 @@ type Client struct {
func NewClient(url string, timeout time.Duration) *Client {
return &Client{
url: url,
httpClient: httputil.NewDeadlineClient(timeout),
httpClient: httputil.NewDeadlineClient(timeout, nil),
}
}

View file

@ -16,6 +16,7 @@ package httputil
import (
"net"
"net/http"
"net/url"
"time"
)
@ -26,14 +27,16 @@ func NewClient(rt http.RoundTripper) *http.Client {
// NewDeadlineClient returns a new http.Client which will time out long running
// requests.
func NewDeadlineClient(timeout time.Duration) *http.Client {
return NewClient(NewDeadlineRoundTripper(timeout))
func NewDeadlineClient(timeout time.Duration, proxyURL *url.URL) *http.Client {
return NewClient(NewDeadlineRoundTripper(timeout, proxyURL))
}
// NewDeadlineRoundTripper returns a new http.RoundTripper which will time out
// long running requests.
func NewDeadlineRoundTripper(timeout time.Duration) http.RoundTripper {
func NewDeadlineRoundTripper(timeout time.Duration, proxyURL *url.URL) http.RoundTripper {
return &http.Transport{
// Set proxy (if null, then becomes a direct connection)
Proxy: http.ProxyURL(proxyURL),
// We need to disable keepalive, because we set a deadline on the
// underlying connection.
DisableKeepAlives: true,