templates.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2017, OpenCensus Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. package zpages
  16. import (
  17. "fmt"
  18. "html/template"
  19. "io/ioutil"
  20. "log"
  21. "strconv"
  22. "time"
  23. "go.opencensus.io/trace"
  24. "go.opencensus.io/zpages/internal"
  25. )
  26. var (
  27. fs = internal.FS(false)
  28. templateFunctions = template.FuncMap{
  29. "count": countFormatter,
  30. "ms": msFormatter,
  31. "rate": rateFormatter,
  32. "datarate": dataRateFormatter,
  33. "even": even,
  34. "traceid": traceIDFormatter,
  35. }
  36. headerTemplate = parseTemplate("header")
  37. summaryTableTemplate = parseTemplate("summary")
  38. statsTemplate = parseTemplate("rpcz")
  39. tracesTableTemplate = parseTemplate("traces")
  40. footerTemplate = parseTemplate("footer")
  41. )
  42. func parseTemplate(name string) *template.Template {
  43. f, err := fs.Open("/templates/" + name + ".html")
  44. if err != nil {
  45. log.Panicf("%v: %v", name, err)
  46. }
  47. defer f.Close()
  48. text, err := ioutil.ReadAll(f)
  49. if err != nil {
  50. log.Panicf("%v: %v", name, err)
  51. }
  52. return template.Must(template.New(name).Funcs(templateFunctions).Parse(string(text)))
  53. }
  54. func countFormatter(num uint64) string {
  55. if num <= 0 {
  56. return " "
  57. }
  58. var floatVal float64
  59. var suffix string
  60. if num >= 1e18 {
  61. floatVal = float64(num) / 1e18
  62. suffix = " E "
  63. } else if num >= 1e15 {
  64. floatVal = float64(num) / 1e15
  65. suffix = " P "
  66. } else if num >= 1e12 {
  67. floatVal = float64(num) / 1e12
  68. suffix = " T "
  69. } else if num >= 1e9 {
  70. floatVal = float64(num) / 1e9
  71. suffix = " G "
  72. } else if num >= 1e6 {
  73. floatVal = float64(num) / 1e6
  74. suffix = " M "
  75. }
  76. if floatVal != 0 {
  77. return fmt.Sprintf("%1.3f%s", floatVal, suffix)
  78. }
  79. return fmt.Sprint(num)
  80. }
  81. func msFormatter(d time.Duration) string {
  82. if d == 0 {
  83. return "0"
  84. }
  85. if d < 10*time.Millisecond {
  86. return fmt.Sprintf("%.3f", float64(d)*1e-6)
  87. }
  88. return strconv.Itoa(int(d / time.Millisecond))
  89. }
  90. func rateFormatter(r float64) string {
  91. return fmt.Sprintf("%.3f", r)
  92. }
  93. func dataRateFormatter(b float64) string {
  94. return fmt.Sprintf("%.3f", b/1e6)
  95. }
  96. func traceIDFormatter(r traceRow) template.HTML {
  97. sc := r.SpanContext
  98. if sc == (trace.SpanContext{}) {
  99. return ""
  100. }
  101. col := "black"
  102. if sc.TraceOptions.IsSampled() {
  103. col = "blue"
  104. }
  105. if r.ParentSpanID != (trace.SpanID{}) {
  106. return template.HTML(fmt.Sprintf(`trace_id: <b style="color:%s">%s</b> span_id: %s parent_span_id: %s`, col, sc.TraceID, sc.SpanID, r.ParentSpanID))
  107. }
  108. return template.HTML(fmt.Sprintf(`trace_id: <b style="color:%s">%s</b> span_id: %s`, col, sc.TraceID, sc.SpanID))
  109. }
  110. func even(x int) bool {
  111. return x%2 == 0
  112. }