github.com/GuanceCloud/cliutils@v1.1.21/pprofparser/tools/parsetoolkit/pprof.go (about) 1 package parsetoolkit 2 3 import ( 4 "fmt" 5 "math" 6 "strconv" 7 8 "github.com/GuanceCloud/cliutils/pprofparser/domain/pprof" 9 "github.com/GuanceCloud/cliutils/pprofparser/domain/quantity" 10 "github.com/google/pprof/profile" 11 ) 12 13 func GetLabel(smp *profile.Sample, key string) string { 14 if labels, ok := smp.Label[key]; ok { 15 for _, label := range labels { 16 if label != "" { 17 return label 18 } 19 } 20 } 21 return "" 22 } 23 24 func GetStringLabel(smp *profile.Sample, key string) string { 25 if span := GetLabel(smp, key); span != "" { 26 return span 27 } 28 if span, ok := GetNumLabel(smp, key); ok { 29 return strconv.FormatUint(uint64(span), 10) 30 } 31 return "" 32 } 33 34 func GetNumLabel(smp *profile.Sample, key string) (int64, bool) { 35 if values, ok := smp.NumLabel[key]; ok { 36 if len(values) > 0 { 37 // Find none zero value at first 38 for _, v := range values { 39 if v != 0 { 40 return v, true 41 } 42 } 43 return values[0], true 44 } 45 } 46 return 0, false 47 } 48 49 func CalcPercentOfAggregator() { 50 51 } 52 53 func CalcPercentAndQuantity(frame *pprof.Frame, total int64) { 54 if frame == nil { 55 return 56 } 57 58 if total <= 0 { 59 frame.Percent = "100" 60 } else { 61 frame.Percent = fmt.Sprintf("%.2f", float64(frame.Value)/float64(total)*100) 62 } 63 64 if frame.Unit != nil { 65 frame.Quantity = frame.Unit.Quantity(frame.Value) 66 67 // 转成默认单位 68 if frame.Unit.Kind == quantity.Memory && frame.Unit != quantity.Byte { 69 frame.Value, _ = frame.Quantity.IntValueIn(quantity.Byte) 70 frame.Unit = quantity.Byte 71 } else if frame.Unit.Kind == quantity.Duration && frame.Unit != quantity.MicroSecond { 72 frame.Value, _ = frame.Quantity.IntValueIn(quantity.MicroSecond) 73 frame.Unit = quantity.MicroSecond 74 } 75 } 76 77 for _, subFrame := range frame.SubFrames { 78 CalcPercentAndQuantity(subFrame, total) 79 } 80 } 81 82 func FormatDuration(nanoseconds int64) string { 83 ms := int64(math.Round(float64(nanoseconds) / 1000_000)) 84 if ms < 1000 { 85 return fmt.Sprintf("%d%s", ms, "ms") 86 } 87 if ms < 60_000 { 88 seconds := int64(math.Round(float64(ms) / 1000)) 89 return fmt.Sprintf("%d%s", seconds, "s") 90 } 91 92 minutes := int64(math.Round(float64(ms) / 60_000)) 93 return fmt.Sprintf("%d%s", minutes, "minute") 94 }