Skip to content

Commit

Permalink
improve error grouping
Browse files Browse the repository at this point in the history
  • Loading branch information
Tantalor93 committed Nov 26, 2023
1 parent 33a86dc commit db4ec8d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
23 changes: 20 additions & 3 deletions cmd/report.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package cmd

import (
"errors"
"fmt"
"io"
"net"
"os"
"sort"
"time"
Expand Down Expand Up @@ -51,10 +53,12 @@ func (b *Benchmark) PrintReport(w io.Writer, stats []*ResultStats, benchmarkDura

for _, s := range stats {
for _, err := range s.Errors {
if v, ok := errs[err.Error()]; ok {
errs[err.Error()] = v + 1
errorString := errString(err)

if v, ok := errs[errorString]; ok {
errs[errorString] = v + 1
} else {
errs[err.Error()] = 1
errs[errorString] = 1
}
}

Expand Down Expand Up @@ -166,6 +170,19 @@ func (b *Benchmark) PrintReport(w io.Writer, stats []*ResultStats, benchmarkDura
return s.print(params)
}

func errString(err ErrorDatapoint) string {
var errorString string
var netOpErr *net.OpError

switch {
case errors.As(err.Err, &netOpErr):
errorString = netOpErr.Op + " " + netOpErr.Net + " " + netOpErr.Addr.String()
default:
errorString = err.Err.Error()
}
return errorString
}

func (b *Benchmark) fileName(dir, name string) string {
return dir + "/" + name + "." + b.PlotFormat
}
Expand Down
42 changes: 30 additions & 12 deletions cmd/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"errors"
"net"
"os"
"time"

Expand Down Expand Up @@ -39,10 +40,11 @@ func ExampleBenchmark_PrintReport() {
// p75: 10ns
// p50: 5ns
//
// Total Errors: 3
// Total Errors: 6
// Top errors:
// test 2 (66.67)%
// test2 1 (33.33)%
// test2 3 (50.00)%
// read udp 8.8.8.8:53 2 (33.33)%
// test 1 (16.67)%
}

func ExampleBenchmark_PrintReport_dnssec() {
Expand Down Expand Up @@ -79,10 +81,11 @@ func ExampleBenchmark_PrintReport_dnssec() {
// p75: 10ns
// p50: 5ns
//
// Total Errors: 3
// Total Errors: 6
// Top errors:
// test 2 (66.67)%
// test2 1 (33.33)%
// test2 3 (50.00)%
// read udp 8.8.8.8:53 2 (33.33)%
// test 1 (16.67)%
}

func ExampleBenchmark_PrintReport_json() {
Expand All @@ -93,7 +96,7 @@ func ExampleBenchmark_PrintReport_json() {

b.PrintReport(os.Stdout, []*ResultStats{&rs}, time.Second)

// Output: {"totalRequests":1,"totalSuccessCodes":4,"totalErrors":3,"TotalIDmismatch":6,"totalTruncatedResponses":7,"responseRcodes":{"NOERROR":2},"questionTypes":{"A":2},"queriesPerSecond":1,"benchmarkDurationSeconds":1,"latencyStats":{"minMs":0,"meanMs":0,"stdMs":0,"maxMs":0,"p99Ms":0,"p95Ms":0,"p90Ms":0,"p75Ms":0,"p50Ms":0},"latencyDistribution":[{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1}]}
// Output: {"totalRequests":1,"totalSuccessCodes":4,"totalErrors":6,"TotalIDmismatch":6,"totalTruncatedResponses":7,"responseRcodes":{"NOERROR":2},"questionTypes":{"A":2},"queriesPerSecond":1,"benchmarkDurationSeconds":1,"latencyStats":{"minMs":0,"meanMs":0,"stdMs":0,"maxMs":0,"p99Ms":0,"p95Ms":0,"p90Ms":0,"p75Ms":0,"p50Ms":0},"latencyDistribution":[{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1}]}
}

func ExampleBenchmark_PrintReport_json_dnssec() {
Expand All @@ -106,7 +109,7 @@ func ExampleBenchmark_PrintReport_json_dnssec() {

b.PrintReport(os.Stdout, []*ResultStats{&rs}, time.Second)

// Output: {"totalRequests":1,"totalSuccessCodes":4,"totalErrors":3,"TotalIDmismatch":6,"totalTruncatedResponses":7,"responseRcodes":{"NOERROR":2},"questionTypes":{"A":2},"queriesPerSecond":1,"benchmarkDurationSeconds":1,"latencyStats":{"minMs":0,"meanMs":0,"stdMs":0,"maxMs":0,"p99Ms":0,"p95Ms":0,"p90Ms":0,"p75Ms":0,"p50Ms":0},"latencyDistribution":[{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1}],"totalDNSSECSecuredDomains":1}
// Output: {"totalRequests":1,"totalSuccessCodes":4,"totalErrors":6,"TotalIDmismatch":6,"totalTruncatedResponses":7,"responseRcodes":{"NOERROR":2},"questionTypes":{"A":2},"queriesPerSecond":1,"benchmarkDurationSeconds":1,"latencyStats":{"minMs":0,"meanMs":0,"stdMs":0,"maxMs":0,"p99Ms":0,"p95Ms":0,"p90Ms":0,"p75Ms":0,"p50Ms":0},"latencyDistribution":[{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":0},{"latencyMs":0,"count":1}],"totalDNSSECSecuredDomains":1}
}

func testData() (Benchmark, ResultStats) {
Expand All @@ -119,6 +122,18 @@ func testData() (Benchmark, ResultStats) {
h.RecordValue(10)
d1 := Datapoint{5, time.Unix(0, 0)}
d2 := Datapoint{10, time.Unix(0, 0)}
addr, err := net.ResolveUDPAddr("udp", "8.8.8.8:53")
if err != nil {
panic(err)
}
saddr1, err := net.ResolveUDPAddr("udp", "127.0.0.1:65359")
if err != nil {
panic(err)
}
saddr2, err := net.ResolveUDPAddr("udp", "127.0.0.1:65360")
if err != nil {
panic(err)
}
rs := ResultStats{
Codes: map[int]int64{
dns.RcodeSuccess: 2,
Expand All @@ -135,10 +150,13 @@ func testData() (Benchmark, ResultStats) {
IDmismatch: 6,
Truncated: 7,
},
Errors: []error{
errors.New("test"),
errors.New("test2"),
errors.New("test"),
Errors: []ErrorDatapoint{
{Start: time.Unix(0, 0), Err: errors.New("test2")},
{Start: time.Unix(0, 0), Err: errors.New("test")},
{Start: time.Unix(0, 0), Err: &net.OpError{Op: "read", Net: udpNetwork, Addr: addr, Source: saddr1}},
{Start: time.Unix(0, 0), Err: &net.OpError{Op: "read", Net: udpNetwork, Addr: addr, Source: saddr2}},
{Start: time.Unix(0, 0), Err: errors.New("test2")},
{Start: time.Unix(0, 0), Err: errors.New("test2")},
},
}
return b, rs
Expand Down
11 changes: 9 additions & 2 deletions cmd/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,28 @@ type Datapoint struct {
Start time.Time
}

// ErrorDatapoint one datapoint representing single IO error of benchmark.
// Datapoint one datapoint of benchmark (single DNS request).
type ErrorDatapoint struct {
Start time.Time
Err error
}

// ResultStats is a representation of benchmark results of single concurrent thread.
type ResultStats struct {
Codes map[int]int64
Qtypes map[string]int64
Hist *hdrhistogram.Histogram
Timings []Datapoint
Counters *Counters
Errors []error
Errors []ErrorDatapoint
AuthenticatedDomains map[string]struct{}
}

func (rs *ResultStats) record(req *dns.Msg, resp *dns.Msg, err error, time time.Time, timing time.Duration) {
if err != nil {
rs.Counters.IOError++
rs.Errors = append(rs.Errors, err)
rs.Errors = append(rs.Errors, ErrorDatapoint{time, err})
return
}

Expand Down

0 comments on commit db4ec8d

Please sign in to comment.