Nenhuma descrição

main.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package main
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. _ "net/http/pprof"
  9. "os"
  10. "github.com/gin-gonic/gin"
  11. "github.com/google/pprof/pkg/driver"
  12. "github.com/google/pprof/profile"
  13. "github.com/sirupsen/logrus"
  14. )
  15. func main() {
  16. r := gin.Default()
  17. r.OPTIONS("/upload", func(c *gin.Context) {
  18. c.Header("Access-Control-Allow-Origin", "http://localhost:8080")
  19. c.Header("Access-Control-Allow-Credentials", "true")
  20. c.Header("Access-Control-Allow-Method", "POST")
  21. //c.Header("","")
  22. //c.Header("","")
  23. //Access-Control-Allow-Origin: *
  24. // Access-Control-Allow-Credentials: true
  25. //Access-Control-Expose-Headers: FooBar
  26. //Content-Type: text/html; charset=utf-8
  27. })
  28. r.POST("/upload", upload)
  29. r.GET("/pprof/:hash/:method", mapping)
  30. //r.GET("/pprof/:hash/", dot)
  31. //r.GET("/pprof/:hash/top", top)
  32. //r.GET("/pprof/:hash/disasm", disasm)
  33. //r.GET("/pprof/:hash/source", source)
  34. //r.GET("/pprof/:hash/peek", peek)
  35. //r.GET("/pprof/:hash/flamegraph", flamegraph)
  36. //r.GET("/pprof/:hash/saveconfig", saveconfig)
  37. //r.GET("/pprof/:hash/deleteconfig", deleteconfig)
  38. go func() {
  39. http.ListenAndServe(":8091", nil)
  40. }()
  41. r.Run(":8090")
  42. }
  43. func mapping(c *gin.Context) {
  44. hash := c.Param("hash")
  45. if hash == "" {
  46. c.AbortWithStatus(http.StatusNotFound)
  47. return
  48. }
  49. filename := fmt.Sprintf("%s.pprof", hash)
  50. f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm)
  51. if err != nil {
  52. c.AbortWithError(http.StatusInternalServerError, err)
  53. return
  54. }
  55. defer f.Close()
  56. prof, err := profile.Parse(f)
  57. if err != nil {
  58. c.AbortWithError(http.StatusInternalServerError, err)
  59. return
  60. }
  61. ui, err := driver.MakeWebInterface(prof, nil)
  62. if err != nil {
  63. c.AbortWithError(http.StatusInternalServerError, err)
  64. return
  65. }
  66. method := c.Param("method")
  67. switch method {
  68. case "", "dot":
  69. ui.Dot(c.Writer, c.Request)
  70. case "top":
  71. ui.Top(c.Writer, c.Request)
  72. case "disasm":
  73. ui.Disasm(c.Writer, c.Request)
  74. case "source":
  75. ui.Source(c.Writer, c.Request)
  76. case "peek":
  77. ui.Peek(c.Writer, c.Request)
  78. case "flamegraph":
  79. ui.Flamegraph(c.Writer, c.Request)
  80. case "saveconfig":
  81. ui.SaveConfig(c.Writer, c.Request)
  82. case "deleteconfig":
  83. ui.DeleteConfig(c.Writer, c.Request)
  84. default:
  85. c.AbortWithStatus(http.StatusNotFound)
  86. }
  87. }
  88. func upload(c *gin.Context) {
  89. f, _, err := c.Request.FormFile("file")
  90. if err != nil {
  91. logrus.Errorln("upload file error:", err)
  92. c.AbortWithError(http.StatusInternalServerError, err)
  93. return
  94. }
  95. fdata, _ := ioutil.ReadAll(f)
  96. f.Close()
  97. rhash := hash(fdata)
  98. if fileExist(rhash) { // 文件已存在
  99. c.Redirect(http.StatusFound, fmt.Sprintf("/pprof/%s/flamegraph", rhash))
  100. return
  101. }
  102. fileDst := fmt.Sprintf("%s.pprof", rhash)
  103. file, err := os.Create(fileDst)
  104. if err != nil {
  105. c.AbortWithError(http.StatusInternalServerError, err)
  106. return
  107. }
  108. defer file.Close()
  109. if _, err := file.Write(fdata); err != nil {
  110. c.AbortWithError(http.StatusInternalServerError, err)
  111. return
  112. }
  113. c.JSONP(http.StatusOK, map[string]interface{}{
  114. "code": 0,
  115. "msg": "ok",
  116. "data": rhash,
  117. })
  118. }
  119. func hash(data []byte) string {
  120. h := md5.New()
  121. h.Write(data)
  122. return hex.EncodeToString(h.Sum(nil))
  123. }
  124. func fileExist(file string) bool {
  125. return false
  126. }
  127. //
  128. //func dot(c *gin.Context) {}
  129. //func top(c *gin.Context) {}
  130. //func disasm(c *gin.Context) {}
  131. //func source(c *gin.Context) {}
  132. //func peek(c *gin.Context) {}
  133. //func flamegraph(c *gin.Context) {
  134. // hash := c.Param("hash")
  135. // if hash == "" {
  136. // c.AbortWithStatus(http.StatusNotFound)
  137. // return
  138. // }
  139. //
  140. // filename := fmt.Sprintf("%s.pprof", hash)
  141. // f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm)
  142. // if err != nil {
  143. // c.AbortWithError(http.StatusInternalServerError, err)
  144. // return
  145. // }
  146. // defer f.Close()
  147. // prof, err := profile.Parse(f)
  148. // if err != nil {
  149. // c.AbortWithError(http.StatusInternalServerError, err)
  150. // return
  151. // }
  152. //
  153. // ui, err := driver.MakeWebInterface(prof, nil)
  154. // if err != nil {
  155. // c.AbortWithError(http.StatusInternalServerError, err)
  156. // return
  157. // }
  158. //
  159. // ui.Flamegraph(c.Writer, c.Request)
  160. //}
  161. //func saveconfig(c *gin.Context) {}
  162. //func deleteconfig(c *gin.Context) {}