logger.go 3.2 KB

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