http.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package agent
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "github.com/prometheus/client_golang/prometheus/promhttp"
  8. "go-common/library/log"
  9. )
  10. // HTTPServer provides an HTTP api for an agent.
  11. type HTTPServer struct {
  12. *http.Server
  13. agent *Agent
  14. // proto is filled by the agent to "http" or "https".
  15. proto string
  16. }
  17. // NewHTTPServer http server provide simple query api
  18. func NewHTTPServer(addr string, a *Agent) *HTTPServer {
  19. s := &HTTPServer{
  20. Server: &http.Server{Addr: addr},
  21. agent: a,
  22. }
  23. s.Server.Handler = s.handler()
  24. return s
  25. }
  26. // handler is used to attach our handlers to the mux
  27. func (s *HTTPServer) handler() http.Handler {
  28. mux := http.NewServeMux()
  29. // TODO: simple manage ui
  30. // API V1
  31. mux.HandleFunc("/v1/naming/", s.wrap(s.NSTranslation)) // naming path
  32. mux.Handle("/metrics", promhttp.Handler())
  33. return mux
  34. }
  35. // wrap is used to wrap functions to make them more convenient
  36. func (s *HTTPServer) wrap(handler func(resp http.ResponseWriter, req *http.Request) (interface{}, error)) http.HandlerFunc {
  37. return func(resp http.ResponseWriter, req *http.Request) {
  38. logURL := req.URL.String()
  39. handleErr := func(err error) {
  40. log.Error("http: Request %s %v from %s, err: %v\n", req.Method, logURL, req.RemoteAddr, err)
  41. resp.WriteHeader(http.StatusInternalServerError)
  42. fmt.Fprint(resp, err.Error())
  43. }
  44. // Invoke the handler
  45. start := time.Now()
  46. defer func() {
  47. log.V(5).Info("http: Request %s %v from %s, Timing: %v\n", req.Method, logURL, req.RemoteAddr, time.Since(start))
  48. }()
  49. obj, err := handler(resp, req)
  50. if err != nil {
  51. handleErr(err)
  52. return
  53. }
  54. if obj == nil {
  55. return
  56. }
  57. buf, err := s.marshalJSON(req, obj)
  58. if err != nil {
  59. handleErr(err)
  60. return
  61. }
  62. resp.Header().Set("Content-Type", "application/json")
  63. resp.Write(buf)
  64. }
  65. }
  66. // marshalJSON marshals the object into JSON, respecting the user's pretty-ness
  67. // configuration.
  68. func (s *HTTPServer) marshalJSON(req *http.Request, obj interface{}) ([]byte, error) {
  69. if _, ok := req.URL.Query()["pretty"]; ok {
  70. buf, err := json.MarshalIndent(obj, "", " ")
  71. if err != nil {
  72. return nil, err
  73. }
  74. buf = append(buf, "\n"...)
  75. return buf, nil
  76. }
  77. buf, err := json.Marshal(obj)
  78. if err != nil {
  79. return nil, err
  80. }
  81. return buf, err
  82. }