示例#1
0
// 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()

}
示例#2
0
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

}
示例#3
0
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
}
示例#4
0
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
}
示例#5
0
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
}