gitea源码

logger.go 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package routing
  4. import (
  5. "net/http"
  6. "strings"
  7. "time"
  8. "code.gitea.io/gitea/modules/log"
  9. "code.gitea.io/gitea/modules/web/types"
  10. )
  11. // NewLoggerHandler is a handler that will log routing to the router log taking account of
  12. // routing information
  13. func NewLoggerHandler() func(next http.Handler) http.Handler {
  14. manager := requestRecordsManager{
  15. requestRecords: map[uint64]*requestRecord{},
  16. }
  17. manager.startSlowQueryDetector(3 * time.Second)
  18. logger := log.GetLogger("router")
  19. manager.print = logPrinter(logger)
  20. return manager.handler
  21. }
  22. var (
  23. startMessage = log.NewColoredValue("started ", log.DEBUG.ColorAttributes()...)
  24. slowMessage = log.NewColoredValue("slow ", log.WARN.ColorAttributes()...)
  25. pollingMessage = log.NewColoredValue("polling ", log.INFO.ColorAttributes()...)
  26. failedMessage = log.NewColoredValue("failed ", log.WARN.ColorAttributes()...)
  27. completedMessage = log.NewColoredValue("completed", log.INFO.ColorAttributes()...)
  28. unknownHandlerMessage = log.NewColoredValue("completed", log.ERROR.ColorAttributes()...)
  29. )
  30. func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
  31. const callerName = "HTTPRequest"
  32. logTrace := func(fmt string, args ...any) {
  33. logger.Log(2, &log.Event{Level: log.TRACE, Caller: callerName}, fmt, args...)
  34. }
  35. logInfo := func(fmt string, args ...any) {
  36. logger.Log(2, &log.Event{Level: log.INFO, Caller: callerName}, fmt, args...)
  37. }
  38. logWarn := func(fmt string, args ...any) {
  39. logger.Log(2, &log.Event{Level: log.WARN, Caller: callerName}, fmt, args...)
  40. }
  41. logError := func(fmt string, args ...any) {
  42. logger.Log(2, &log.Event{Level: log.ERROR, Caller: callerName}, fmt, args...)
  43. }
  44. return func(trigger Event, record *requestRecord) {
  45. if trigger == StartEvent {
  46. if !logger.LevelEnabled(log.TRACE) {
  47. // for performance, if the "started" message shouldn't be logged, we just return as early as possible
  48. // developers can set the router log level to TRACE to get the "started" request messages.
  49. return
  50. }
  51. // when a request starts, we have no information about the handler function information, we only have the request path
  52. req := record.request
  53. logTrace("router: %s %v %s for %s", startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr)
  54. return
  55. }
  56. req := record.request
  57. // Get data from the record
  58. record.lock.Lock()
  59. handlerFuncInfo := record.funcInfo.String()
  60. isLongPolling := record.isLongPolling
  61. isUnknownHandler := record.funcInfo == nil
  62. panicErr := record.panicError
  63. record.lock.Unlock()
  64. if trigger == StillExecutingEvent {
  65. message := slowMessage
  66. logf := logWarn
  67. if isLongPolling {
  68. logf = logInfo
  69. message = pollingMessage
  70. }
  71. logf("router: %s %v %s for %s, elapsed %v @ %s",
  72. message,
  73. log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr,
  74. log.ColoredTime(time.Since(record.startTime)),
  75. handlerFuncInfo,
  76. )
  77. return
  78. }
  79. if panicErr != nil {
  80. logWarn("router: %s %v %s for %s, panic in %v @ %s, err=%v",
  81. failedMessage,
  82. log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr,
  83. log.ColoredTime(time.Since(record.startTime)),
  84. handlerFuncInfo,
  85. panicErr,
  86. )
  87. return
  88. }
  89. var status int
  90. if v, ok := record.responseWriter.(types.ResponseStatusProvider); ok {
  91. status = v.WrittenStatus()
  92. }
  93. logf := logInfo
  94. // lower the log level for some specific requests, in most cases these logs are not useful
  95. if strings.HasPrefix(req.RequestURI, "/assets/") /* static assets */ ||
  96. req.RequestURI == "/user/events" /* Server-Sent Events (SSE) handler */ ||
  97. req.RequestURI == "/api/actions/runner.v1.RunnerService/FetchTask" /* Actions Runner polling */ {
  98. logf = logTrace
  99. }
  100. message := completedMessage
  101. if isUnknownHandler {
  102. logf = logError
  103. message = unknownHandlerMessage
  104. }
  105. logf("router: %s %v %s for %s, %v %v in %v @ %s",
  106. message,
  107. log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr,
  108. log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(record.startTime)),
  109. handlerFuncInfo,
  110. )
  111. }
  112. }