observer: add TCP prober (#7118)
This is potentially useful for diagnosing issues with connection timeouts, which could have separate causes from HTTP errors. For instance, a connection timeout is more likely to be caused by network congestion or high CPU usage on the load balancer.
This commit is contained in:
parent
bba8fd31a6
commit
c84201c09a
|
@ -14,7 +14,7 @@ import (
|
||||||
// MonConf is exported to receive YAML configuration in `ObsConf`.
|
// MonConf is exported to receive YAML configuration in `ObsConf`.
|
||||||
type MonConf struct {
|
type MonConf struct {
|
||||||
Period config.Duration `yaml:"period"`
|
Period config.Duration `yaml:"period"`
|
||||||
Kind string `yaml:"kind" validate:"required,oneof=DNS HTTP CRL TLS"`
|
Kind string `yaml:"kind" validate:"required,oneof=DNS HTTP CRL TLS TCP"`
|
||||||
Settings probers.Settings `yaml:"settings" validate:"min=1,dive"`
|
Settings probers.Settings `yaml:"settings" validate:"min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
_ "github.com/letsencrypt/boulder/observer/probers/crl"
|
_ "github.com/letsencrypt/boulder/observer/probers/crl"
|
||||||
_ "github.com/letsencrypt/boulder/observer/probers/dns"
|
_ "github.com/letsencrypt/boulder/observer/probers/dns"
|
||||||
_ "github.com/letsencrypt/boulder/observer/probers/http"
|
_ "github.com/letsencrypt/boulder/observer/probers/http"
|
||||||
|
_ "github.com/letsencrypt/boulder/observer/probers/tcp"
|
||||||
_ "github.com/letsencrypt/boulder/observer/probers/tls"
|
_ "github.com/letsencrypt/boulder/observer/probers/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package tcp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TCPProbe struct {
|
||||||
|
hostport string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns a string that uniquely identifies the monitor.
|
||||||
|
|
||||||
|
func (p TCPProbe) Name() string {
|
||||||
|
return p.hostport
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kind returns a name that uniquely identifies the `Kind` of `Prober`.
|
||||||
|
func (p TCPProbe) Kind() string {
|
||||||
|
return "TCP"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probe performs the configured TCP dial.
|
||||||
|
func (p TCPProbe) Probe(timeout time.Duration) (bool, time.Duration) {
|
||||||
|
start := time.Now()
|
||||||
|
dialer := &net.Dialer{
|
||||||
|
Timeout: timeout,
|
||||||
|
FallbackDelay: -1,
|
||||||
|
}
|
||||||
|
c, err := dialer.Dial("tcp", p.hostport)
|
||||||
|
if err != nil {
|
||||||
|
return false, time.Since(start)
|
||||||
|
}
|
||||||
|
c.Close()
|
||||||
|
return true, time.Since(start)
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package tcp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/letsencrypt/boulder/observer/probers"
|
||||||
|
"github.com/letsencrypt/boulder/strictyaml"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TCPConf is exported to receive YAML configuration.
|
||||||
|
type TCPConf struct {
|
||||||
|
Hostport string `yaml:"hostport"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kind returns a name that uniquely identifies the `Kind` of `Configurer`.
|
||||||
|
func (c TCPConf) Kind() string {
|
||||||
|
return "TCP"
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalSettings takes YAML as bytes and unmarshals it to the to an
|
||||||
|
// TCPConf object.
|
||||||
|
func (c TCPConf) UnmarshalSettings(settings []byte) (probers.Configurer, error) {
|
||||||
|
var conf TCPConf
|
||||||
|
err := strictyaml.Unmarshal(settings, &conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return conf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeProber constructs a `TCPPProbe` object from the contents of the
|
||||||
|
// bound `TCPPConf` object.
|
||||||
|
func (c TCPConf) MakeProber(_ map[string]prometheus.Collector) (probers.Prober, error) {
|
||||||
|
return TCPProbe{c.Hostport}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instrument is a no-op to implement the `Configurer` interface.
|
||||||
|
func (c TCPConf) Instrument() map[string]prometheus.Collector {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// init is called at runtime and registers `TCPConf`, a `Prober`
|
||||||
|
// `Configurer` type, as "TCP".
|
||||||
|
func init() {
|
||||||
|
probers.Register(TCPConf{})
|
||||||
|
}
|
|
@ -83,9 +83,14 @@ monitors:
|
||||||
recurse: true
|
recurse: true
|
||||||
query_name: google.com
|
query_name: google.com
|
||||||
query_type: A
|
query_type: A
|
||||||
-
|
-
|
||||||
period: 2s
|
period: 2s
|
||||||
kind: HTTP
|
kind: HTTP
|
||||||
settings:
|
settings:
|
||||||
url: http://letsencrypt.org/foo
|
url: http://letsencrypt.org/foo
|
||||||
rcodes: [200, 404]
|
rcodes: [200, 404]
|
||||||
|
-
|
||||||
|
period: 10s
|
||||||
|
kind: TCP
|
||||||
|
settings:
|
||||||
|
hostport: acme-v02.api.letsencrypt.org:443
|
||||||
|
|
Loading…
Reference in New Issue