package bo import ( "scd_check_tools/logger" "scd_check_tools/models/enum" "scd_check_tools/tools" "encoding/json" "errors" "fmt" "io/fs" "os" "strconv" "strings" "sync" "time" "github.com/astaxie/beego/orm" _ "github.com/astaxie/beego/orm" ) //系统操作日志管理 type SystemLog struct { DeviceBaseModel //操作分类 Logtype enum.LogType //审计分类 Audittype enum.AuditType //事件分类 Eventtype enum.OptEventType //事件等级 Eventlevel enum.OptEventLevel //日志内容 Description string } type Global_syslog struct { Id int64 `orm:"pk;auto"` Insdate string `orm:"size(20)"` Description string `orm:"size(500)"` Staff string `orm:"size(50)"` //操作分类 Logtype int //审计分类 Audittype int //事件分类 Eventtype int //事件等级 Eventlevel int Success int Ip string } func init() { orm.RegisterModel(new(Global_syslog)) } //操作失败日志记录 //该方法通过属性设置方式完成属性值的赋予 func (c *SystemLog) Fail2() { c.Fail(c.Audittype, c.Logtype, c.Eventtype, c.Eventlevel, c.Description, c.GetUserInfo()) } //操作失败日志记录 //该方法通过参数方式完成属性值的赋予 func (c *SystemLog) Fail(module enum.AuditType, logtype enum.LogType, event enum.OptEventType, eventlevel enum.OptEventLevel, desc string, uinfo ...map[string]interface{}) { u_info := c.GetUserInfo() if u_info == nil { if len(uinfo) > 0 { c.SetUserInfo(uinfo[0]) } else { logger.Logger.Error("写日志记录失败:未指定的当前用户对象") return } } username := c.GetUserName() if username == "" { username = "系统内置用户" } go SaveSyslog(desc, module, logtype, event, eventlevel, enum.OptResult_Fail, username, c.GetIP()) } //操作成功日志记录 //该方法通过属性设置方式完成属性值的赋予 func (c *SystemLog) Success2() { c.Success(c.Audittype, c.Logtype, c.Eventtype, c.Eventlevel, c.Description, c.GetUserInfo()) } //操作成功日志记录 //该方法通过参数方式完成属性值的赋予 func (c *SystemLog) Success(module enum.AuditType, logtype enum.LogType, event enum.OptEventType, eventlevel enum.OptEventLevel, desc string, uinfo ...map[string]interface{}) { u_info := c.GetUserInfo() if u_info == nil { if len(uinfo) > 0 { c.SetUserInfo(uinfo[0]) } else { logger.Logger.Error("写日志记录失败:未指定的当前用户对象") return } } username := c.GetUserName() if username == "" { username = "系统内置用户" } go SaveSyslog(desc, module, logtype, event, eventlevel, enum.OptResult_Success, username, c.GetIP()) } //清除所有日志数据 func ClearAllSyslog() (err error) { o := orm.NewOrm() sqlCommandText := "delete from global_syslog" _, err = o.Raw(sqlCommandText).Exec() if err != nil { return err } else { return nil } } //根据日志配置(如存储时长、容量限制等)自动清除符合条件的日志数据 func ClearSyslog(clearbeforedate string) (err error) { o := orm.NewOrm() sqlCommandText := "delete from global_syslog where insdate 0 { obj.Ip = ip[0] } var id int64 id, err = o.Insert(&obj) return id, err } //查询系统日志 func (c *SystemLog) SearchLogList(cond map[string]string, pageIndex, pageSize int) ([]orm.Params, int, error) { o := orm.NewOrm() var totalSql string var sqlCondition []string var sqlParameter []interface{} var sqlCommandText = ` select t.*,t1.name audittypename,t2.name logtypename,t3.name eventtypename,t4.name optresultname,t5.name eventlevelname from global_syslog t left join global_const_code t1 on t.audittype=t1.code and t1.parentcode='log_audittype' left join global_const_code t2 on t.logtype=t2.code and t2.parentcode='log_opttype' left join global_const_code t3 on t.eventtype=t3.code and t3.parentcode='log_eventtype' left join global_const_code t4 on t.success=t4.code and t4.parentcode='log_optresult' left join global_const_code t5 on t.eventlevel=t5.code and t5.parentcode='log_eventlevel' ` endDate := cond["enddate"] if endDate != "" { endDate += " 23:59:59" } startDate := cond["startdate"] if startDate != "" && endDate != "" { sqlCondition = append(sqlCondition, "t.insdate between ? and ? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00", endDate) } else if startDate != "" { sqlCondition = append(sqlCondition, "t.insdate>=? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00") } else if endDate != "" { sqlCondition = append(sqlCondition, "t.insdate<=? ") sqlParameter = append(sqlParameter, endDate) } description := cond["description"] if description != "" { sqlCondition = append(sqlCondition, "t.description like concat('%',?,'%')") sqlParameter = append(sqlParameter, description) } staff := cond["staff"] if staff != "" { sqlCondition = append(sqlCondition, "t.staff like concat('%',?,'%')") sqlParameter = append(sqlParameter, staff) } ip := cond["ip"] if ip != "" { sqlCondition = append(sqlCondition, "t.ip like concat('%',?,'%')") sqlParameter = append(sqlParameter, ip) } success := cond["success"] if success != "" { sqlCondition = append(sqlCondition, "t.success=?") sqlParameter = append(sqlParameter, success) } logtype := cond["logtype"] if logtype != "" { sqlCondition = append(sqlCondition, "t.logtype=?") sqlParameter = append(sqlParameter, logtype) } audittype := cond["audittype"] if audittype != "" { sqlCondition = append(sqlCondition, "t.audittype=?") sqlParameter = append(sqlParameter, audittype) } eventtype := cond["eventtype"] if eventtype != "" { sqlCondition = append(sqlCondition, "t.eventtype=?") sqlParameter = append(sqlParameter, eventtype) } eventlevel := cond["eventlevel"] if eventlevel != "" { sqlCondition = append(sqlCondition, "t.eventlevel=?") sqlParameter = append(sqlParameter, eventlevel) } if len(sqlCondition) > 0 { sqlCommandText += " where " + strings.Join(sqlCondition, " and ") totalSql = "select count(1) number from global_syslog t where " + strings.Join(sqlCondition, " and ") } else { totalSql = "select count(1) number from global_syslog t " } var limit = " limit " + strconv.Itoa((pageIndex-1)*pageSize) + "," + strconv.Itoa(pageSize) sqlCommandText += " order by t.id desc " + limit var tableData []orm.Params var number int _, err := o.Raw(sqlCommandText, sqlParameter).Values(&tableData) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_Query c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Hight sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sqlCommandText, sqlParameter) c.Description = sqllog if err == nil { c.Success2() if len(tableData) > 0 { var totalData []orm.Params _, err = o.Raw(totalSql, sqlParameter).Values(&totalData) if err == nil { number, _ = strconv.Atoi(totalData[0]["number"].(string)) } } } else { c.Fail2() } return tableData, number, err } func (c *SystemLog) EchartStat(cond map[string]string) (map[string]interface{}, error) { statcycle := cond["cycletype"] //"%Y%m%d" //统计周期 if statcycle == "" { statcycle = "hour" } switch statcycle { case "year": statcycle = "%Y" case "month": statcycle = "%Y%m" case "day": statcycle = "%Y%m%d" case "hour": statcycle = "%Y%m%d%H" case "week": statcycle = "%Y%u" default: statcycle = "%Y%m%d" } sqlCondition := []string{} sqlParameter := []interface{}{} endDate := cond["enddate"] if endDate != "" { endDate += " 23:59:59" } startDate := cond["startdate"] if startDate != "" && endDate != "" { sqlCondition = append(sqlCondition, "t.insdate between ? and ? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00") sqlParameter = append(sqlParameter, endDate) } else if startDate != "" { sqlCondition = append(sqlCondition, "t.insdate>=? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00") } else if endDate != "" { sqlCondition = append(sqlCondition, "t.insdate<=? ") sqlParameter = append(sqlParameter, endDate) } description := cond["description"] if description != "" { sqlCondition = append(sqlCondition, "t.description like concat('%',?,'%')") sqlParameter = append(sqlParameter, description) } staff := cond["staff"] if staff != "" { sqlCondition = append(sqlCondition, "t.staff like concat('%',?,'%')") sqlParameter = append(sqlParameter, staff) } ip := cond["ip"] if ip != "" { sqlCondition = append(sqlCondition, "t.ip like concat('%',?,'%')") sqlParameter = append(sqlParameter, ip) } success := cond["success"] if success != "" { sqlCondition = append(sqlCondition, "t.success=?") sqlParameter = append(sqlParameter, success) } logtype := cond["logtype"] if logtype != "" { sqlCondition = append(sqlCondition, "t.logtype=?") sqlParameter = append(sqlParameter, logtype) } audittype := cond["audittype"] if audittype != "" { sqlCondition = append(sqlCondition, "t.audittype=?") sqlParameter = append(sqlParameter, audittype) } eventtype := cond["eventtype"] if eventtype != "" { sqlCondition = append(sqlCondition, "t.eventtype=?") sqlParameter = append(sqlParameter, eventtype) } eventlevel := cond["eventlevel"] if eventlevel != "" { sqlCondition = append(sqlCondition, "t.eventlevel=?") sqlParameter = append(sqlParameter, eventlevel) } eventstat := []orm.Params{} tableData := []orm.Params{} optypestat := []orm.Params{} staffstat := []orm.Params{} ipstat := []orm.Params{} o := orm.NewOrm() var wg = sync.WaitGroup{} wg.Add(5) go func() { sql := "select DATE_FORMAT(t.insdate,'" + statcycle + "') dt, count(0) num from global_syslog t " if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY dt" _, err := o.Raw(sql, sqlParameter).Values(&tableData) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_chartstat c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } wg.Done() }() go func() { sql := "SELECT t.eventtype ,count(0) num from global_syslog t " if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY eventtype" _, err := o.Raw(sql, sqlParameter).Values(&eventstat) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_datastat c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } wg.Done() }() go func() { sql := "SELECT t.logtype,count(0) num from global_syslog t " if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY logtype" _, err := o.Raw(sql, sqlParameter).Values(&optypestat) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_datastat c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } wg.Done() }() go func() { sql := "SELECT t.staff,count(0) num from global_syslog t " if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY staff" _, err := o.Raw(sql, sqlParameter).Values(&staffstat) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_datastat c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } wg.Done() }() go func() { sql := "SELECT t.ip,count(0) num from global_syslog t " if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY ip" _, err := o.Raw(sql, sqlParameter).Values(&ipstat) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_datastat c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } wg.Done() }() wg.Wait() result := map[string]interface{}{"list": tableData, "eventstat": eventstat, "optypestat": optypestat, "staffstat": staffstat, "ipstat": ipstat} return result, nil } func (c *SystemLog) DataStat(cond map[string]string) ([]orm.Params, error) { sqlCondition := []string{} sqlParameter := []interface{}{} endDate := cond["enddate"] if endDate == "" { endDate = time.Now().Format("2006-01-02") } startDate := cond["startdate"] if startDate == "" { startDate = time.Now().Format("2006-01-02") } sqlCondition = append(sqlCondition, "t.insdate between ? and ? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00") sqlParameter = append(sqlParameter, endDate+" 23:59:59") description := cond["description"] if description != "" { sqlCondition = append(sqlCondition, "t.description like concat('%',?,'%')") sqlParameter = append(sqlParameter, description) } staff := cond["staff"] if staff != "" { sqlCondition = append(sqlCondition, "t.staff like concat('%',?,'%')") sqlParameter = append(sqlParameter, staff) } ip := cond["ip"] if ip != "" { sqlCondition = append(sqlCondition, "t.ip like concat('%',?,'%')") sqlParameter = append(sqlParameter, ip) } success := cond["success"] if success != "" { sqlCondition = append(sqlCondition, "t.success=?") sqlParameter = append(sqlParameter, success) } logtype := cond["logtype"] if logtype != "" { sqlCondition = append(sqlCondition, "t.logtype=?") sqlParameter = append(sqlParameter, logtype) } audittype := cond["audittype"] if audittype != "" { sqlCondition = append(sqlCondition, "t.audittype=?") sqlParameter = append(sqlParameter, audittype) } eventtype := cond["eventtype"] if eventtype != "" { sqlCondition = append(sqlCondition, "t.eventtype=?") sqlParameter = append(sqlParameter, eventtype) } eventlevel := cond["eventlevel"] if eventlevel != "" { sqlCondition = append(sqlCondition, "t.eventlevel=?") sqlParameter = append(sqlParameter, eventlevel) } statresult := []orm.Params{} o := orm.NewOrm() sql := "" dtstr := fmt.Sprintf("%s到%s", startDate, endDate) stattype := cond["stattype"] if stattype == "" { sql = `SELECT t.staff,t.ip,t.logtype,t.eventtype,n1.name logtypename ,n2.name eventtypename,count(0) num, '` + dtstr + `' dt from global_syslog t LEFT JOIN global_const_code n1 on t.logtype=n1.code and n1.parentcode='log_opttype' LEFT JOIN global_const_code n2 on t.eventtype=n2.code and n2.parentcode='log_eventtype' ` if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY staff,ip,logtype,eventtype limit 0,1000" } else if stattype == "logtype" { sql = `SELECT t.logtype,n1.name logtypename ,count(0) num, '` + dtstr + `' dt from global_syslog t LEFT JOIN global_const_code n1 on t.logtype=n1.code and n1.parentcode='log_opttype' ` if len(sqlCondition) > 0 { sql += " where " + strings.Join(sqlCondition, " and ") } sql += " GROUP BY logtype " } _, err := o.Raw(sql, sqlParameter).Values(&statresult) c.Audittype = enum.AuditType_admin_system_logquery c.Logtype = enum.LogType_datastat c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } return statresult, err } //日志备份 func (c *SystemLog) Backup(param map[string]string) error { c.Audittype = enum.AuditType_admin_logbackorrecorvey c.Logtype = enum.LogType_Insert c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Mid backstartdate := param["startdate"] backenddate := param["enddate"] sql := "insert into global_backup(backtype,backdate,backstaff,backfilepath,datastartdate,dataenddate,backfilesize)values(?,?,?,?,?,?,?)" sqlParameter := []interface{}{} sqlParameter = append(sqlParameter, "log") sqlParameter = append(sqlParameter, tools.NowTime()) sqlParameter = append(sqlParameter, c.GetUserName()) fname := fmt.Sprintf("%d.json", time.Now().Unix()) fpath := strings.Join([]string{"static", "backup", "log"}, string(os.PathSeparator)) os.MkdirAll(fpath, fs.ModeDir) logfilepath := fpath + string(os.PathSeparator) + fname sqlParameter = append(sqlParameter, logfilepath) sqlParameter = append(sqlParameter, backstartdate) sqlParameter = append(sqlParameter, backenddate) logfile, err := os.OpenFile(logfilepath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775) defer logfile.Close() if err != nil { logger.Logger.Error(err) return nil } o := orm.NewOrm() querySql := "select * from global_syslog where insdate BETWEEN ? and ?" rowset := []orm.Params{} o.Raw(querySql, backstartdate, backenddate).Values(&rowset) if len(rowset) == 0 { c.Description = fmt.Sprintf("日期范围%s到%s内没有可备份的日志数据!", backstartdate, backenddate) c.Fail2() return errors.New(c.Description) } logbytes, _ := json.Marshal(rowset) n, _ := logfile.Write(logbytes) sqlParameter = append(sqlParameter, n) _, err = o.Raw(sql, sqlParameter).Exec() sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParameter) c.Description = sqllog if err == nil { c.Success2() } else { c.Fail2() } return err } func (c *SystemLog) BackupList(cond map[string]string, pageIndex, pageSize int) ([]orm.Params, int, error) { o := orm.NewOrm() var totalSql string var sqlCondition []string var sqlParameter []interface{} var sqlCommandText = ` select t.* from global_backup t where t.backtype='log' ` endDate := cond["enddate"] if endDate != "" { endDate += " 23:59:59" } startDate := cond["startdate"] if startDate != "" && endDate != "" { sqlCondition = append(sqlCondition, "t.backdate between ? and ? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00", endDate) } else if startDate != "" { sqlCondition = append(sqlCondition, "t.backdate>=? ") sqlParameter = append(sqlParameter, startDate+" 00:00:00") } else if endDate != "" { sqlCondition = append(sqlCondition, "t.backdate<=? ") sqlParameter = append(sqlParameter, endDate) } staff := cond["staff"] if staff != "" { sqlCondition = append(sqlCondition, "t.backstaff like concat('%',?,'%')") sqlParameter = append(sqlParameter, staff) } if len(sqlCondition) > 0 { sqlCommandText += strings.Join(sqlCondition, " and ") totalSql = "select count(1) number from global_backup t where t.backtype='log' and " + strings.Join(sqlCondition, " and ") } else { totalSql = "select count(1) number from global_backup t where t.backtype='log' " } var limit = " limit " + strconv.Itoa((pageIndex-1)*pageSize) + "," + strconv.Itoa(pageSize) sqlCommandText += " order by t.id desc " + limit var tableData []orm.Params var number int _, err := o.Raw(sqlCommandText, sqlParameter).Values(&tableData) c.Audittype = enum.AuditType_admin_logbackorrecorvey c.Logtype = enum.LogType_Query c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Low sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sqlCommandText, sqlParameter) c.Description = sqllog if err == nil { c.Success2() if len(tableData) > 0 { var totalData []orm.Params _, err = o.Raw(totalSql, sqlParameter).Values(&totalData) if err == nil { number, _ = strconv.Atoi(totalData[0]["number"].(string)) } } } else { c.Fail2() } return tableData, number, err } func (c *SystemLog) Delete(id int) (err error) { c.Audittype = enum.AuditType_admin_logbackorrecorvey c.Logtype = enum.LogType_Delete c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Hight db := orm.NewOrm() modle := Global_backup{Id: id} if modle.Id == 0 { return errors.New("无效的ID") } else { db.Read(&modle) _, err = db.Delete(&modle) } if err != nil { logger.Logger.Error(err) c.Description = fmt.Sprintf("删除日志备份%s失败:%s", modle.Backdate, err.Error()) c.Fail2() } else { ferr := os.Remove("." + string(os.PathSeparator) + modle.Backfilepath) if ferr != nil { logger.Logger.Error(ferr, modle.Backfilepath) } c.Description = fmt.Sprintf("删除日志备份%s成功", modle.Backdate) c.Success2() } return err } //将数据还原到指定备份 func (c *SystemLog) Recover(backid int) (err error) { c.Audittype = enum.AuditType_admin_logbackorrecorvey c.Logtype = enum.LogType_Execute c.Eventtype = enum.OptEventType_Bus c.Eventlevel = enum.OptEventLevel_Mid db := orm.NewOrm() model := Global_backup{Id: backid} err = db.Read(&model) if err != nil { logger.Logger.Error(err) return err } go func(model Global_backup) { fn := "." + string(os.PathSeparator) + model.Backfilepath btys, err := os.ReadFile(fn) if err != nil { logger.Logger.Error(err) return } logs := []map[string]interface{}{} err = json.Unmarshal(btys, &logs) if err != nil { logger.Logger.Error(err) c.Description = fmt.Sprintf("日志还原失败:%s,操作数据:%+v", err.Error(), model) c.Fail2() } else { if len(logs) > 0 { } c.Description = fmt.Sprintf("日志还原成功,操作数据:%+v", model) c.Success2() } }(model) return err }