// Write all the commands of the given thread func StatCmdTID(aTID string) { rs, ok := record.RecordByThread[aTID] if !ok { fmt.Println("Unknown TID") return } w := new(tabwriter.Writer) w.Init(os.Stdout, 20, 0, 2, ' ', tabwriter.AlignRight) //fmt.Fprintln(w, "Time\tCommand\tEnd\tDuration\t") fmt.Fprintln(w, "Time\tCommand\tDuration(s)\tNext Cmd After(s)\t") currentCmd := rs[0] // TODO Optim to start at the border of the window if currentCmd.PreviousByThread != nil { currentCmd = currentCmd.PreviousByThread } for { nextCmd := currentCmd.GetNextCommand() if nextCmd == nil { break } if window.InCurrentWindow(nextCmd.Time) { nextCmd.GetCommandCompletion() } currentCmd = nextCmd if window.InCurrentWindow(currentCmd.Time) { duration := -1.0 next := -1.0 if currentCmd.CmdCompletionRecord != nil { duration = currentCmd.CmdCompletionRecord.Time.Sub(currentCmd.Time).Seconds() nc := currentCmd.GetNextCommand() if nc != nil { next = nc.Time.Sub(currentCmd.CmdCompletionRecord.Time).Seconds() } } fmt.Fprintf(w, "%s\t%s\t%f\t%f\t\n", currentCmd.Time.Format(utils.DateFormat), currentCmd.Cmd, duration, next) } } fmt.Fprintln(w) w.Flush() }
func statThreadID() []statRecord { var result ResultMap var wg sync.WaitGroup for id, sl := range record.RecordByThread { wg.Add(1) go func(tid string, rs []*record.Record) { defer wg.Done() max := time.Duration(0) var rmax *record.Record for _, r := range rs { if !window.InCurrentWindow(r.Time) { continue } if r.NextByThread != nil { d := r.NextByThread.Time.Sub(r.Time) if d > max { max = d rmax = r } } } if rmax != nil { rcmd := rmax.GetCurrentCommand() rcmdCompleted := rcmd if rcmd != nil { rcmdCompleted = rmax.GetCommandCompletion() } result.Lock() result.m = append(result.m, statRecord{tid: tid, r: rmax, rcmd: rcmd, rcmdCompleted: rcmdCompleted}) result.Unlock() } }(id, sl) } wg.Wait() sort.Sort(byTime(result.m)) return result.m }
func statCmdPerThread() cmdMap { var result cmdMap result.m = make(map[string]record.Records) var wg sync.WaitGroup for id, sl := range record.RecordByThread { wg.Add(1) go func(tid string, rs []*record.Record) { defer wg.Done() currentCmd := rs[0] // TODO Optim to start at the border of the window if currentCmd.PreviousByThread != nil { currentCmd = currentCmd.PreviousByThread } for { nextCmd := currentCmd.GetNextCommand() if nextCmd == nil { break } if window.InCurrentWindow(nextCmd.Time) { nextCmd.GetCommandCompletion() result.Lock() records, ok := result.m[nextCmd.Cmd] if !ok { records = make([]*record.Record, 0, 0) } result.m[nextCmd.Cmd] = append(records, nextCmd) result.Unlock() } currentCmd = nextCmd } }(id, sl) } wg.Wait() return result }
func statThreadIDCmd() []countTID { var result statTIDResults var wg sync.WaitGroup fmt.Printf("Length:%d\n", len(record.RecordByThread)) for id, sl := range record.RecordByThread { wg.Add(1) go func(tid string, rs []*record.Record) { defer wg.Done() myStat := countTID{tid: tid, count: 0} currentCmd := rs[0] // TODO Optim to start at the border of the window if currentCmd.IsCommand() { myStat.count = 1 } for { nextCmd := currentCmd.GetNextCommand() if nextCmd == nil { break } if window.InCurrentWindow(nextCmd.Time) { myStat.count++ } currentCmd = nextCmd } result.Lock() result.stats = append(result.stats, myStat) result.Unlock() }(id, sl) } wg.Wait() sort.Sort(byCount(result.stats)) return result.stats }
func StatQueue(writeQ bool) error { var myresults results var wg sync.WaitGroup for id, sl := range record.RecordByThread { wg.Add(1) go func(tid string, rs []*record.Record) { defer wg.Done() for _, r := range rs { if !window.InCurrentWindow(r.Time) { continue } if len(r.Raw) < 151 { continue } txt := strings.Split(r.Raw[60:150], ">") if len(txt) < 2 { continue } tokens := strings.Split(txt[1], " ") // 60:140 to limit the scope of search, with reasonable margins if len(tokens) < 3 { continue } if writeQ { if ((tokens[1] == "Queue") && (tokens[2] == "command")) || ((tokens[1] == "Dequeue") && (tokens[2] == "and") && (tokens[3] == "execute")) { //2015/08/04 15:19:59.904847 magap302 masterag-11298 MDW INFO <SEI_MAAdminSequence.cpp#223 TID#13> Queue command 0x2aacbf979400 [Command#14015: kSEIBELibLoaded : BE->MAG:Notify the Master Agent that a lib has been loaded (version 1)^@] (from BENT0UCL4VXODY to masterag); Command sequence queue size: 0 backToken := strings.Split(r.Raw[len(r.Raw)-40:len(r.Raw)], " ") last := len(backToken) - 1 txt1 := strings.Join(backToken[last-2:last], " ") if txt1 == "queue size:" { if s, err := strconv.Atoi(backToken[last]); err == nil { myresults.Lock() myresults.HasRecords = append(myresults.HasRecords, &result{qSize: s, tid: tid, r: r}) myresults.Unlock() } } } } else { if (tokens[1] == "Scheduling") && (tokens[3] == "command") && (tokens[6] == "Read-only") { //2015/12/03 05:07:12.577382 magap302 masterag-32357 MDW INFO <SEI_MAAdminSequence.cpp#196 TID#13> Scheduling the command in the Read-only command sequencer pool. Pool queue size: 393 backToken := strings.Split(r.Raw[len(r.Raw)-40:len(r.Raw)], " ") last := len(backToken) - 1 txt1 := strings.Join(backToken[last-2:last], " ") if txt1 == "queue size:" { if s, err := strconv.Atoi(backToken[last]); err == nil { myresults.Lock() myresults.HasRecords = append(myresults.HasRecords, &result{qSize: s, tid: tid, r: r}) myresults.Unlock() } } } } } }(id, sl) } wg.Wait() sort.Sort(record.ByHasRecordTime{myresults.HasRecords}) // Build chart chart := tm.NewLineChart(tm.Width()-10, tm.Height()-10) data := new(tm.DataTable) data.AddColumn("Seconds") data.AddColumn("QMax") data.AddColumn("QMin") type prec struct { max int min int } t0 := myresults.HasRecords[0].(*result).r.Time tmax := myresults.HasRecords[len(myresults.HasRecords)-1].(*result).r.Time indexMax := int(tmax.Sub(t0).Seconds()) qmaxTime := time.Unix(0, 0) qmax := 0 m := make(map[int]prec) for _, v := range myresults.HasRecords { r := v.(*result) d := int(r.r.Time.Sub(t0).Seconds()) p, ok := m[d] if !ok { p = prec{r.qSize, r.qSize} } else { if p.max < r.qSize { p.max = r.qSize } if p.min > r.qSize { p.min = r.qSize } } m[d] = p if p.max > qmax { qmax = p.max qmaxTime = r.GetRecord().Time } } for t := 0; t <= int(indexMax); t++ { data.AddRow(float64(t), float64(m[t].max), float64(m[t].min)) } tm.Println(chart.Draw(data)) tm.Flush() fmt.Printf("Qmax=%d at %s\n", qmax, qmaxTime.Format(utils.DateFormat)) return nil }