logger.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package middleware
  2. import (
  3. "bytes"
  4. "fmt"
  5. "time"
  6. "git.qianqiusoft.com/public/glog"
  7. "git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
  8. "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
  9. "github.com/gin-gonic/gin"
  10. )
  11. /**
  12. * 自定义日志响应类,主要是把resp的响应内容写入到body中
  13. */
  14. type loggerRespWriter struct {
  15. gin.ResponseWriter
  16. respBody *bytes.Buffer
  17. }
  18. // 写字节数组
  19. func (w loggerRespWriter) Write(b []byte) (int, error) {
  20. w.respBody.Write(b) // 保存
  21. return w.ResponseWriter.Write(b)
  22. }
  23. // 写字符串
  24. func (w loggerRespWriter) WriteString(s string) (int, error) {
  25. w.respBody.WriteString(s) // 保存
  26. return w.ResponseWriter.WriteString(s)
  27. }
  28. /**
  29. * 日志信息
  30. */
  31. type LogInfo struct {
  32. ReqClientIp string
  33. ReqTime time.Time
  34. ReqMethod string
  35. ReqUrl string
  36. ReqProto string
  37. ReqUa string
  38. ReqReferer string
  39. Header []byte
  40. LoginId string
  41. ReqHeader []byte
  42. ReqBody []byte
  43. RespTime time.Time
  44. RespBody []byte
  45. CostTime float64
  46. }
  47. var bucket utils.SyncSlice
  48. // 日志chan
  49. var __logInfoChan chan *LogInfo
  50. // app名称
  51. var __appName string = ""
  52. // 日志处理函数
  53. var __logHandler func(info []LogInfo) = nil
  54. func init() {
  55. defer func() {
  56. if p := recover(); p != nil {
  57. glog.Errorln("ecover", p)
  58. }
  59. }()
  60. // 设置app名称
  61. __appName = config.AppConfig.GetKey("logger_app_name")
  62. if __appName == "" {
  63. __appName = config.AppConfig.GetKey("app_name")
  64. }
  65. __logInfoChan = make(chan *LogInfo, 2000)
  66. // 日志处理
  67. logProcess()
  68. }
  69. // 设置日志处理接口
  70. func SetLogHandler(handler func(info []LogInfo)) {
  71. __logHandler = handler
  72. }
  73. // 获取日志中间件
  74. func LoggerMiddleware() gin.HandlerFunc {
  75. return func(c *gin.Context) {
  76. respWriter := &loggerRespWriter{
  77. ResponseWriter: c.Writer,
  78. respBody: bytes.NewBuffer([]byte{}),
  79. }
  80. c.Writer = respWriter // 注入自定writer
  81. logInfo := &LogInfo{}
  82. logInfo.ReqTime = time.Now()
  83. // 下一个请求
  84. c.Next()
  85. hByte := bytes.Buffer{}
  86. bByte := make([]byte, 1024)
  87. cReq := c.Request.Clone(c)
  88. cReq.Header.Write(&hByte)
  89. rbn, _ := cReq.Body.Read(bByte)
  90. // 设置对象
  91. logInfo.RespBody = respWriter.respBody.Bytes()
  92. logInfo.RespTime = time.Now()
  93. logInfo.ReqMethod = c.Request.Method
  94. logInfo.ReqUrl = c.Request.RequestURI
  95. logInfo.ReqProto = c.Request.Proto
  96. logInfo.ReqUa = c.Request.UserAgent()
  97. logInfo.ReqReferer = c.Request.Referer()
  98. logInfo.ReqBody = bByte[0:rbn]
  99. logInfo.ReqHeader = hByte.Bytes()
  100. logInfo.ReqClientIp = c.ClientIP()
  101. logInfo.CostTime = float64(logInfo.RespTime.Sub(logInfo.ReqTime).Seconds())
  102. token := c.GetHeader("token")
  103. if token != "" {
  104. tk := utils.GetGlobalTokenStore().Get(token)
  105. if tk != nil {
  106. logInfo.LoginId = tk.LoginID
  107. }
  108. }
  109. if logInfo.LoginId == "" {
  110. logInfo.LoginId = "__no_login__"
  111. }
  112. __logInfoChan <- logInfo
  113. }
  114. }
  115. // 日志处理进程
  116. func logProcess() {
  117. go func() {
  118. defer func() {
  119. if rec := recover(); rec != nil {
  120. fmt.Println(rec)
  121. }
  122. }()
  123. for {
  124. select {
  125. case <-time.Tick(6 * time.Second):
  126. if __logHandler != nil {
  127. logs := []LogInfo{}
  128. for _, v := range bucket.Reset() {
  129. logs = append(logs, *v.(*LogInfo))
  130. }
  131. __logHandler(logs)
  132. }
  133. case logInfo := <-__logInfoChan:
  134. if __logHandler != nil {
  135. bucket.Append(logInfo)
  136. }
  137. }
  138. }
  139. }()
  140. }