package probe import "time" // PhaseStats holds min/avg/max for a phase across N samples. type PhaseStats struct { Min, Avg, Max time.Duration Present bool } // Aggregate holds per-phase statistics over a set of Results. type Aggregate struct { URL string Count int StatusCode int DNS PhaseStats Connect PhaseStats TLS PhaseStats TTFB PhaseStats Transfer PhaseStats Total PhaseStats } // Summarize computes min/avg/max per phase from a slice of Results. func Summarize(results []Result) Aggregate { a := Aggregate{Count: len(results)} if len(results) == 0 { return a } a.URL = results[0].URL a.StatusCode = results[len(results)-1].StatusCode a.DNS = phaseStats(results, func(r Result) Phase { return r.DNS }) a.Connect = phaseStats(results, func(r Result) Phase { return r.Connect }) a.TLS = phaseStats(results, func(r Result) Phase { return r.TLS }) a.TTFB = phaseStats(results, func(r Result) Phase { return r.TTFB }) a.Transfer = phaseStats(results, func(r Result) Phase { return r.Transfer }) a.Total = phaseStats(results, func(r Result) Phase { return r.Total }) return a } func phaseStats(results []Result, get func(Result) Phase) PhaseStats { var durations []time.Duration for _, r := range results { if p := get(r); p.Present { durations = append(durations, p.Duration) } } if len(durations) == 0 { return PhaseStats{} } min, max := durations[0], durations[0] var sum time.Duration for _, d := range durations { if d < min { min = d } if d > max { max = d } sum += d } return PhaseStats{ Min: min, Avg: sum / time.Duration(len(durations)), Max: max, Present: true, } }