restful-cpuprofiler-service.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package main
  2. import (
  3. "github.com/emicklei/go-restful"
  4. "io"
  5. "log"
  6. "os"
  7. "runtime/pprof"
  8. )
  9. // ProfilingService is a WebService that can start/stop a CPU profile and write results to a file
  10. // GET /{rootPath}/start will activate CPU profiling
  11. // GET /{rootPath}/stop will stop profiling
  12. //
  13. // NewProfileService("/profiler", "ace.prof").AddWebServiceTo(restful.DefaultContainer)
  14. //
  15. type ProfilingService struct {
  16. rootPath string // the base (root) of the service, e.g. /profiler
  17. cpuprofile string // the output filename to write profile results, e.g. myservice.prof
  18. cpufile *os.File // if not nil, then profiling is active
  19. }
  20. func NewProfileService(rootPath string, outputFilename string) *ProfilingService {
  21. ps := new(ProfilingService)
  22. ps.rootPath = rootPath
  23. ps.cpuprofile = outputFilename
  24. return ps
  25. }
  26. // Add this ProfileService to a restful Container
  27. func (p ProfilingService) AddWebServiceTo(container *restful.Container) {
  28. ws := new(restful.WebService)
  29. ws.Path(p.rootPath).Consumes("*/*").Produces(restful.MIME_JSON)
  30. ws.Route(ws.GET("/start").To(p.startProfiler))
  31. ws.Route(ws.GET("/stop").To(p.stopProfiler))
  32. container.Add(ws)
  33. }
  34. func (p *ProfilingService) startProfiler(req *restful.Request, resp *restful.Response) {
  35. if p.cpufile != nil {
  36. io.WriteString(resp.ResponseWriter, "[restful] CPU profiling already running")
  37. return // error?
  38. }
  39. cpufile, err := os.Create(p.cpuprofile)
  40. if err != nil {
  41. log.Fatal(err)
  42. }
  43. // remember for close
  44. p.cpufile = cpufile
  45. pprof.StartCPUProfile(cpufile)
  46. io.WriteString(resp.ResponseWriter, "[restful] CPU profiling started, writing on:"+p.cpuprofile)
  47. }
  48. func (p *ProfilingService) stopProfiler(req *restful.Request, resp *restful.Response) {
  49. if p.cpufile == nil {
  50. io.WriteString(resp.ResponseWriter, "[restful] CPU profiling not active")
  51. return // error?
  52. }
  53. pprof.StopCPUProfile()
  54. p.cpufile.Close()
  55. p.cpufile = nil
  56. io.WriteString(resp.ResponseWriter, "[restful] CPU profiling stopped, closing:"+p.cpuprofile)
  57. }
  58. func main() {} // exists for example compilation only