ui.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2016 Marc-Antoine Ruel. All rights reserved.
  2. // Use of this source code is governed under the Apache License, Version 2.0
  3. // that can be found in the LICENSE file.
  4. package internal
  5. import (
  6. "fmt"
  7. "strings"
  8. "notabug.org/themusicgod1/panicparse/stack"
  9. )
  10. // Palette defines the color used.
  11. //
  12. // An empty object Palette{} can be used to disable coloring.
  13. type Palette struct {
  14. EOLReset string
  15. // Routine header.
  16. RoutineFirst string // The first routine printed.
  17. Routine string // Following routines.
  18. CreatedBy string
  19. // Call line.
  20. Package string
  21. SrcFile string
  22. FuncStdLib string
  23. FuncStdLibExported string
  24. FuncMain string
  25. FuncOther string
  26. FuncOtherExported string
  27. Arguments string
  28. }
  29. // CalcLengths returns the maximum length of the source lines and package names.
  30. func CalcLengths(buckets []*stack.Bucket, fullPath bool) (int, int) {
  31. srcLen := 0
  32. pkgLen := 0
  33. for _, bucket := range buckets {
  34. for _, line := range bucket.Signature.Stack.Calls {
  35. l := 0
  36. if fullPath {
  37. l = len(line.FullSrcLine())
  38. } else {
  39. l = len(line.SrcLine())
  40. }
  41. if l > srcLen {
  42. srcLen = l
  43. }
  44. l = len(line.Func.PkgName())
  45. if l > pkgLen {
  46. pkgLen = l
  47. }
  48. }
  49. }
  50. return srcLen, pkgLen
  51. }
  52. // functionColor returns the color to be used for the function name based on
  53. // the type of package the function is in.
  54. func (p *Palette) functionColor(line *stack.Call) string {
  55. if line.IsStdlib {
  56. if line.Func.IsExported() {
  57. return p.FuncStdLibExported
  58. }
  59. return p.FuncStdLib
  60. } else if line.IsPkgMain() {
  61. return p.FuncMain
  62. } else if line.Func.IsExported() {
  63. return p.FuncOtherExported
  64. }
  65. return p.FuncOther
  66. }
  67. // routineColor returns the color for the header of the goroutines bucket.
  68. func (p *Palette) routineColor(bucket *stack.Bucket, multipleBuckets bool) string {
  69. if bucket.First && multipleBuckets {
  70. return p.RoutineFirst
  71. }
  72. return p.Routine
  73. }
  74. // BucketHeader prints the header of a goroutine signature.
  75. func (p *Palette) BucketHeader(bucket *stack.Bucket, fullPath, multipleBuckets bool) string {
  76. extra := ""
  77. if s := bucket.SleepString(); s != "" {
  78. extra += " [" + s + "]"
  79. }
  80. if bucket.Locked {
  81. extra += " [locked]"
  82. }
  83. if c := bucket.CreatedByString(fullPath); c != "" {
  84. extra += p.CreatedBy + " [Created by " + c + "]"
  85. }
  86. return fmt.Sprintf(
  87. "%s%d: %s%s%s\n",
  88. p.routineColor(bucket, multipleBuckets), len(bucket.IDs),
  89. bucket.State, extra,
  90. p.EOLReset)
  91. }
  92. // callLine prints one stack line.
  93. func (p *Palette) callLine(line *stack.Call, srcLen, pkgLen int, fullPath bool) string {
  94. src := ""
  95. if fullPath {
  96. src = line.FullSrcLine()
  97. } else {
  98. src = line.SrcLine()
  99. }
  100. return fmt.Sprintf(
  101. " %s%-*s %s%-*s %s%s%s(%s)%s",
  102. p.Package, pkgLen, line.Func.PkgName(),
  103. p.SrcFile, srcLen, src,
  104. p.functionColor(line), line.Func.Name(),
  105. p.Arguments, &line.Args,
  106. p.EOLReset)
  107. }
  108. // StackLines prints one complete stack trace, without the header.
  109. func (p *Palette) StackLines(signature *stack.Signature, srcLen, pkgLen int, fullPath bool) string {
  110. out := make([]string, len(signature.Stack.Calls))
  111. for i := range signature.Stack.Calls {
  112. out[i] = p.callLine(&signature.Stack.Calls[i], srcLen, pkgLen, fullPath)
  113. }
  114. if signature.Stack.Elided {
  115. out = append(out, " (...)")
  116. }
  117. return strings.Join(out, "\n") + "\n"
  118. }