server.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package devserver
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "net/http/pprof"
  7. "sync"
  8. "github.com/felixge/fgprof"
  9. "github.com/prometheus/client_golang/prometheus/promhttp"
  10. "github.com/zeromicro/go-zero/core/logx"
  11. "github.com/zeromicro/go-zero/core/threading"
  12. "github.com/zeromicro/go-zero/internal/health"
  13. )
  14. var once sync.Once
  15. // Server is inner http server, expose some useful observability information of app.
  16. // For example health check, metrics and pprof.
  17. type Server struct {
  18. config *Config
  19. server *http.ServeMux
  20. routes []string
  21. }
  22. // NewServer returns a new inner http Server.
  23. func NewServer(config *Config) *Server {
  24. return &Server{
  25. config: config,
  26. server: http.NewServeMux(),
  27. }
  28. }
  29. func (s *Server) addRoutes() {
  30. // route path, routes list
  31. s.handleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
  32. _ = json.NewEncoder(w).Encode(s.routes)
  33. })
  34. // health
  35. s.handleFunc(s.config.HealthPath, health.CreateHttpHandler())
  36. // metrics
  37. if s.config.EnableMetrics {
  38. s.handleFunc(s.config.MetricsPath, promhttp.Handler().ServeHTTP)
  39. }
  40. // pprof
  41. if s.config.EnablePprof {
  42. s.handleFunc("/debug/fgprof", fgprof.Handler().(http.HandlerFunc))
  43. s.handleFunc("/debug/pprof/", pprof.Index)
  44. s.handleFunc("/debug/pprof/cmdline", pprof.Cmdline)
  45. s.handleFunc("/debug/pprof/profile", pprof.Profile)
  46. s.handleFunc("/debug/pprof/symbol", pprof.Symbol)
  47. s.handleFunc("/debug/pprof/trace", pprof.Trace)
  48. }
  49. }
  50. func (s *Server) handleFunc(pattern string, handler http.HandlerFunc) {
  51. s.server.HandleFunc(pattern, handler)
  52. s.routes = append(s.routes, pattern)
  53. }
  54. // StartAsync start inner http server background.
  55. func (s *Server) StartAsync() {
  56. s.addRoutes()
  57. threading.GoSafe(func() {
  58. addr := fmt.Sprintf("%s:%d", s.config.Host, s.config.Port)
  59. logx.Infof("Starting dev http server at %s", addr)
  60. if err := http.ListenAndServe(addr, s.server); err != nil {
  61. logx.Error(err)
  62. }
  63. })
  64. }
  65. // StartAgent start inner http server by config.
  66. func StartAgent(c Config) {
  67. once.Do(func() {
  68. if c.Enabled {
  69. s := NewServer(&c)
  70. s.StartAsync()
  71. }
  72. })
  73. }