diff --git a/api/entrance.go b/api/entrance.go index 824725c..02f4e9a 100644 --- a/api/entrance.go +++ b/api/entrance.go @@ -17,6 +17,7 @@ type APIGroup struct { WafAccountApi WafAccountLogApi WafLoginApi + WafSysLogApi } var APIGroupAPP = new(APIGroup) @@ -36,4 +37,6 @@ var ( wafAccountService = waf_service.WafAccountServiceApp wafAccountLogService = waf_service.WafAccountLogServiceApp wafTokenInfoService = waf_service.WafTokenInfoServiceApp + + wafSysLogService = waf_service.WafSysLogServiceApp ) diff --git a/api/waf_sys_log.go b/api/waf_sys_log.go new file mode 100644 index 0000000..ac230e7 --- /dev/null +++ b/api/waf_sys_log.go @@ -0,0 +1,36 @@ +package api + +import ( + "SamWaf/model/common/response" + "SamWaf/model/request" + "github.com/gin-gonic/gin" +) + +type WafSysLogApi struct { +} + +func (w *WafSysLogApi) GetDetailApi(c *gin.Context) { + var req request.WafSysLogDetailReq + err := c.ShouldBind(&req) + if err == nil { + bean := wafSysLogService.GetDetailApi(req) + response.OkWithDetailed(bean, "获取成功", c) + } else { + response.FailWithMessage("解析失败", c) + } +} +func (w *WafSysLogApi) GetListApi(c *gin.Context) { + var req request.WafSysLogSearchReq + err := c.ShouldBind(&req) + if err == nil { + beans, total, _ := wafSysLogService.GetListApi(req) + response.OkWithDetailed(response.PageResult{ + List: beans, + Total: total, + PageIndex: req.PageIndex, + PageSize: req.PageSize, + }, "获取成功", c) + } else { + response.FailWithMessage("解析失败", c) + } +} diff --git a/localwaf/src/apis/syslog.ts b/localwaf/src/apis/syslog.ts new file mode 100644 index 0000000..cf8d53c --- /dev/null +++ b/localwaf/src/apis/syslog.ts @@ -0,0 +1,10 @@ +import request from '@/utils/request' + +//查询所有系统操作日志列表 +export function sys_log_list_api(params) { + return request({ + url: 'sys_log/list', + method: 'get', + params: params + }) +} diff --git a/localwaf/src/pages/waf/accountlog/index.vue b/localwaf/src/pages/waf/accountlog/index.vue index f26fcfd..80852db 100644 --- a/localwaf/src/pages/waf/accountlog/index.vue +++ b/localwaf/src/pages/waf/accountlog/index.vue @@ -6,7 +6,7 @@ 导出日志

已选{{ selectedRowKeys.length }}项

- + diff --git a/localwaf/src/pages/waf/syslog/detail/index.less b/localwaf/src/pages/waf/syslog/detail/index.less new file mode 100644 index 0000000..d599763 --- /dev/null +++ b/localwaf/src/pages/waf/syslog/detail/index.less @@ -0,0 +1,106 @@ +@import '@/style/variables.less'; + +.detail-base { + /deep/ .t-card { + padding: 8px; + } + + /deep/ .t-card__title { + font-size: 20px; + font-weight: 500; + } + + &-info-steps { + padding-top: 12px; + } +} + +.info-block { + column-count: 2; + + .info-item { + padding: 12px 0; + display: flex; + color: var(--td-text-color-primary); + + h1 { + width: 200px; + font-weight: normal; + font-size: @font-size-base; + color: var(--td-text-color-secondary); + text-align: left; + line-height: 22px; + + @media (max-width: @screen-sm-max) { + width: 100px; + } + + @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { + width: 120px; + } + } + + span { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + margin-left: 24px; + } + + i { + display: inline-block; + width: 8px; + height: 8px; + border-radius: @border-radius-50; + background: var(--td-success-color-5); + } + + .inProgress { + color: var(--td-success-color-5); + } + + .pdf { + color: var(--td-brand-color); + + &:hover { + cursor: pointer; + } + } + } +} + +.dialog-info-block { + .info-item { + padding: 12px 0; + display: flex; + + h1 { + width: 84px; + font-family: PingFangSC-Regular; + font-size: 14px; + color: var(--td-text-color-secondary); + text-align: left; + line-height: 22px; + } + + span { + margin-left: 24px; + } + + i { + display: inline-block; + width: 8px; + height: 8px; + border-radius: @border-radius-50; + background: var(--td-success-color-5); + } + + .green { + color: var(--td-success-color-5); + } + + .blue { + color: var(--td-brand-color-8); + } + } +} diff --git a/localwaf/src/pages/waf/syslog/detail/index.vue b/localwaf/src/pages/waf/syslog/detail/index.vue new file mode 100644 index 0000000..c0ede96 --- /dev/null +++ b/localwaf/src/pages/waf/syslog/detail/index.vue @@ -0,0 +1,148 @@ + + + diff --git a/localwaf/src/pages/waf/syslog/index.vue b/localwaf/src/pages/waf/syslog/index.vue new file mode 100644 index 0000000..d04c5b3 --- /dev/null +++ b/localwaf/src/pages/waf/syslog/index.vue @@ -0,0 +1,333 @@ + + + + diff --git a/localwaf/src/router/modules/waf.ts b/localwaf/src/router/modules/waf.ts index 0175302..a7deb6b 100644 --- a/localwaf/src/router/modules/waf.ts +++ b/localwaf/src/router/modules/waf.ts @@ -48,6 +48,25 @@ export default [ ], }, + + { + path: '/sys', + name: 'sys', + component: Layout, + redirect: '/sys', + meta: { title: '系统设置', icon: ViewModuleIcon }, + children: [ + { + path: 'SysLog', + name: 'SysLog', + component: () => import('@/pages/waf/syslog/index.vue'), + meta: { title: '系统操作日志' }, + }, + + + ], + }, + { path: '/waf-host', name: 'wafhost', diff --git a/model/request/waf_sys_log_detail_req.go b/model/request/waf_sys_log_detail_req.go new file mode 100644 index 0000000..abba5b6 --- /dev/null +++ b/model/request/waf_sys_log_detail_req.go @@ -0,0 +1,5 @@ +package request + +type WafSysLogDetailReq struct { + Id string `json:"id" form:"id"` //唯一键 +} diff --git a/model/request/waf_sys_log_search.go b/model/request/waf_sys_log_search.go new file mode 100644 index 0000000..9196be4 --- /dev/null +++ b/model/request/waf_sys_log_search.go @@ -0,0 +1,9 @@ +package request + +import "SamWaf/model/common/request" + +type WafSysLogSearchReq struct { + OpType string `json:"op_type" form:"op_type"` //操作类型 + OpContent string `json:"op_content" form:"op_content"` //操作内容 + request.PageInfo +} diff --git a/model/waf_sys.go b/model/waf_sys.go new file mode 100644 index 0000000..663eb74 --- /dev/null +++ b/model/waf_sys.go @@ -0,0 +1,12 @@ +package model + +import "time" + +type WafSysLog struct { + Id string `gorm:"primary_key" json:"id"` + UserCode string `json:"user_code"` //用户码(主要键) + TenantId string `json:"tenant_id"` //租户ID(主要键) + OpType string `json:"op_type"` //操作类型 + OpContent string `json:"op_content"` //操作内容 + CreateTime time.Time `json:"create_time"` //创建时间 +} diff --git a/router/entrance.go b/router/entrance.go index a225c73..9f33730 100644 --- a/router/entrance.go +++ b/router/entrance.go @@ -15,6 +15,7 @@ type ApiGroup struct { AccountRouter AccountLogRouter LoginOutRouter + SysLogRouter } type PublicApiGroup struct { LoginRouter diff --git a/router/waf_sys_log.go b/router/waf_sys_log.go new file mode 100644 index 0000000..aeaf0f0 --- /dev/null +++ b/router/waf_sys_log.go @@ -0,0 +1,16 @@ +package router + +import ( + "SamWaf/api" + "github.com/gin-gonic/gin" +) + +type SysLogRouter struct { +} + +func (receiver *SysLogRouter) InitSysLogRouter(group *gin.RouterGroup) { + api := api.APIGroupAPP.WafSysLogApi + router := group.Group("") + router.GET("/samwaf/sys_log/list", api.GetListApi) + router.GET("/samwaf/sys_log/detail", api.GetDetailApi) +} diff --git a/service/waf_service/waf_sys_log.go b/service/waf_service/waf_sys_log.go new file mode 100644 index 0000000..f390065 --- /dev/null +++ b/service/waf_service/waf_sys_log.go @@ -0,0 +1,24 @@ +package waf_service + +import ( + "SamWaf/global" + "SamWaf/model" + "SamWaf/model/request" +) + +type WafSysLogService struct{} + +var WafSysLogServiceApp = new(WafSysLogService) + +func (receiver *WafSysLogService) GetDetailApi(req request.WafSysLogDetailReq) model.WafSysLog { + var bean model.WafSysLog + global.GWAF_LOCAL_LOG_DB.Debug().Where("id=?", req.Id).Find(&bean) + return bean +} +func (receiver *WafSysLogService) GetListApi(req request.WafSysLogSearchReq) ([]model.WafSysLog, int64, error) { + var bean []model.WafSysLog + var total int64 = 0 + global.GWAF_LOCAL_LOG_DB.Debug().Limit(req.PageSize).Offset(req.PageSize * (req.PageIndex - 1)).Find(&bean) + global.GWAF_LOCAL_LOG_DB.Debug().Model(&model.WafSysLog{}).Count(&total) + return bean, total, nil +} diff --git a/wafenginecore/localdb.go b/wafenginecore/localdb.go index a6a58b8..c3ce20e 100644 --- a/wafenginecore/localdb.go +++ b/wafenginecore/localdb.go @@ -57,6 +57,7 @@ func InitDb() { logDB.AutoMigrate(&model.StatsIPCityDay{}) logDB.AutoMigrate(&innerbean.WebLog{}) logDB.AutoMigrate(&model.AccountLog{}) + logDB.AutoMigrate(&model.WafSysLog{}) global.GWAF_LOCAL_LOG_DB.Callback().Query().Before("gorm:query").Register("tenant_plugin:before_query", before_query) } diff --git a/wafenginecore/localserver.go b/wafenginecore/localserver.go index 5189acd..1cd2c18 100644 --- a/wafenginecore/localserver.go +++ b/wafenginecore/localserver.go @@ -31,6 +31,7 @@ func InitRouter(r *gin.Engine) { router.ApiGroupApp.InitAccountRouter(RouterGroup) router.ApiGroupApp.InitAccountLogRouter(RouterGroup) router.ApiGroupApp.InitLoginOutRouter(RouterGroup) + router.ApiGroupApp.InitSysLogRouter(RouterGroup) } PublicRouterGroup := r.Group("") router.PublicApiGroupApp.InitLoginRouter(PublicRouterGroup) diff --git a/wafenginecore/wafengine.go b/wafenginecore/wafengine.go index f217376..2f0961a 100644 --- a/wafenginecore/wafengine.go +++ b/wafenginecore/wafengine.go @@ -519,6 +519,17 @@ func (waf *WafEngine) Start_WAF() { waf.HostCode[hosts[i].Code] = hosts[i].Host + ":" + strconv.Itoa(hosts[i].Port) } + + wafSysLog := &model.WafSysLog{ + Id: uuid.NewV4().String(), + UserCode: global.GWAF_USER_CODE, + TenantId: global.GWAF_TENANT_ID, + OpType: "信息", + OpContent: "WAF启动", + CreateTime: time.Now(), + } + global.GWAF_LOCAL_LOG_DB.Create(wafSysLog) + for _, v := range waf.ServerOnline { go func(innruntime innerbean.ServerRunTime) { @@ -547,6 +558,16 @@ func (waf *WafEngine) Start_WAF() { if err == http.ErrServerClosed { zlog.Info("[HTTPServer] https server has been close, cause:[%v]", err) } else { + //TODO 记录如果https 端口被占用的情况 记录日志 且应该推送websocket + wafSysLog := model.WafSysLog{ + Id: uuid.NewV4().String(), + UserCode: global.GWAF_USER_CODE, + TenantId: global.GWAF_TENANT_ID, + OpType: "系统运行错误", + OpContent: "HTTPS端口被占用: " + strconv.Itoa(innruntime.Port) + ",请检查", + CreateTime: time.Time{}, + } + global.GWAF_LOCAL_LOG_DB.Create(wafSysLog) zlog.Error("[HTTPServer] https server start fail, cause:[%v]", err) } zlog.Info("server https shutdown") @@ -571,6 +592,16 @@ func (waf *WafEngine) Start_WAF() { if err == http.ErrServerClosed { zlog.Warn("[HTTPServer] http server has been close, cause:[%v]", err) } else { + //TODO 记录如果http 端口被占用的情况 记录日志 且应该推送websocket + wafSysLog := model.WafSysLog{ + Id: uuid.NewV4().String(), + UserCode: global.GWAF_USER_CODE, + TenantId: global.GWAF_TENANT_ID, + OpType: "系统运行错误", + OpContent: "HTTP端口被占用: " + strconv.Itoa(innruntime.Port) + ",请检查", + CreateTime: time.Time{}, + } + global.GWAF_LOCAL_LOG_DB.Create(wafSysLog) zlog.Error("[HTTPServer] http server start fail, cause:[%v]", err) } zlog.Info("server http shutdown") @@ -589,6 +620,15 @@ func (waf *WafEngine) CLoseWAF() { zlog.Debug("关闭 recover ", e) } }() + wafSysLog := &model.WafSysLog{ + Id: uuid.NewV4().String(), + UserCode: global.GWAF_USER_CODE, + TenantId: global.GWAF_TENANT_ID, + OpType: "信息", + OpContent: "WAF关闭", + CreateTime: time.Now(), + } + global.GWAF_LOCAL_LOG_DB.Create(wafSysLog) waf.EngineCurrentStatus = 0 for _, v := range waf.ServerOnline { if v.Svr != nil {