Documentation
¶
Overview ¶
Package libtower provides network health-check primitives for Go.
It covers TCP dials, TLS handshakes (with client certificates), HTTP status checks, per-phase HTTP timing traces, TLS certificate validation with expiry warnings, DNS resolution (both system resolver and direct queries), ICMP ping, and WebSocket connectivity.
Common pattern ¶
Every check follows the same pattern: create a struct, set its input fields, call its method (which records Start, End, and Duration), and read the result. All I/O methods accept a context.Context.
Checker interface ¶
All check types implement the Checker interface, returning a Result:
checks := []Checker{
&TCP{URL: u, Timeout: time.Second},
&HTTPS{Host: "example.com", WarnIfExpiringWithin: 30 * 24 * time.Hour},
&DNS{ADDR: "example.com"},
}
for _, c := range checks {
r := c.Check(ctx)
if !r.OK { log.Fatal(r.Error) }
}
Context variants ¶
Short-form functions (Ping, DNSLookup) use context.Background internally. Use the ...Context variants (PingContext, DNSLookupContext) for cancellation and timeouts:
ip, dur, err := libtower.PingContext(ctx, "example.com", 1)
Root requirement ¶
Ping and PingContext require raw ICMP sockets, which need root privileges (or CAP_NET_RAW on Linux). All other checks work without special permissions.
Index ¶
- Constants
- func DNSLookup(addr string) (*net.IPAddr, time.Duration, error)
- func DNSLookupContext(ctx context.Context, addr string) (*net.IPAddr, time.Duration, error)
- func DNSLookupFrom(addr string, server string) (*net.IPAddr, time.Duration, error)
- func DNSLookupFromContext(ctx context.Context, addr string, server string) (*net.IPAddr, time.Duration, error)
- func Ping(addr string, seq int) (*net.IPAddr, time.Duration, error)
- func PingContext(ctx context.Context, addr string, seq int) (*net.IPAddr, time.Duration, error)
- type CertData
- type CertExpiringWarning
- type CheckData
- type Checker
- type DNS
- type DNSData
- type HTTP
- type HTTPS
- type HTTPTrace
- type PingCheck
- type PingData
- type Result
- type TCP
- type Time
- type Timeout
- type WebSocket
Examples ¶
Constants ¶
const ( // ProtocolICMP DSCP IPv4ProtocolICMP = 1 IPv6ProtocolICMP = 58 )
const DefaultHTTPSPort = "443"
Variables ¶
This section is empty.
Functions ¶
func DNSLookup ¶
DNSLookup func
Example ¶
package main
import (
"fmt"
"github.com/mismatched/libtower"
)
func main() {
ip, dur, err := libtower.DNSLookup("example.com")
fmt.Println("ip:", ip, "duration:", dur, "err:", err)
}
Output:
func DNSLookupContext ¶
DNSLookupContext resolves addr via the default resolver, respecting ctx cancellation.
func DNSLookupFrom ¶
DNSLookupFrom func
func DNSLookupFromContext ¶
func DNSLookupFromContext(ctx context.Context, addr string, server string) (*net.IPAddr, time.Duration, error)
DNSLookupFromContext performs a direct DNS query to server, respecting ctx cancellation.
func Ping ¶
Ping sends an ICMP echo request to addr and returns the resolved address, round-trip time, and any error.
Requires root privileges (or CAP_NET_RAW on Linux) for raw ICMP sockets. Without root, this returns "socket: operation not permitted". Use -tags offline for rootless testing.
Example ¶
package main
import (
"fmt"
"github.com/mismatched/libtower"
)
func main() {
ip, dur, err := libtower.Ping("example.com", 1)
fmt.Println("ip:", ip, "rtt:", dur, "err:", err)
}
Output:
func PingContext ¶
PingContext sends an ICMP echo request to addr, respecting ctx cancellation.
Requires root privileges (or CAP_NET_RAW on Linux) for raw ICMP sockets. Without root, this returns "socket: operation not permitted". Use -tags offline for rootless testing.
Types ¶
type CertExpiringWarning ¶
CertExpiringWarning is returned as Result.Warning when a certificate is expiring soon.
func (*CertExpiringWarning) Error ¶
func (w *CertExpiringWarning) Error() string
type CheckData ¶
type CheckData interface {
// Kind returns a short identifier for the check type.
Kind() string
}
CheckData is implemented by types carrying check-specific result data.
type Checker ¶
Checker is implemented by types that can perform a health check.
Example ¶
package main
import (
"context"
"fmt"
"net/url"
"time"
"github.com/mismatched/libtower"
)
func main() {
u, _ := url.Parse("tcp://example.com:443")
checks := []libtower.Checker{
&libtower.TCP{URL: u, Timeout: time.Second},
&libtower.DNS{ADDR: "example.com"},
}
for _, c := range checks {
r := c.Check(context.Background())
fmt.Printf("%T ok=%v duration=%v\n", c, r.OK, r.Duration)
}
}
Output:
type DNS ¶
type DNS struct {
ADDR string
Timeout time.Duration
Start time.Time
End time.Time
Duration time.Duration
}
DNS type
type HTTP ¶
type HTTP struct {
URL string
Method string
Timeout Timeout
Status string // e.g. "200 OK"
StatusCode int
Proto string // e.g. "HTTP/1.0"
ProtoMajor int // e.g. 1
ProtoMinor int // e.g. 0
Header map[string][]string
Body []byte
ContentLength int64
TransferEncoding []string
Close bool
Uncompressed bool
Trailer map[string][]string
Time
}
HTTP type
type HTTPS ¶
type HTTPS struct {
Host string
Port string
Timeout time.Duration
InsecureSkipVerify bool
// WarnIfExpiringWithin, when > 0, triggers a Result.Warning if the
// earliest certificate NotAfter falls within this window from now.
WarnIfExpiringWithin time.Duration
Start time.Time
End time.Time
Duration time.Duration
}
HTTPS type
func (*HTTPS) Check ¶
Check performs a TLS certificate check.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/mismatched/libtower"
)
func main() {
hs := &libtower.HTTPS{
Host: "example.com",
Timeout: 5 * time.Second,
WarnIfExpiringWithin: 30 * 24 * time.Hour,
}
r := hs.Check(context.Background())
fmt.Println("ok:", r.OK)
if r.Data != nil {
certData := r.Data.(libtower.CertData)
fmt.Println("notAfter:", certData.NotAfter.Format(time.RFC3339))
}
if r.Warning != nil {
fmt.Println("warning:", r.Warning)
}
}
Output:
type HTTPTrace ¶
type HTTPTrace struct {
URL string
Method string
DNS time.Duration
TLSHandshake time.Duration
Connect time.Duration
GotFirstResponseByte time.Duration
Total time.Duration
Time
}
HTTPTrace type
type Result ¶
type Result struct {
OK bool
Duration time.Duration
Data CheckData // check-specific data, nil if none
Warning error // non-nil when the check passed but with a warning (e.g., cert expiring soon)
Error error
}
Result is the unified return type for all health checks.
type TCP ¶
type TCP struct {
URL *url.URL
Timeout time.Duration
CertFile string
PrivateKeyFile string
Start time.Time
End time.Time
Duration time.Duration
}
TCP type
func (*TCP) TCPPortCheck ¶
TCPPortCheck checks if a tcp port is open
Example ¶
package main
import (
"context"
"fmt"
"net/url"
"time"
"github.com/mismatched/libtower"
)
func main() {
u, _ := url.Parse("tcp://example.com:443")
tcp := &libtower.TCP{URL: u, Timeout: 5 * time.Second}
ok, err := tcp.TCPPortCheck(context.Background())
fmt.Println("ok:", ok, "err:", err)
}
Output:
type WebSocket ¶
type WebSocket struct {
URL string
Timeout time.Duration
Start time.Time
End time.Time
Duration time.Duration
}
WebSocket type
func (*WebSocket) WSCheck ¶
WSCheck performs a WebSocket health check by dialing and verifying the upgrade.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/mismatched/libtower"
)
func main() {
ws := &libtower.WebSocket{
URL: "ws://echo.example.com",
Timeout: 5 * time.Second,
}
err := ws.WSCheck(context.Background())
fmt.Println("err:", err)
}
Output: