Move retrieval.NewHTTPClient -> httputil.NewClientFromConfig

This commit is contained in:
Julius Volz 2017-03-20 14:17:04 +01:00
parent eb14678a25
commit 815762a4ad
7 changed files with 64 additions and 70 deletions

View file

@ -24,10 +24,9 @@ import (
"time" "time"
"github.com/prometheus/common/log" "github.com/prometheus/common/log"
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"golang.org/x/net/context"
"github.com/prometheus/prometheus/util/httputil" "golang.org/x/net/context/ctxhttp"
) )
const ( const (
@ -37,15 +36,15 @@ const (
// Client allows sending batches of Prometheus samples to OpenTSDB. // Client allows sending batches of Prometheus samples to OpenTSDB.
type Client struct { type Client struct {
url string url string
httpClient *http.Client timeout time.Duration
} }
// NewClient creates a new Client. // NewClient creates a new Client.
func NewClient(url string, timeout time.Duration) *Client { func NewClient(url string, timeout time.Duration) *Client {
return &Client{ return &Client{
url: url, url: url,
httpClient: httputil.NewDeadlineClient(timeout, nil), timeout: timeout,
} }
} }
@ -100,11 +99,10 @@ func (c *Client) Store(samples model.Samples) error {
return err return err
} }
resp, err := c.httpClient.Post( ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
u.String(), defer cancel()
contentTypeJSON,
bytes.NewBuffer(buf), resp, err := ctxhttp.Post(ctx, http.DefaultClient, u.String(), contentTypeJSON, bytes.NewBuffer(buf))
)
if err != nil { if err != nil {
return err return err
} }

View file

@ -35,7 +35,7 @@ import (
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/discovery" "github.com/prometheus/prometheus/discovery"
"github.com/prometheus/prometheus/relabel" "github.com/prometheus/prometheus/relabel"
"github.com/prometheus/prometheus/retrieval" "github.com/prometheus/prometheus/util/httputil"
) )
const ( const (
@ -435,7 +435,7 @@ type alertmanagerSet struct {
} }
func newAlertmanagerSet(cfg *config.AlertmanagerConfig) (*alertmanagerSet, error) { func newAlertmanagerSet(cfg *config.AlertmanagerConfig) (*alertmanagerSet, error) {
client, err := retrieval.NewHTTPClient(cfg.HTTPClientConfig) client, err := httputil.NewClientFromConfig(cfg.HTTPClientConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -31,6 +31,7 @@ import (
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/storage/local" "github.com/prometheus/prometheus/storage/local"
"github.com/prometheus/prometheus/util/httputil"
) )
const ( const (
@ -114,7 +115,7 @@ type scrapePool struct {
} }
func newScrapePool(ctx context.Context, cfg *config.ScrapeConfig, app storage.SampleAppender) *scrapePool { func newScrapePool(ctx context.Context, cfg *config.ScrapeConfig, app storage.SampleAppender) *scrapePool {
client, err := NewHTTPClient(cfg.HTTPClientConfig) client, err := httputil.NewClientFromConfig(cfg.HTTPClientConfig)
if err != nil { if err != nil {
// Any errors that could occur here should be caught during config validation. // Any errors that could occur here should be caught during config validation.
log.Errorf("Error creating HTTP client for job %q: %s", cfg.JobName, err) log.Errorf("Error creating HTTP client for job %q: %s", cfg.JobName, err)
@ -161,7 +162,7 @@ func (sp *scrapePool) reload(cfg *config.ScrapeConfig) {
sp.mtx.Lock() sp.mtx.Lock()
defer sp.mtx.Unlock() defer sp.mtx.Unlock()
client, err := NewHTTPClient(cfg.HTTPClientConfig) client, err := httputil.NewClientFromConfig(cfg.HTTPClientConfig)
if err != nil { if err != nil {
// Any errors that could occur here should be caught during config validation. // Any errors that could occur here should be caught during config validation.
log.Errorf("Error creating HTTP client for job %q: %s", cfg.JobName, err) log.Errorf("Error creating HTTP client for job %q: %s", cfg.JobName, err)

View file

@ -16,9 +16,7 @@ package retrieval
import ( import (
"fmt" "fmt"
"hash/fnv" "hash/fnv"
"io/ioutil"
"net" "net"
"net/http"
"net/url" "net/url"
"strings" "strings"
"sync" "sync"
@ -29,7 +27,6 @@ import (
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/relabel" "github.com/prometheus/prometheus/relabel"
"github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/util/httputil"
) )
// TargetHealth describes the health state of a target. // TargetHealth describes the health state of a target.
@ -67,43 +64,6 @@ func NewTarget(labels, discoveredLabels model.LabelSet, params url.Values) *Targ
} }
} }
// NewHTTPClient returns a new HTTP client configured for the given scrape configuration.
func NewHTTPClient(cfg config.HTTPClientConfig) (*http.Client, error) {
tlsConfig, err := httputil.NewTLSConfig(cfg.TLSConfig)
if err != nil {
return nil, err
}
// The only timeout we care about is the configured scrape timeout.
// It is applied on request. So we leave out any timings here.
var rt http.RoundTripper = &http.Transport{
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
DisableKeepAlives: true,
TLSClientConfig: tlsConfig,
}
// If a bearer token is provided, create a round tripper that will set the
// Authorization header correctly on each request.
bearerToken := cfg.BearerToken
if len(bearerToken) == 0 && len(cfg.BearerTokenFile) > 0 {
b, err := ioutil.ReadFile(cfg.BearerTokenFile)
if err != nil {
return nil, fmt.Errorf("unable to read bearer token file %s: %s", cfg.BearerTokenFile, err)
}
bearerToken = strings.TrimSpace(string(b))
}
if len(bearerToken) > 0 {
rt = httputil.NewBearerAuthRoundTripper(bearerToken, rt)
}
if cfg.BasicAuth != nil {
rt = httputil.NewBasicAuthRoundTripper(cfg.BasicAuth.Username, cfg.BasicAuth.Password, rt)
}
// Return a new client with the configured round tripper.
return httputil.NewClient(rt), nil
}
func (t *Target) String() string { func (t *Target) String() string {
return t.URL().String() return t.URL().String()
} }

View file

@ -29,6 +29,7 @@ import (
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/util/httputil"
) )
const ( const (
@ -154,7 +155,7 @@ func TestNewHTTPBearerToken(t *testing.T) {
cfg := config.HTTPClientConfig{ cfg := config.HTTPClientConfig{
BearerToken: "1234", BearerToken: "1234",
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -181,7 +182,7 @@ func TestNewHTTPBearerTokenFile(t *testing.T) {
cfg := config.HTTPClientConfig{ cfg := config.HTTPClientConfig{
BearerTokenFile: "testdata/bearertoken.txt", BearerTokenFile: "testdata/bearertoken.txt",
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -210,7 +211,7 @@ func TestNewHTTPBasicAuth(t *testing.T) {
Password: "password123", Password: "password123",
}, },
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -238,7 +239,7 @@ func TestNewHTTPCACert(t *testing.T) {
CAFile: caCertPath, CAFile: caCertPath,
}, },
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -272,7 +273,7 @@ func TestNewHTTPClientCert(t *testing.T) {
KeyFile: "testdata/client.key", KeyFile: "testdata/client.key",
}, },
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -301,7 +302,7 @@ func TestNewHTTPWithServerName(t *testing.T) {
ServerName: "prometheus.rocks", ServerName: "prometheus.rocks",
}, },
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -330,7 +331,7 @@ func TestNewHTTPWithBadServerName(t *testing.T) {
ServerName: "badname", ServerName: "badname",
}, },
} }
c, err := NewHTTPClient(cfg) c, err := httputil.NewClientFromConfig(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -369,7 +370,7 @@ func TestNewClientWithBadTLSConfig(t *testing.T) {
KeyFile: "testdata/nonexistent_client.key", KeyFile: "testdata/nonexistent_client.key",
}, },
} }
_, err := NewHTTPClient(cfg) _, err := httputil.NewClientFromConfig(cfg)
if err == nil { if err == nil {
t.Fatalf("Expected error, got nil.") t.Fatalf("Expected error, got nil.")
} }

View file

@ -27,8 +27,8 @@ import (
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/retrieval"
"github.com/prometheus/prometheus/storage/metric" "github.com/prometheus/prometheus/storage/metric"
"github.com/prometheus/prometheus/util/httputil"
) )
// Client allows reading and writing from/to a remote HTTP endpoint. // Client allows reading and writing from/to a remote HTTP endpoint.
@ -47,7 +47,7 @@ type clientConfig struct {
// NewClient creates a new Client. // NewClient creates a new Client.
func NewClient(index int, conf *clientConfig) (*Client, error) { func NewClient(index int, conf *clientConfig) (*Client, error) {
httpClient, err := retrieval.NewHTTPClient(conf.httpClientConfig) httpClient, err := httputil.NewClientFromConfig(conf.httpClientConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -21,6 +21,7 @@ import (
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"strings"
"time" "time"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
@ -31,10 +32,42 @@ func NewClient(rt http.RoundTripper) *http.Client {
return &http.Client{Transport: rt} return &http.Client{Transport: rt}
} }
// NewDeadlineClient returns a new http.Client which will time out long running // NewClientFromConfig returns a new HTTP client configured for the
// requests. // given config.HTTPClientConfig.
func NewDeadlineClient(timeout time.Duration, proxyURL *url.URL) *http.Client { func NewClientFromConfig(cfg config.HTTPClientConfig) (*http.Client, error) {
return NewClient(NewDeadlineRoundTripper(timeout, proxyURL)) tlsConfig, err := NewTLSConfig(cfg.TLSConfig)
if err != nil {
return nil, err
}
// The only timeout we care about is the configured scrape timeout.
// It is applied on request. So we leave out any timings here.
var rt http.RoundTripper = &http.Transport{
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
DisableKeepAlives: true,
TLSClientConfig: tlsConfig,
}
// If a bearer token is provided, create a round tripper that will set the
// Authorization header correctly on each request.
bearerToken := cfg.BearerToken
if len(bearerToken) == 0 && len(cfg.BearerTokenFile) > 0 {
b, err := ioutil.ReadFile(cfg.BearerTokenFile)
if err != nil {
return nil, fmt.Errorf("unable to read bearer token file %s: %s", cfg.BearerTokenFile, err)
}
bearerToken = strings.TrimSpace(string(b))
}
if len(bearerToken) > 0 {
rt = NewBearerAuthRoundTripper(bearerToken, rt)
}
if cfg.BasicAuth != nil {
rt = NewBasicAuthRoundTripper(cfg.BasicAuth.Username, cfg.BasicAuth.Password, rt)
}
// Return a new client with the configured round tripper.
return NewClient(rt), nil
} }
// NewDeadlineRoundTripper returns a new http.RoundTripper which will time out // NewDeadlineRoundTripper returns a new http.RoundTripper which will time out
@ -119,6 +152,7 @@ func cloneRequest(r *http.Request) *http.Request {
return r2 return r2
} }
// NewTLSConfig creates a new tls.Config from the given config.TLSConfig.
func NewTLSConfig(cfg config.TLSConfig) (*tls.Config, error) { func NewTLSConfig(cfg config.TLSConfig) (*tls.Config, error) {
tlsConfig := &tls.Config{InsecureSkipVerify: cfg.InsecureSkipVerify} tlsConfig := &tls.Config{InsecureSkipVerify: cfg.InsecureSkipVerify}