1
0

server.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package devserver
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "net/http/pprof"
  7. "sync"
  8. "github.com/prometheus/client_golang/prometheus/promhttp"
  9. "github.com/wuntsong-org/go-zero-plus/core/logx"
  10. "github.com/wuntsong-org/go-zero-plus/core/prometheus"
  11. "github.com/wuntsong-org/go-zero-plus/core/threading"
  12. "github.com/wuntsong-org/go-zero-plus/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. // enable prometheus global switch
  39. prometheus.Enable()
  40. s.handleFunc(s.config.MetricsPath, promhttp.Handler().ServeHTTP)
  41. }
  42. // pprof
  43. if s.config.EnablePprof {
  44. s.handleFunc("/debug/pprof/", pprof.Index)
  45. s.handleFunc("/debug/pprof/cmdline", pprof.Cmdline)
  46. s.handleFunc("/debug/pprof/profile", pprof.Profile)
  47. s.handleFunc("/debug/pprof/symbol", pprof.Symbol)
  48. s.handleFunc("/debug/pprof/trace", pprof.Trace)
  49. }
  50. }
  51. func (s *Server) handleFunc(pattern string, handler http.HandlerFunc) {
  52. s.server.HandleFunc(pattern, handler)
  53. s.routes = append(s.routes, pattern)
  54. }
  55. // StartAsync start inner http server background.
  56. func (s *Server) StartAsync() {
  57. s.addRoutes()
  58. threading.GoSafe(func() {
  59. addr := fmt.Sprintf("%s:%d", s.config.Host, s.config.Port)
  60. logx.Infof("Starting dev http server at %s", addr)
  61. if err := http.ListenAndServe(addr, s.server); err != nil {
  62. logx.Error(err)
  63. }
  64. })
  65. }
  66. // StartAgent start inner http server by config.
  67. func StartAgent(c Config) {
  68. once.Do(func() {
  69. if c.Enabled {
  70. s := NewServer(c)
  71. s.StartAsync()
  72. }
  73. })
  74. }