Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions dns/dnsperfgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"flag"
"fmt"
"log"
"log/slog"
"net"
"net/http"
"os"
Expand All @@ -39,10 +40,10 @@ import (
const clusterDomain = "cluster.local"

type Config struct {
qps int
testDuration, idleDuration, queryTimeout time.Duration
hostnameFile string
queryClusterNames, logQueries bool
qps int
testDuration, idleDuration, queryTimeout time.Duration
hostnameFile string
queryClusterNames, logQueries, enableLatencyLogging bool
}

type dnsClient struct {
Expand All @@ -59,6 +60,13 @@ type dnsClient struct {

type LookupFunc func(string) ([]string, error)

var (
// infoLogger writes to stdout, initialized if flag is set.
infoLogger *slog.Logger
// errorLogger writes to stderr, initialized if flag is set.
errorLogger *slog.Logger
)

func main() {
config := Config{}
flag.IntVar(&config.qps, "qps", 10, "The number of DNS queries per second to issue")
Expand All @@ -68,8 +76,12 @@ func main() {
flag.StringVar(&config.hostnameFile, "inputfile", "", "Path to the file containing hostnames to lookup. Hostnames should be newline-separated.")
flag.BoolVar(&config.queryClusterNames, "query-cluster-names", false, "Indicates whether the query names should be the service names in the cluster.")
flag.BoolVar(&config.logQueries, "log-queries", false, "Indicates whether each query should be logged.")

flag.BoolVar(&config.enableLatencyLogging, "enable-latency-logging", false, "Indicate whether to enable structured logging for each DNS lookup latency.")
flag.Parse()
if config.enableLatencyLogging {
infoLogger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
}
errorLogger = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError}))
log.Printf("Starting dnstest with config parameters - %+v", config)
client := &dnsClient{config: &config, stopChan: make(chan os.Signal, 1)}
signal.Notify(client.stopChan, syscall.SIGTERM)
Expand Down Expand Up @@ -199,7 +211,7 @@ func (c *dnsClient) logResults() {

}

func (c *dnsClient) updateResults(timedOut bool, err error) {
func (c *dnsClient) updateResults(timedOut bool, err error, name string) {
c.resultsLock.Lock()
defer c.resultsLock.Unlock()
if err != nil {
Expand All @@ -223,6 +235,12 @@ func (c *dnsClient) runQuery(name string, timeout time.Duration, lookupFunc Look
startTime := time.Now()
_, err := lookupFunc(name)
latency := time.Since(startTime)
if infoLogger != nil && err == nil {
infoLogger.Info("DNS lookup successful, latency recorded",
"hostname", name,
"latency_seconds", latency.Seconds(),
)
}
dnsLatency.Observe(latency.Seconds())
resultChan <- err
}(resultChan)
Expand All @@ -235,9 +253,13 @@ func (c *dnsClient) runQuery(name string, timeout time.Duration, lookupFunc Look
log.Printf("DNS lookup of name %q, err - %v\n", name, err)
}
if err != nil {
log.Printf("Failed DNS lookup of name %q, err - %v\n", name, err)
errorLogger.Error("Failed DNS lookup",
"hostname", name,
"error", err.Error(),
"timed_out", timedOut,
)
}
c.updateResults(timedOut, err)
c.updateResults(timedOut, err, name)
}()

for {
Expand Down