handlers.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package diagnostic
  2. import (
  3. "context"
  4. "encoding/json"
  5. "net/http"
  6. "time"
  7. "github.com/rs/zerolog"
  8. )
  9. type Handler struct {
  10. log *zerolog.Logger
  11. timeout time.Duration
  12. systemCollector SystemCollector
  13. }
  14. func NewDiagnosticHandler(
  15. log *zerolog.Logger,
  16. timeout time.Duration,
  17. systemCollector SystemCollector,
  18. ) *Handler {
  19. if timeout == 0 {
  20. timeout = defaultCollectorTimeout
  21. }
  22. return &Handler{
  23. log,
  24. timeout,
  25. systemCollector,
  26. }
  27. }
  28. func (handler *Handler) SystemHandler(writer http.ResponseWriter, request *http.Request) {
  29. logger := handler.log.With().Str(collectorField, systemCollectorName).Logger()
  30. logger.Info().Msg("Collection started")
  31. defer func() {
  32. logger.Info().Msg("Collection finished")
  33. }()
  34. ctx, cancel := context.WithTimeout(request.Context(), handler.timeout)
  35. defer cancel()
  36. info, rawInfo, err := handler.systemCollector.Collect(ctx)
  37. if err != nil {
  38. logger.Error().Err(err).Msg("error occurred whilst collecting system information")
  39. if rawInfo != "" {
  40. logger.Info().Msg("using raw information fallback")
  41. bytes := []byte(rawInfo)
  42. writeResponse(writer, bytes, &logger)
  43. } else {
  44. logger.Error().Msg("no raw information available")
  45. writer.WriteHeader(http.StatusInternalServerError)
  46. }
  47. return
  48. }
  49. if info == nil {
  50. logger.Error().Msgf("system information collection is nil")
  51. writer.WriteHeader(http.StatusInternalServerError)
  52. }
  53. encoder := json.NewEncoder(writer)
  54. err = encoder.Encode(info)
  55. if err != nil {
  56. logger.Error().Err(err).Msgf("error occurred whilst serializing information")
  57. writer.WriteHeader(http.StatusInternalServerError)
  58. }
  59. }
  60. func writeResponse(writer http.ResponseWriter, bytes []byte, logger *zerolog.Logger) {
  61. bytesWritten, err := writer.Write(bytes)
  62. if err != nil {
  63. logger.Error().Err(err).Msg("error occurred writing response")
  64. } else if bytesWritten != len(bytes) {
  65. logger.Error().Msgf("error incomplete write response %d/%d", bytesWritten, len(bytes))
  66. }
  67. }