diff --git a/app/admin/middleware/handler/auth.go b/app/admin/middleware/handler/auth.go index 68c6ae64..f0fbedb1 100644 --- a/app/admin/middleware/handler/auth.go +++ b/app/admin/middleware/handler/auth.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk" "github.com/go-admin-team/go-admin-core/sdk/api" "github.com/go-admin-team/go-admin-core/sdk/config" "github.com/go-admin-team/go-admin-core/sdk/pkg" @@ -14,7 +15,7 @@ import ( "github.com/mssola/user_agent" "go-admin/app/admin/models/system" - "go-admin/app/admin/service" + "go-admin/common/global" ) var store = base64Captcha.DefaultMemStore @@ -107,29 +108,35 @@ func Authenticator(c *gin.Context) (interface{}, error) { // LoginLogToDB Write log to database func LoginLogToDB(c *gin.Context, status string, msg string, username string) { + if !config.LoggerConfig.EnabledDB { + return + } log := api.GetRequestLogger(c) - if config.LoggerConfig.EnabledDB { - var loginLog system.SysLoginLog - db, err := pkg.GetOrm(c) + l := make(map[string]interface{}) + + ua := user_agent.New(c.Request.UserAgent()) + l["ipaddr"] = c.ClientIP() + l["loginLocation"] = pkg.GetLocation(c.ClientIP()) + l["loginTime"] = pkg.GetCurrentTime() + l["status"] = status + l["remark"] = c.Request.UserAgent() + browserName, browserVersion := ua.Browser() + l["browser"] = browserName + " " + browserVersion + l["os"] = ua.OS() + l["platform"] = ua.Platform() + l["username"] = username + l["msg"] = msg + + q := sdk.Runtime.GetCachePrefix(c.Request.Host) + message, err := sdk.Runtime.GetStreamMessage("", global.LoginLog, l) + if err != nil { + log.Errorf("GetStreamMessage error, %s", err.Error()) + //日志报错错误,不中断请求 + } else { + err = q.Append(message) if err != nil { - log.Errorf("获取Orm失败, error:%s", err) + log.Errorf("Append message error, %s", err.Error()) } - ua := user_agent.New(c.Request.UserAgent()) - loginLog.Ipaddr = c.ClientIP() - loginLog.Username = username - location := pkg.GetLocation(c.ClientIP()) - loginLog.LoginLocation = location - loginLog.LoginTime = pkg.GetCurrentTime() - loginLog.Status = status - loginLog.Remark = c.Request.UserAgent() - browserName, browserVersion := ua.Browser() - loginLog.Browser = browserName + " " + browserVersion - loginLog.Os = ua.OS() - loginLog.Msg = msg - loginLog.Platform = ua.Platform() - serviceLoginLog := service.SysLoginLog{} - serviceLoginLog.Orm = db - _ = serviceLoginLog.InsertSysLoginLog(loginLog.Generate()) } } @@ -143,28 +150,27 @@ func LoginLogToDB(c *gin.Context, status string, msg string, username string) { // @Router /logout [post] // @Security Bearer func LogOut(c *gin.Context) { - log := api.GetRequestLogger(c) - var loginLog system.SysLoginLog - ua := user_agent.New(c.Request.UserAgent()) - loginLog.Ipaddr = c.ClientIP() - location := pkg.GetLocation(c.ClientIP()) - loginLog.LoginLocation = location - loginLog.LoginTime = pkg.GetCurrentTime() - loginLog.Status = "2" - loginLog.Remark = c.Request.UserAgent() - browserName, browserVersion := ua.Browser() - loginLog.Browser = browserName + " " + browserVersion - loginLog.Os = ua.OS() - loginLog.Platform = ua.Platform() - loginLog.Username = user.GetUserName(c) - loginLog.Msg = "退出成功" - db, err := pkg.GetOrm(c) - if err != nil { - log.Errorf("获取Orm失败, error:%s", err) - } - serviceLoginLog := service.SysLoginLog{} - serviceLoginLog.Orm = db - _ = serviceLoginLog.InsertSysLoginLog(loginLog.Generate()) + LoginLogToDB(c, "2", "退出成功", user.GetUserName(c)) + //var loginLog system.SysLoginLog + //loginLog.Ipaddr = c.ClientIP() + //location := pkg.GetLocation(c.ClientIP()) + //loginLog.LoginLocation = location + //loginLog.LoginTime = pkg.GetCurrentTime() + //loginLog.Status = "2" + //loginLog.Remark = c.Request.UserAgent() + //browserName, browserVersion := ua.Browser() + //loginLog.Browser = browserName + " " + browserVersion + //loginLog.Os = ua.OS() + //loginLog.Platform = ua.Platform() + //loginLog.Username = user.GetUserName(c) + //loginLog.Msg = "退出成功" + //db, err := pkg.GetOrm(c) + //if err != nil { + // log.Errorf("获取Orm失败, error:%s", err) + //} + //serviceLoginLog := service.SysLoginLog{} + //serviceLoginLog.Orm = db + //_ = serviceLoginLog.InsertSysLoginLog(loginLog.Generate()) c.JSON(http.StatusOK, gin.H{ "code": 200, diff --git a/app/admin/middleware/logger.go b/app/admin/middleware/logger.go index 88da4530..acc5952b 100644 --- a/app/admin/middleware/logger.go +++ b/app/admin/middleware/logger.go @@ -2,21 +2,18 @@ package middleware import ( "encoding/json" - "fmt" "net/http" "strings" "time" "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk" "github.com/go-admin-team/go-admin-core/sdk/api" "github.com/go-admin-team/go-admin-core/sdk/config" "github.com/go-admin-team/go-admin-core/sdk/pkg" "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" - "github.com/go-admin-team/go-admin-core/sdk/pkg/response" - "go-admin/app/admin/models" - "go-admin/app/admin/models/system" - "go-admin/app/admin/service" + "go-admin/common/global" ) // LoggerToFile 日志记录到文件 @@ -87,60 +84,49 @@ func LoggerToFile() gin.HandlerFunc { // SetDBOperLog 写入操作日志表 fixme 该方法后续即将弃用 func SetDBOperLog(c *gin.Context, clientIP string, statusCode int, reqUri string, reqMethod string, latencyTime time.Duration, body string, result string, status int) { log := api.GetRequestLogger(c) - db, err := pkg.GetOrm(c) - if err != nil { - log.Errorf("get db connection error, %s", err.Error()) - response.Error(c, http.StatusInternalServerError, err, "数据库连接获取失败") - return - } - - menu := models.Menu{} - menu.Path = reqUri - menu.Action = reqMethod - menuList, _ := menu.Get(db) - sysOperaLog := system.SysOperaLog{} - sysOperaLog.OperIp = clientIP - sysOperaLog.OperLocation = pkg.GetLocation(clientIP) - sysOperaLog.Status = pkg.IntToString(statusCode) - sysOperaLog.OperName = user.GetUserName(c) - sysOperaLog.RequestMethod = c.Request.Method - sysOperaLog.OperUrl = reqUri - sysOperaLog.OperParam = body + l := make(map[string]interface{}) + l["_fullPath"] = c.FullPath() + l["operUrl"] = reqUri + l["method"] = reqMethod + l["operIp"] = clientIP + l["operLocation"] = pkg.GetLocation(clientIP) + l["operName"] = user.GetUserName(c) + l["requestMethod"] = c.Request.Method + l["operParam"] = body + l["operTime"] = time.Now() if reqUri == "/login" { - sysOperaLog.BusinessType = "10" - sysOperaLog.Title = "用户登录" - sysOperaLog.OperName = "-" + l["businessType"] = "10" + l["title"] = "用户登录" + l["operName"] = "-" } else if strings.Contains(reqUri, "/api/v1/logout") { - sysOperaLog.BusinessType = "11" + l["businessType"] = "11" + l["title"] = "退出登录" } else if strings.Contains(reqUri, "/api/v1/getCaptcha") { - sysOperaLog.BusinessType = "12" - sysOperaLog.Title = "验证码" + l["businessType"] = "12" + l["title"] = "验证码" } else { if reqMethod == "POST" { - sysOperaLog.BusinessType = "1" + l["businessType"] = "1" } else if reqMethod == "PUT" { - sysOperaLog.BusinessType = "2" + l["businessType"] = "2" } else if reqMethod == "DELETE" { - sysOperaLog.BusinessType = "3" + l["businessType"] = "3" } } - sysOperaLog.Method = reqMethod - if len(menuList) > 0 { - sysOperaLog.Title = menuList[0].Title - } - sysOperaLog.CreateBy = user.GetUserId(c) - sysOperaLog.OperTime = pkg.GetCurrentTime() - sysOperaLog.LatencyTime = fmt.Sprintf("%v", latencyTime) - - sysOperaLog.JsonResult = result - sysOperaLog.UserAgent = c.Request.UserAgent() - if status == 200 { - sysOperaLog.Status = "2" + if status == http.StatusOK { + l["status"] = "2" } else { - sysOperaLog.Status = "1" + l["status"] = "1" + } + q := sdk.Runtime.GetCachePrefix(c.Request.Host) + message, err := sdk.Runtime.GetStreamMessage("", global.OperateLog, l) + if err != nil { + log.Errorf("GetStreamMessage error, %s", err.Error()) + //日志报错错误,不中断请求 + } else { + err = q.Append(message) + if err != nil { + log.Errorf("Append message error, %s", err.Error()) + } } - serviceOperaLog := service.SysOperaLog{} - serviceOperaLog.Orm = db - serviceOperaLog.Log = log - _ = serviceOperaLog.InsertSysOperaLog(&sysOperaLog) } diff --git a/app/admin/models/system/sys_login_log.go b/app/admin/models/system/sys_login_log.go index c1bbf1d8..e534d5cb 100644 --- a/app/admin/models/system/sys_login_log.go +++ b/app/admin/models/system/sys_login_log.go @@ -1,9 +1,15 @@ package system import ( - "go-admin/common/models" - + "encoding/json" + "errors" "time" + + "github.com/go-admin-team/go-admin-core/cache" + log "github.com/go-admin-team/go-admin-core/logger" + "github.com/go-admin-team/go-admin-core/sdk" + + "go-admin/common/models" ) type SysLoginLog struct { @@ -35,3 +41,32 @@ func (e *SysLoginLog) Generate() models.ActiveRecord { func (e *SysLoginLog) GetId() interface{} { return e.Id } + +// SaveLoginLog 从队列中获取登录日志 +func SaveLoginLog(message cache.Message) (err error) { + //准备db + db := sdk.Runtime.GetDbByKey(message.GetPrefix()) + if db == nil { + err = errors.New("db not exist") + log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error()) + return err + } + var rb []byte + rb, err = json.Marshal(message.GetValues()) + if err != nil { + log.Errorf("json Marshal error, %s", err.Error()) + return err + } + var l SysLoginLog + err = json.Unmarshal(rb, &l) + if err != nil { + log.Errorf("json Unmarshal error, %s", err.Error()) + return err + } + err = db.Create(&l).Error + if err != nil { + log.Errorf("db create error, %s", err.Error()) + return err + } + return nil +} diff --git a/app/admin/models/system/sys_opera_log.go b/app/admin/models/system/sys_opera_log.go index e7c78be8..e4bed1eb 100644 --- a/app/admin/models/system/sys_opera_log.go +++ b/app/admin/models/system/sys_opera_log.go @@ -1,9 +1,15 @@ package system import ( - "go-admin/common/models" - + "encoding/json" + "errors" "time" + + "github.com/go-admin-team/go-admin-core/cache" + log "github.com/go-admin-team/go-admin-core/logger" + "github.com/go-admin-team/go-admin-core/sdk" + + "go-admin/common/models" ) type SysOperaLog struct { @@ -43,3 +49,37 @@ func (e *SysOperaLog) Generate() models.ActiveRecord { func (e *SysOperaLog) GetId() interface{} { return e.Id } + +// SaveOperaLog 从队列中获取操作日志 +func SaveOperaLog(message cache.Message) (err error) { + //准备db + db := sdk.Runtime.GetDbByKey(message.GetPrefix()) + if db == nil { + err = errors.New("db not exist") + log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error()) + return err + } + var rb []byte + rb, err = json.Marshal(message.GetValues()) + if err != nil { + log.Errorf("json Marshal error, %s", err.Error()) + return err + } + var l SysOperaLog + err = json.Unmarshal(rb, &l) + if err != nil { + log.Errorf("json Unmarshal error, %s", err.Error()) + return err + } + if l.Title == "" { + m := &SysMenu{} + db.Model(m).Select("Title").Where("action = ?", l.Method).Where("path = ?", message.GetValues()["_fullPath"]).First(m) + l.Title = m.Title + } + err = db.Create(&l).Error + if err != nil { + log.Errorf("db create error, %s", err.Error()) + return err + } + return nil +} diff --git a/cmd/api/server.go b/cmd/api/server.go index c95d2df0..0b998e41 100644 --- a/cmd/api/server.go +++ b/cmd/api/server.go @@ -3,8 +3,6 @@ package api import ( "context" "fmt" - "github.com/go-admin-team/go-admin-core/sdk" - "github.com/go-admin-team/go-admin-core/sdk/pkg" "log" "net/http" "os" @@ -13,10 +11,13 @@ import ( "github.com/gin-gonic/gin" "github.com/go-admin-team/go-admin-core/config/source/file" + "github.com/go-admin-team/go-admin-core/sdk" + "github.com/go-admin-team/go-admin-core/sdk/config" + "github.com/go-admin-team/go-admin-core/sdk/pkg" + "github.com/go-admin-team/go-admin-core/sdk/pkg/logger" "github.com/spf13/cobra" - "github.com/go-admin-team/go-admin-core/sdk/config" - "github.com/go-admin-team/go-admin-core/sdk/pkg/logger" + "go-admin/app/admin/models/system" "go-admin/app/admin/router" "go-admin/app/jobs" "go-admin/common/database" @@ -63,10 +64,17 @@ func setup() { //3. 初始化数据库链接 database.Setup() //4. 设置缓存 - sdk.Runtime.SetCacheAdapter(config.CacheConfig.Setup()) + cacheAdapter, err := config.CacheConfig.Setup() + if err != nil { + log.Fatalf("cache setup error, %s\n", err.Error()) + } + sdk.Runtime.SetCacheAdapter(cacheAdapter) usageStr := `starting api server...` log.Println(usageStr) + //注册监听函数 + sdk.Runtime.GetCacheAdapter().Register(global.LoginLog, system.SaveLoginLog) + sdk.Runtime.GetCacheAdapter().Register(global.OperateLog, system.SaveOperaLog) } func run() error { diff --git a/common/global/topic.go b/common/global/topic.go new file mode 100644 index 00000000..ae88ce4d --- /dev/null +++ b/common/global/topic.go @@ -0,0 +1,6 @@ +package global + +const ( + LoginLog = "login_log_queue" + OperateLog = "operate_log_queue" +) diff --git a/go.mod b/go.mod index bbd8bffa..c7552bc7 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 github.com/casbin/casbin/v2 v2.25.1 github.com/gin-gonic/gin v1.6.3 - github.com/go-admin-team/go-admin-core v1.3.1 + github.com/go-admin-team/go-admin-core v1.3.2-rc.0 github.com/google/uuid v1.2.0 github.com/mojocn/base64Captcha v1.3.1 github.com/mssola/user_agent v0.5.2