func compilerProxyLogSummary(w http.ResponseWriter, logPath string, cpl *compilerproxylog.CompilerProxyLog) error { data := struct { Path string CompilerProxyLog *compilerproxylog.CompilerProxyLog Tasks []*compilerproxylog.TaskLog NumTasks int TasksPerSec float64 ByCompileMode map[compilerproxylog.CompileMode]byCompileMode DurationDistribution []time.Duration }{ Path: logPath, CompilerProxyLog: cpl, Tasks: cpl.TaskLogs(), ByCompileMode: make(map[compilerproxylog.CompileMode]byCompileMode), } data.NumTasks = len(data.Tasks) data.TasksPerSec = float64(data.NumTasks) / cpl.Duration().Seconds() var duration time.Duration for _, t := range data.Tasks { duration += t.Duration() } tasksByCompileMode := compilerproxylog.ClassifyByCompileMode(data.Tasks) for m, tasks := range tasksByCompileMode { mode := compilerproxylog.CompileMode(m) sort.Sort(sort.Reverse(compilerproxylog.ByDuration{TaskLogs: tasks})) bcm := byCompileMode{ Tasks: tasks, NumTasks: len(tasks), } if len(tasks) == 0 { data.ByCompileMode[mode] = bcm continue } if len(bcm.Tasks) > 10 { bcm.Tasks = bcm.Tasks[:10] } tr := compilerproxylog.ClassifyByResponse(tasks) var resps []string for r := range tr { resps = append(resps, r) } sort.Strings(resps) for _, r := range resps { bcm.Resps = append(bcm.Resps, struct { Response string Num int }{ Response: r, Num: len(tr[r]), }) } var duration time.Duration for _, t := range tasks { duration += t.Duration() } bcm.Average = duration / time.Duration(len(tasks)) bcm.Max = tasks[0].Duration() for _, p := range []int{98, 91, 75, 50, 25, 9, 2} { bcm.P = append(bcm.P, struct { P int D time.Duration }{ P: p, D: tasks[int(float64(len(tasks)*(100-p))/100.0)].Duration(), }) } bcm.Min = tasks[len(tasks)-1].Duration() data.ByCompileMode[mode] = bcm } data.DurationDistribution = compilerproxylog.DurationDistribution(cpl.Created, data.Tasks) var buf bytes.Buffer err := compilerProxyLogIndexTempl.Execute(&buf, data) if err != nil { return err } w.Header().Set("Content-Type", "text/html") _, err = w.Write(buf.Bytes()) return err }
func diagnose(fname string) { f, err := os.Open(fname) if err != nil { log.Fatal(err) } defer f.Close() rd, err := reader(fname, f) if err != nil { log.Fatal(err) } cpl, err := compilerproxylog.Parse(fname, rd) if err != nil { log.Fatal(err) } fmt.Println("Filename:", cpl.Filename) fmt.Println("Created:", cpl.Created) fmt.Println("Machine:", cpl.Machine) fmt.Println("GomaRevision:", cpl.GomaRevision) fmt.Println("GomaVersion:", cpl.GomaVersion) fmt.Println("GomaFlags:", cpl.GomaFlags) fmt.Println("GomaLimits:", cpl.GomaLimits) fmt.Println("CrashDump:", cpl.CrashDump) fmt.Println("Stats:", cpl.Stats) fmt.Println("") fmt.Println("duration:", cpl.Duration()) tasks := cpl.TaskLogs() fmt.Println("tasks:", len(tasks)) fmt.Println("tasks/sec:", float64(len(tasks))/cpl.Duration().Seconds()) fmt.Println("") var duration time.Duration for _, t := range tasks { duration += t.Duration() } tasksByCompileMode := compilerproxylog.ClassifyByCompileMode(tasks) for i, tasks := range tasksByCompileMode { mode := compilerproxylog.CompileMode(i) fmt.Println(mode, ": # of tasks: ", len(tasks)) if len(tasks) == 0 { fmt.Println("") continue } tr := compilerproxylog.ClassifyByResponse(tasks) var resps []string for r := range tr { resps = append(resps, r) } fmt.Println(" replies:") for _, r := range resps { fmt.Println(" ", r, len(tr[r])) } sort.Sort(sort.Reverse(compilerproxylog.ByDuration{TaskLogs: tasks})) var duration time.Duration for _, t := range tasks { duration += t.Duration() } fmt.Println(" durations:") fmt.Println(" ave :", duration/time.Duration(len(tasks))) fmt.Println(" max :", tasks[0].Duration()) for _, q := range []int{98, 91, 75, 50, 25, 9, 2} { fmt.Printf(" %2d%% : %s\n", q, tasks[int(float64(len(tasks)*q)/100.0)].Duration()) } fmt.Println(" min :", tasks[len(tasks)-1].Duration()) fmt.Println(" long tasks:") for i := 0; i < 5; i++ { if i >= len(tasks) { break } fmt.Printf(" #%d %s %s\n", i, tasks[i].ID, tasks[i].Duration()) fmt.Println(" ", tasks[i].Desc) fmt.Println(" ", tasks[i].Response) } fmt.Println("") } dd := compilerproxylog.DurationDistribution(cpl.Created, tasks) fmt.Println("Duration per num active tasks") for i, d := range dd { fmt.Printf(" %3d tasks: %s\n", i, d) } }