HTTP, HTTPS (via the `http` prober), DNS, TCP socket and ICMP (see permissions section) are currently supported.
Additional modules can be defined to meet your needs.
+The timeout of each probe is automatically determined from the `scrape_timeout` in the [Prometheus config](https://prometheus.io/docs/operating/configuration/#configuration-file), slightly reduced to allow for network delays.
+This can be further limited by the `timeout` in the Blackbox exporter config file. If neither is specified, it defaults to 10 seconds.
## Prometheus Configuration
package main
import (
+ "context"
"net"
"regexp"
+ "time"
"github.com/miekg/dns"
"github.com/prometheus/client_golang/prometheus"
return false
}
-func probeDNS(target string, module Module, registry *prometheus.Registry) bool {
+func probeDNS(ctx context.Context, target string, module Module, registry *prometheus.Registry) bool {
var numAnswer, numAuthority, numAdditional int
var dialProtocol string
probeDNSAnswerRRSGauge := prometheus.NewGauge(prometheus.GaugeOpts{
client := new(dns.Client)
client.Net = dialProtocol
- client.Timeout = module.Timeout
-
qt := dns.TypeANY
if module.DNS.QueryType != "" {
var ok bool
}
msg := new(dns.Msg)
msg.SetQuestion(dns.Fqdn(module.DNS.QueryName), qt)
+
+ timeoutDeadline, _ := ctx.Deadline()
+ client.Timeout = timeoutDeadline.Sub(time.Now())
+
response, _, err := client.Exchange(msg, target)
if err != nil {
log.Warnf("Error while sending a DNS query: %s", err)
package main
import (
+ "context"
"net"
"runtime"
"testing"
test.Probe.TransportProtocol = protocol
registry := prometheus.NewPedanticRegistry()
registry.Gather()
- result := probeDNS(addr.String(), Module{Timeout: time.Second, DNS: test.Probe}, registry)
+
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeDNS(testCTX, addr.String(), Module{Timeout: time.Second, DNS: test.Probe}, registry)
if result != test.ShouldSucceed {
t.Fatalf("Test %d had unexpected result: %v", i, result)
}
for i, test := range tests {
test.Probe.TransportProtocol = protocol
registry := prometheus.NewRegistry()
- result := probeDNS(addr.String(), Module{Timeout: time.Second, DNS: test.Probe}, registry)
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeDNS(testCTX, addr.String(), Module{Timeout: time.Second, DNS: test.Probe}, registry)
if result != test.ShouldSucceed {
t.Fatalf("Test %d had unexpected result: %v", i, result)
}
for i, test := range tests {
test.Probe.TransportProtocol = protocol
registry := prometheus.NewRegistry()
- result := probeDNS(addr.String(), Module{Timeout: time.Second, DNS: test.Probe}, registry)
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeDNS(testCTX, addr.String(), Module{Timeout: time.Second, DNS: test.Probe}, registry)
if result != test.ShouldSucceed {
t.Fatalf("Test %d had unexpected result: %v", i, result)
}
},
}
registry := prometheus.NewRegistry()
- result := probeDNS(net.JoinHostPort("localhost", port), module, registry)
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeDNS(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("DNS protocol: \"%v4\" connection test failed, expected success.", protocol)
}
},
}
registry = prometheus.NewRegistry()
- result = probeDNS(net.JoinHostPort("localhost", port), module, registry)
+ testCTX, cancel = context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result = probeDNS(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("DNS protocol: \"%v6\" connection test failed, expected success.", protocol)
}
},
}
registry = prometheus.NewRegistry()
- result = probeDNS(net.JoinHostPort("localhost", port), module, registry)
+ testCTX, cancel = context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result = probeDNS(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("DNS protocol: \"%v\", preferred \"ip6\" connection test failed, expected success.", protocol)
}
},
}
registry = prometheus.NewRegistry()
- result = probeDNS(net.JoinHostPort("localhost", port), module, registry)
+ testCTX, cancel = context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result = probeDNS(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("DNS protocol: \"%v\", preferred \"ip4\" connection test failed, expected success.", protocol)
}
},
}
registry = prometheus.NewRegistry()
- result = probeDNS(net.JoinHostPort("localhost", port), module, registry)
+ testCTX, cancel = context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result = probeDNS(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("DNS protocol: \"%v\" connection test failed, expected success.", protocol)
}
},
}
registry = prometheus.NewRegistry()
- result = probeDNS(net.JoinHostPort("localhost", port), module, registry)
+ testCTX, cancel = context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result = probeDNS(testCTX, net.JoinHostPort("localhost", port), module, registry)
if protocol == "udp" {
if !result {
t.Fatalf("DNS test connection with protocol %s failed, expected success.", protocol)
package main
import (
+ "context"
"errors"
"io"
"io/ioutil"
return true
}
-func probeHTTP(target string, module Module, registry *prometheus.Registry) (success bool) {
+func probeHTTP(ctx context.Context, target string, module Module, registry *prometheus.Registry) (success bool) {
var redirects int
-
var (
contentLengthGauge = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "content_length",
log.Errorf("Error generating HTTP client: %v", err)
return false
}
- client.Timeout = module.Timeout
client.CheckRedirect = func(_ *http.Request, via []*http.Request) error {
redirects = len(via)
request, err := http.NewRequest(httpConfig.Method, target, nil)
request.Host = targetURL.Host
+ request = request.WithContext(ctx)
if targetPort == "" {
targetURL.Host = ip.String()
} else {
request.Header.Set(key, value)
}
- // If a body is configured, add it to the request
+ // If a body is configured, add it to the request.
if httpConfig.Body != "" {
request.Body = ioutil.NopCloser(strings.NewReader(httpConfig.Body))
}
resp, err := client.Do(request)
// Err won't be nil if redirects were turned off. See https://github.com/golang/go/issues/3795
if err != nil && resp == nil {
- log.Warnf("Error for HTTP request to %s: %s", target, err)
+ log.Errorf("Error for HTTP request to %s: %s", target, err)
+ success = false
} else {
defer resp.Body.Close()
if len(httpConfig.ValidStatusCodes) != 0 {
package main
import (
+ "context"
"fmt"
"net/http"
"net/http/httptest"
defer ts.Close()
registry := prometheus.NewRegistry()
recorder := httptest.NewRecorder()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{ValidStatusCodes: test.ValidStatusCodes}}, registry)
body := recorder.Body.String()
if result != test.ShouldSucceed {
defer ts.Close()
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ result := probeHTTP(context.Background(), ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{
ValidHTTPVersions: test.ValidHTTPVersions,
}}, registry)
// Follow redirect, should succeed with 200.
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{}}, registry)
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{}}, registry)
body := recorder.Body.String()
if !result {
t.Fatalf("Redirect test failed unexpectedly, got %s", body)
// Follow redirect, should succeed with 200.
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{NoFollowRedirects: true, ValidStatusCodes: []int{302}}}, registry)
body := recorder.Body.String()
if !result {
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{Method: "POST"}}, registry)
body := recorder.Body.String()
if !result {
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{
HTTPClientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{InsecureSkipVerify: false},
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{
HTTPClientConfig: config.HTTPClientConfig{
BearerToken: config.Secret("mysecret"),
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfNotSSL: true}}, registry)
body := recorder.Body.String()
if result {
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfMatchesRegexp: []string{"could not connect to database"}}}, registry)
body := recorder.Body.String()
if result {
recorder = httptest.NewRecorder()
registry = prometheus.NewRegistry()
- result = probeHTTP(ts.URL,
+ result = probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfMatchesRegexp: []string{"could not connect to database"}}}, registry)
body = recorder.Body.String()
if !result {
recorder = httptest.NewRecorder()
registry = prometheus.NewRegistry()
- result = probeHTTP(ts.URL,
+ result = probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfMatchesRegexp: []string{"could not connect to database", "internal error"}}}, registry)
body = recorder.Body.String()
if result {
recorder = httptest.NewRecorder()
registry = prometheus.NewRegistry()
- result = probeHTTP(ts.URL,
+ result = probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfMatchesRegexp: []string{"could not connect to database", "internal error"}}}, registry)
body = recorder.Body.String()
if !result {
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfNotMatchesRegexp: []string{"Download the latest version here"}}}, registry)
body := recorder.Body.String()
if result {
recorder = httptest.NewRecorder()
registry = prometheus.NewRegistry()
- result = probeHTTP(ts.URL,
+ result = probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfNotMatchesRegexp: []string{"Download the latest version here"}}}, registry)
body = recorder.Body.String()
if !result {
recorder = httptest.NewRecorder()
registry = prometheus.NewRegistry()
- result = probeHTTP(ts.URL,
+ result = probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfNotMatchesRegexp: []string{"Download the latest version here", "Copyright 2015"}}}, registry)
body = recorder.Body.String()
if result {
recorder = httptest.NewRecorder()
registry = prometheus.NewRegistry()
- result = probeHTTP(ts.URL,
+ result = probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{FailIfNotMatchesRegexp: []string{"Download the latest version here", "Copyright 2015"}}}, registry)
body = recorder.Body.String()
if !result {
}))
defer ts.Close()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{
Headers: headers,
}}, registry)
if !result {
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{
HTTPClientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{InsecureSkipVerify: false},
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{
HTTPClientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{InsecureSkipVerify: true},
recorder := httptest.NewRecorder()
registry := prometheus.NewRegistry()
- result := probeHTTP(ts.URL,
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ result := probeHTTP(testCTX, ts.URL,
Module{Timeout: time.Second, HTTP: HTTPProbe{
HTTPClientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{InsecureSkipVerify: false},
import (
"bytes"
+ "context"
"net"
"os"
"sync"
return icmpSequence
}
-func probeICMP(target string, module Module, registry *prometheus.Registry) (success bool) {
+func probeICMP(ctx context.Context, target string, module Module, registry *prometheus.Registry) (success bool) {
var (
socket *icmp.PacketConn
requestType icmp.Type
replyType icmp.Type
)
-
- deadline := time.Now().Add(module.Timeout)
+ timeoutDeadline, _ := ctx.Deadline()
+ deadline := time.Now().Add(timeoutDeadline.Sub(time.Now()))
ip, err := chooseProtocol(module.ICMP.PreferredIPProtocol, target, registry)
if err != nil {
package main
import (
+ "context"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/signal"
+ "strconv"
"syscall"
"time"
"github.com/prometheus/common/version"
)
-var Probers = map[string]func(string, Module, *prometheus.Registry) bool{
+var (
+ sc = &SafeConfig{
+ C: &Config{},
+ }
+ configFile = flag.String("config.file", "blackbox.yml", "Blackbox exporter configuration file.")
+ listenAddress = flag.String("web.listen-address", ":9115", "The address to listen on for HTTP requests.")
+ showVersion = flag.Bool("version", false, "Print version information.")
+ timeoutOffset = flag.Float64("timeout-offset", 0.5, "Offset to subtract from timeout in seconds.")
+)
+
+var Probers = map[string]func(context.Context, string, Module, *prometheus.Registry) bool{
"http": probeHTTP,
"tcp": probeTCP,
"icmp": probeICMP,
return nil
}
-func probeHandler(w http.ResponseWriter, r *http.Request, conf *Config) {
+func probeHandler(w http.ResponseWriter, r *http.Request, c *Config) {
+
+ moduleName := r.URL.Query().Get("module")
+ if moduleName == "" {
+ moduleName = "http_2xx"
+ }
+ module, ok := c.Modules[moduleName]
+ if !ok {
+ http.Error(w, fmt.Sprintf("Unknown module %q", moduleName), 400)
+ return
+ }
+
+ // If a timeout is configured via the Prometheus header, add it to the request.
+ var prometheusTimeout string
+ if r.Header["X-Prometheus-Scrape-Timeout-Seconds"] != nil {
+ prometheusTimeout = r.Header["X-Prometheus-Scrape-Timeout-Seconds"][0]
+ }
+
+ timeoutSeconds, err := strconv.ParseFloat(prometheusTimeout, 64)
+ if err != nil {
+ http.Error(w, fmt.Sprintf("Failed to parse timeout from Prometheus header: %s", err), http.StatusInternalServerError)
+ return
+ }
+ if timeoutSeconds == 0 {
+ timeoutSeconds = 10
+ }
+
+ if module.Timeout.Seconds() < timeoutSeconds && module.Timeout.Seconds() > 0 {
+ timeoutSeconds = module.Timeout.Seconds()
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), time.Duration((timeoutSeconds-*timeoutOffset)*1e9))
+ defer cancel()
+ r = r.WithContext(ctx)
+
probeSuccessGauge := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "probe_success",
Help: "Displays whether or not the probe was a success",
return
}
- moduleName := params.Get("module")
- if moduleName == "" {
- moduleName = "http_2xx"
- }
- module, ok := conf.Modules[moduleName]
- if !ok {
- http.Error(w, fmt.Sprintf("Unknown module %q", moduleName), 400)
- return
- }
prober, ok := Probers[module.Prober]
if !ok {
http.Error(w, fmt.Sprintf("Unknown prober %q", module.Prober), 400)
registry := prometheus.NewRegistry()
registry.MustRegister(probeSuccessGauge)
registry.MustRegister(probeDurationGauge)
- success := prober(target, module, registry)
+ success := prober(ctx, target, module, registry)
probeDurationGauge.Set(time.Since(start).Seconds())
if success {
probeSuccessGauge.Set(1)
}
func main() {
-
- var (
- configFile = flag.String("config.file", "blackbox.yml", "Blackbox exporter configuration file.")
- listenAddress = flag.String("web.listen-address", ":9115", "The address to listen on for HTTP requests.")
- showVersion = flag.Bool("version", false, "Print version information.")
- sc = &SafeConfig{
- C: &Config{},
- }
- )
flag.Parse()
if *showVersion {
}
}()
- http.Handle("/metrics", prometheus.Handler())
- http.HandleFunc("/probe",
- func(w http.ResponseWriter, r *http.Request) {
- sc.RLock()
- c := sc.C
- sc.RUnlock()
-
- probeHandler(w, r, c)
- })
http.HandleFunc("/-/reload",
func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, fmt.Sprintf("failed to reload config: %s", err), http.StatusInternalServerError)
}
})
-
+ http.Handle("/metrics", prometheus.Handler())
+ http.HandleFunc("/probe", func(w http.ResponseWriter, r *http.Request) {
+ sc.Lock()
+ conf := sc.C
+ sc.Unlock()
+ probeHandler(w, r, conf)
+ })
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<html>
<head><title>Blackbox Exporter</title></head>
--- /dev/null
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+ "time"
+)
+
+var c = &Config{
+ Modules: map[string]Module{
+ "http_2xx": Module{
+ Prober: "http",
+ Timeout: 10 * time.Second,
+ },
+ },
+}
+
+func TestPrometheusTimeout(t *testing.T) {
+
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ time.Sleep(2 * time.Second)
+ }))
+ defer ts.Close()
+
+ req, err := http.NewRequest("GET", "?target="+ts.URL, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ req.Header.Set("X-Prometheus-Scrape-Timeout-Seconds", "1")
+
+ rr := httptest.NewRecorder()
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ probeHandler(w, r, c)
+ })
+
+ handler.ServeHTTP(rr, req)
+
+ if status := rr.Code; status != http.StatusOK {
+ t.Errorf("probe request handler returned wrong status code: %v, want %v", status, http.StatusOK)
+ }
+}
import (
"bufio"
+ "context"
"crypto/tls"
"fmt"
"net"
"github.com/prometheus/common/log"
)
-func dialTCP(target string, module Module, registry *prometheus.Registry) (net.Conn, error) {
+func dialTCP(ctx context.Context, target string, module Module, registry *prometheus.Registry) (net.Conn, error) {
var dialProtocol, dialTarget string
- dialer := &net.Dialer{Timeout: module.Timeout}
-
+ dialer := &net.Dialer{}
targetAddress, port, err := net.SplitHostPort(target)
if err != nil {
log.Errorf("Error splitting target address and port: %v", err)
dialTarget = net.JoinHostPort(ip.String(), port)
if !module.TCP.TLS {
- return dialer.Dial(dialProtocol, dialTarget)
+ return dialer.DialContext(ctx, dialProtocol, dialTarget)
}
tlsConfig, err := config.NewTLSConfig(&module.TCP.TLSConfig)
if err != nil {
log.Errorf("Error creating TLS configuration: %v", err)
return nil, err
}
+ timeoutDeadline, _ := ctx.Deadline()
+ dialer.Deadline = timeoutDeadline
+
return tls.DialWithDialer(dialer, dialProtocol, dialTarget, tlsConfig)
}
-func probeTCP(target string, module Module, registry *prometheus.Registry) bool {
+func probeTCP(ctx context.Context, target string, module Module, registry *prometheus.Registry) bool {
probeSSLEarliestCertExpiry := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "probe_ssl_earliest_cert_expiry",
Help: "Returns earliest SSL cert expiry date",
})
- registry.MustRegister(probeSSLEarliestCertExpiry)
deadline := time.Now().Add(module.Timeout)
- conn, err := dialTCP(target, module, registry)
+ conn, err := dialTCP(ctx, target, module, registry)
if err != nil {
log.Errorf("Error dialing TCP: %v", err)
return false
}
if module.TCP.TLS {
state := conn.(*tls.Conn).ConnectionState()
+ registry.MustRegister(probeSSLEarliestCertExpiry)
probeSSLEarliestCertExpiry.Set(float64(getEarliestCertExpiry(&state).UnixNano()) / 1e9)
}
scanner := bufio.NewScanner(conn)
package main
import (
+ "context"
"fmt"
"net"
"runtime"
conn.Close()
ch <- struct{}{}
}()
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
registry := prometheus.NewRegistry()
- if !probeTCP(ln.Addr().String(), Module{Timeout: time.Second}, registry) {
+ if !probeTCP(testCTX, ln.Addr().String(), Module{Timeout: time.Second}, registry) {
t.Fatalf("TCP module failed, expected success.")
}
<-ch
func TestTCPConnectionFails(t *testing.T) {
// Invalid port number.
registry := prometheus.NewRegistry()
- if probeTCP(":0", Module{Timeout: time.Second}, registry) {
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ if probeTCP(testCTX, ":0", Module{Timeout: time.Second}, registry) {
t.Fatalf("TCP module suceeded, expected failure.")
}
}
}
defer ln.Close()
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
module := Module{
Timeout: time.Second,
TCP: TCPProbe{
ch <- struct{}{}
}()
registry := prometheus.NewRegistry()
- if !probeTCP(ln.Addr().String(), module, registry) {
+ if !probeTCP(testCTX, ln.Addr().String(), module, registry) {
t.Fatalf("TCP module failed, expected success.")
}
<-ch
ch <- struct{}{}
}()
registry = prometheus.NewRegistry()
- if probeTCP(ln.Addr().String(), module, registry) {
+ if probeTCP(testCTX, ln.Addr().String(), module, registry) {
t.Fatalf("TCP module succeeded, expected failure.")
}
<-ch
}
defer ln.Close()
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
module := Module{
Timeout: time.Second,
TCP: TCPProbe{
ch <- version
}()
registry := prometheus.NewRegistry()
- if !probeTCP(ln.Addr().String(), module, registry) {
+ if !probeTCP(testCTX, ln.Addr().String(), module, registry) {
t.Fatalf("TCP module failed, expected success.")
}
if got, want := <-ch, "OpenSSH_6.9p1"; got != want {
}
defer ln.Close()
+ testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
_, port, _ := net.SplitHostPort(ln.Addr().String())
// Force IPv4
}
registry := prometheus.NewRegistry()
- result := probeTCP(net.JoinHostPort("localhost", port), module, registry)
+ result := probeTCP(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("TCP protocol: \"tcp4\" connection test failed, expected success.")
}
}
registry = prometheus.NewRegistry()
- result = probeTCP(net.JoinHostPort("localhost", port), module, registry)
+ result = probeTCP(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("TCP protocol: \"tcp6\" connection test failed, expected success.")
}
}
registry = prometheus.NewRegistry()
- result = probeTCP(net.JoinHostPort("localhost", port), module, registry)
+ result = probeTCP(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("TCP protocol: \"tcp\", prefer: \"ip4\" connection test failed, expected success.")
}
}
registry = prometheus.NewRegistry()
- result = probeTCP(net.JoinHostPort("localhost", port), module, registry)
+ result = probeTCP(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("TCP protocol: \"tcp\", prefer: \"ip6\" connection test failed, expected success.")
}
}
registry = prometheus.NewRegistry()
- result = probeTCP(net.JoinHostPort("localhost", port), module, registry)
+ result = probeTCP(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("TCP protocol: \"tcp\" connection test failed, expected success.")
}
}
registry = prometheus.NewRegistry()
- result = probeTCP(net.JoinHostPort("localhost", port), module, registry)
+ result = probeTCP(testCTX, net.JoinHostPort("localhost", port), module, registry)
if !result {
t.Fatalf("TCP connection test with protocol unspecified failed, expected success.")
}