func showCpuStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error { cusage, err := ss.GetCpuUsage(prev_rec.Cpu, cur_rec.Cpu) if err != nil { return err } buffer.WriteString(`,"cpu":`) cusage.WriteJsonTo(buffer) return nil }
func main() { var cheader ss.CommonHeader var pheader ss.PlatformHeader parseArgs() f, err := os.Open(option.logfile) if err != nil { panic(err) } dec := gob.NewDecoder(f) err = dec.Decode(&cheader) if err == io.EOF { return } if err != nil { panic(err) } err = dec.Decode(&pheader) if err == io.EOF { return } if err != nil { panic(err) } var fst_record ss.StatRecord // read first record err = dec.Decode(&fst_record) if err == io.EOF { return } else if err != nil { panic(err) } // loop until last line var lst_records [2]ss.StatRecord idx := 0 for { err = dec.Decode(&lst_records[idx]) if err == io.EOF { idx ^= 1 break } else if err != nil { panic(err) } idx ^= 1 } lst_record := lst_records[idx] var cpu_usage *ss.CpuUsage = nil var intr_usage *ss.InterruptUsage = nil var disk_usage *ss.DiskUsage = nil var net_usage *ss.NetUsage = nil if fst_record.Cpu != nil && lst_record.Cpu != nil { cpu_usage, err = ss.GetCpuUsage(fst_record.Cpu, lst_record.Cpu) } if fst_record.Interrupt != nil && lst_record.Interrupt != nil { intr_usage, err = ss.GetInterruptUsage( fst_record.Time, fst_record.Interrupt, lst_record.Time, lst_record.Interrupt, ) } if fst_record.Disk != nil && lst_record.Disk != nil { disk_usage, err = ss.GetDiskUsage1( fst_record.Time, fst_record.Disk, lst_record.Time, lst_record.Disk, option.disk_only_regex) } if fst_record.Disk != nil && lst_record.Disk != nil { net_usage, err = ss.GetNetUsage( fst_record.Time, fst_record.Net, lst_record.Time, lst_record.Net) } interval := lst_record.Time.Sub(fst_record.Time) if option.json { buf := bytes.NewBuffer([]byte{}) buf.WriteString(fmt.Sprintf(`{"exectime":%.3f`, interval.Seconds())) if cpu_usage != nil { buf.WriteString(`,"cpu":`) cpu_usage.WriteJsonTo(buf) } if intr_usage != nil { buf.WriteString(`,"intr":`) intr_usage.WriteJsonTo(buf) } if disk_usage != nil { buf.WriteString(`,"disk":`) disk_usage.WriteJsonTo(buf) } if net_usage != nil { buf.WriteString(`,"net":`) net_usage.WriteJsonTo(buf) } buf.WriteByte('}') fmt.Println(buf.String()) } else { if option.title == "" { fmt.Println("== performance summary ==") } else { fmt.Printf("== performance summary of '%s' ==\n", option.title) } fmt.Printf(` Duration: %.3f sec `, interval.Seconds()) if cpu_usage != nil { fmt.Printf(`* Average CPU usage (MAX: %d %%) * Non-idle usage: %.2f %% %%usr: %.2f %% %%sys: %.2f %% %%irq: %.2f %% %%soft: %.2f %% %%other: %.2f %% * Idle usage: %.2f %% %%iowait: %.2f %% %%idle: %.2f %% `, 100*cpu_usage.NumCore, 100.0*float64(cpu_usage.NumCore)-cpu_usage.All.Idle-cpu_usage.All.Iowait, cpu_usage.All.User+cpu_usage.All.Nice, cpu_usage.All.Sys, cpu_usage.All.Hardirq, cpu_usage.All.Softirq, cpu_usage.All.Steal, cpu_usage.All.Idle+cpu_usage.All.Iowait, cpu_usage.All.Iowait, cpu_usage.All.Idle) } if disk_usage != nil { devices := []string{} for device, _ := range *disk_usage { if device != "total" { devices = append(devices, device) } } sort.Strings(devices) if len(devices) > 1 { devices = append(devices, "total") } for _, device := range devices { e := (*disk_usage)[device] fmt.Printf(`* Average DEVICE usage: %s read IOPS: %.2f write IOPS: %.2f read throughput: %.2f MB/s write throughput: %.2f MB/s read latency: %.1f usec write latency: %.1f usec read amount: %.2f MB write amount: %.2f MB `, device, e.RdIops, e.WrIops, e.RdSecps*512.0/1024.0/1024.0, e.WrSecps*512.0/1024.0/1024.0, e.RdLatency*1000.0, e.WrLatency*1000.0, float64(e.RdSectors*512)/1024.0/1024.0, float64(e.WrSectors*512)/1024.0/1024.0) } } } }
func main() { opt := parseArgs() var in *os.File f, err := os.Open(opt.PerfmongerFile) if err != nil { panic(err) } in = f defer f.Close() dec := gob.NewDecoder(bufio.NewReader(in)) var cheader ss.CommonHeader var pheader ss.PlatformHeader var records = make([]ss.StatRecord, 2) curr := 0 err = dec.Decode(&cheader) if err == io.EOF { return } if err != nil { panic(err) } err = dec.Decode(&pheader) if err == io.EOF { return } if err != nil { panic(err) } // read first record err = dec.Decode(&records[curr]) if err == io.EOF { return } else if err != nil { panic(err) } t0 := records[curr].Time curr ^= 1 meta_set := false meta := PlotMeta{} meta.StartTime = float64(records[0].Time.UnixNano()) / 1.0e9 disk_dat_files := map[string]*DiskDatTmpFile{} cpu_dat_files := make([]*CpuDatTmpFile, records[0].Cpu.NumCore) meta.Cpu.NumCore = records[0].Cpu.NumCore f, err = os.Create(opt.CpuFile) if err != nil { panic(err) } defer f.Close() cpu_writer := bufio.NewWriter(f) cpu_writer.WriteString("# All cpu usage\n") cpu_writer.WriteString("# elapsed_time %usr %nice %sys %iowait %hardirq %softirq %steal %guest %idle\n") for { prev_rec := &records[curr^1] cur_rec := &records[curr] err := dec.Decode(cur_rec) if err == io.EOF { break } else if err != nil { panic(err) } // Disk usage dusage, err := ss.GetDiskUsage(prev_rec.Time, prev_rec.Disk, cur_rec.Time, cur_rec.Disk) if err != nil { panic(err) } didx := 0 var dnames []string for dname, _ := range *dusage { if dname != "total" { dnames = append(dnames, dname) } } sort.Strings(dnames) dnames = append(dnames, "total") // for dname, dusage_entry := range *dusage { for _, dname := range dnames { dusage_entry, ok := (*dusage)[dname] if !ok { panic("device '" + dname + "' not found") } if !meta_set { meta.Disk.Devices = append(meta.Disk.Devices, DiskMetaEntry{Name: dname, Idx: didx}) } disk_dat, ok := disk_dat_files[dname] if !ok { disk_dat = makeDiskDatTmpFile(dname, didx) disk_dat_files[dname] = disk_dat defer disk_dat.File.Close() disk_dat.Writer.WriteString("\n\n\n") disk_dat.Writer.WriteString("# device: " + disk_dat.Name + "\n") disk_dat.Writer.WriteString(fmt.Sprintln( "# elapsed_time r_iops w_iops r_MB/s w_MB/s r_latency w_latency r_avgsz w_avgsz qdepth")) } elapsed_time := prev_rec.Time.Sub(t0).Seconds() disk_dat.Writer.WriteString( fmt.Sprintf("%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", elapsed_time, dusage_entry.RdIops, dusage_entry.WrIops, dusage_entry.RdSecps*512.0/1024.0/1024.0, dusage_entry.WrSecps*512.0/1024.0/1024.0, dusage_entry.RdLatency, dusage_entry.WrLatency, dusage_entry.AvgRdSize, dusage_entry.AvgWrSize, dusage_entry.ReqQlen)) didx += 1 } // Cpu usage cusage, err := ss.GetCpuUsage(prev_rec.Cpu, cur_rec.Cpu) if err != nil { panic(err) } for coreid, coreusage := range cusage.CoreUsages { cpu_dat := cpu_dat_files[coreid] if cpu_dat == nil { cpu_dat = makeCpuDatTmpFile(coreid) cpu_dat_files[coreid] = cpu_dat defer cpu_dat.File.Close() cpu_dat.Writer.WriteString(fmt.Sprintf("\n\n\n# core: %d\n", coreid)) cpu_dat.Writer.WriteString("# elapsed_time %usr %nice %sys %iowait %hardirq %softirq %steal %guest %idle\n") } printCoreUsage(cpu_dat.Writer, prev_rec.Time.Sub(t0).Seconds(), coreusage) } printCoreUsage(cpu_writer, prev_rec.Time.Sub(t0).Seconds(), cusage.All) curr ^= 1 meta_set = true } meta.EndTime = float64(records[curr^1].Time.UnixNano()) / 1.0e9 for _, disk_dat := range disk_dat_files { disk_dat.Writer.Flush() disk_dat.File.Close() } f, err = os.Create(opt.DiskFile) if err != nil { panic(err) } defer f.Close() df_writer := bufio.NewWriter(f) for _, dev := range meta.Disk.Devices { disk_dat, ok := disk_dat_files[dev.Name] if !ok { panic(dev.Name) } content, err := ioutil.ReadFile(disk_dat.Path) if err != nil { panic(err) } df_writer.Write(content) os.Remove(disk_dat.Path) } df_writer.Flush() for _, cpu_dat := range cpu_dat_files { cpu_dat.Writer.Flush() cpu_dat.File.Close() content, err := ioutil.ReadFile(cpu_dat.Path) if err != nil { panic(err) } cpu_writer.Write(content) os.Remove(cpu_dat.Path) } cpu_writer.Flush() json_enc := json.NewEncoder(os.Stdout) json_enc.Encode(meta) }