logger.go 2.8 KB

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