trace.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //go:build trace
  2. package engine
  3. import (
  4. "flag"
  5. "os"
  6. "runtime/pprof"
  7. "runtime/trace"
  8. "github.com/felixge/fgtrace"
  9. log "github.com/sirupsen/logrus"
  10. )
  11. var (
  12. cpuProfileFilename *string
  13. memProfileFilename *string
  14. traceFilename *string
  15. fgtraceFilename *string
  16. )
  17. func init() {
  18. cpuProfileFilename = flag.String("cpuprofile", "", "write CPU profile to `file`")
  19. memProfileFilename = flag.String("memprofile", "", "write memory profile to `file`")
  20. traceFilename = flag.String("tracefile", "", "write trace to `file`")
  21. fgtraceFilename = flag.String("fgtrace", "", "write fgtrace to `file`")
  22. }
  23. func traceStart() {
  24. // Output CPU profile information, if a filename is given
  25. if *cpuProfileFilename != "" {
  26. f, err := os.Create(*cpuProfileFilename)
  27. if err != nil {
  28. log.Fatal("could not create CPU profile: ", err)
  29. }
  30. log.Info("Profiling CPU usage")
  31. if err := pprof.StartCPUProfile(f); err != nil {
  32. log.Fatal("could not start CPU profile: ", err)
  33. }
  34. AtShutdown(func() {
  35. pprof.StopCPUProfile()
  36. log.Info("Done profiling CPU usage")
  37. f.Close()
  38. })
  39. }
  40. // Profile memory at server shutdown, if a filename is given
  41. if *memProfileFilename != "" {
  42. AtShutdown(func() {
  43. f, errProfile := os.Create(*memProfileFilename)
  44. if errProfile != nil {
  45. // Fatal is okay here, since it's inside the anonymous shutdown function
  46. log.Fatal("could not create memory profile: ", errProfile)
  47. }
  48. defer f.Close()
  49. log.Info("Saving heap profile to ", *memProfileFilename)
  50. if err := pprof.WriteHeapProfile(f); err != nil {
  51. log.Fatal("could not write memory profile: ", err)
  52. }
  53. })
  54. }
  55. if *traceFilename != "" {
  56. f, errTrace := os.Create(*traceFilename)
  57. if errTrace != nil {
  58. panic(errTrace)
  59. }
  60. go func() {
  61. log.Info("Tracing")
  62. if err := trace.Start(f); err != nil {
  63. panic(err)
  64. }
  65. }()
  66. AtShutdown(func() {
  67. pprof.StopCPUProfile()
  68. trace.Stop()
  69. log.Info("Done tracing")
  70. f.Close()
  71. })
  72. }
  73. if *fgtraceFilename != "" {
  74. AtShutdown(func() {
  75. fgtrace.Config{Dst: fgtrace.File(*fgtraceFilename)}.Trace().Stop()
  76. })
  77. }
  78. }