소스 검색

Add 添加清除设备日志定时任务

YueYunyun 2 년 전
부모
커밋
2234eb7566

+ 64 - 0
SERVER/IotAdmin/app/schedule/jobs/clean-log.go

@@ -0,0 +1,64 @@
+package jobs
+
+import (
+	"IotAdmin/core/logger"
+	iotLog "IotAdmin/iot/log"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// CleanLog
+// 新添加的job 必须按照以下格式定义,并实现Exec函数
+type CleanLog struct {
+}
+
+func (t *CleanLog) Exec(arg interface{}) error {
+	logger.Info(time.Now().Format(timeFormat) + " [INFO] JobCore CleanLog exec START")
+	switch arg.(type) {
+	case string:
+		if arg.(string) != "" {
+			str := arg.(string)
+			arr := strings.Split(str, ",")
+			p1, err := strconv.Atoi(arr[0])
+			if err != nil {
+				logger.Error(time.Now().Format(timeFormat) + " [ERROR] JobCore CleanLog exec error:" + err.Error())
+				return err
+			}
+			if len(arr) > 1 {
+				p2, err := strconv.Atoi(arr[1])
+				if err != nil {
+					logger.Error(time.Now().Format(timeFormat) + " [ERROR] JobCore CleanLog exec error:" + err.Error())
+					return err
+				}
+				err = iotLog.Clean(p1, p2)
+				if err != nil {
+					logger.Error(time.Now().Format(timeFormat) + " [ERROR] JobCore CleanLog exec error:" + err.Error())
+					return err
+				}
+			} else {
+				err = iotLog.Clean(p1, p1)
+				if err != nil {
+					logger.Error(time.Now().Format(timeFormat) + " [ERROR] JobCore CleanLog exec error:" + err.Error())
+					return err
+				}
+			}
+		} else {
+			logger.Errorf(time.Now().Format(timeFormat) + " [ERROR] JobCore CleanLog exec error: arg is empty")
+		}
+		break
+	case int:
+		if arg.(int) != 0 {
+			p := arg.(int)
+			err := iotLog.Clean(p, p)
+			if err != nil {
+				logger.Error(time.Now().Format(timeFormat) + " [ERROR] JobCore CleanLog exec error:" + err.Error())
+				return err
+			}
+		}
+		break
+	default:
+	}
+
+	return nil
+}

+ 6 - 7
SERVER/IotAdmin/app/schedule/jobs/examples.go

@@ -1,7 +1,7 @@
 package jobs
 
 import (
-	"fmt"
+	"IotAdmin/core/logger"
 	"time"
 )
 
@@ -11,19 +11,18 @@ type ExamplesOne struct {
 }
 
 func (t *ExamplesOne) Exec(arg interface{}) error {
-	str := time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec success"
+	logger.Info(time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec START")
 	// TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化;
 	switch arg.(type) {
-
 	case string:
 		if arg.(string) != "" {
-			fmt.Println("string", arg.(string))
-			fmt.Println(str, arg.(string))
+
 		} else {
-			fmt.Println("arg is nil")
-			fmt.Println(str, "arg is nil")
+			logger.Errorf(time.Now().Format(timeFormat) + " [ERROR] JobCore ExamplesOne exec error: arg is empty")
 		}
 		break
+	case int:
+		break
 	}
 
 	return nil

+ 1 - 2
SERVER/IotAdmin/app/schedule/jobs/init.go

@@ -25,6 +25,7 @@ func InitJob() {
 // 字典 key 可以配置到 自动任务 调用目标 中;
 func initJobList() {
 	jobList = map[string]JobExec{
+		"CleanLog":    &CleanLog{},
 		"ExamplesOne": &ExamplesOne{},
 		// ...
 	}
@@ -32,9 +33,7 @@ func initJobList() {
 
 // Setup 初始化
 func Setup(dbs map[string]*gorm.DB) {
-
 	fmt.Println(time.Now().Format(timeFormat), " [INFO] JobCore Starting...")
-
 	for k, db := range dbs {
 		sdk.Runtime.SetCrontab(k, cronjob.NewWithSeconds())
 		setup(k, db)

+ 1 - 1
SERVER/IotAdmin/app/system/apis/welcome.go

@@ -9,7 +9,7 @@ const INDEX = `
 <html>
 <head>
 <meta charset="utf-8">
-<title>VerAdmin欢迎您</title>
+<title>IOTAdmin欢迎您</title>
 <style>
 body{
   margin:0; 

+ 1 - 0
SERVER/IotAdmin/config/sql/db.sql

@@ -436,6 +436,7 @@ INSERT INTO sys_dict_data VALUES (54, 2, '表计主动上报', '2', 'iot_device_
 
 INSERT INTO sys_job VALUES (1, '接口测试', 'SYSTEM', 1, '0/5 * * * * ', 'http://localhost:6071', '', 1, 1, 1, 0, 1, 1, '2024-03-14 00:00:00.000', '2024-03-14 00:00:00.000', NULL);
 INSERT INTO sys_job VALUES (2, '函数测试', 'SYSTEM', 2, '0/5 * * * * ', 'ExamplesOne', '参数', 1, 1, 1, 0, 1, 1, '2024-03-14 00:00:00.000', '2024-03-14 00:00:00.000', NULL);
+INSERT INTO sys_job VALUES (3, '清除日志', 'SYSTEM', 2, '30 0 0 * * ?', 'CleanLog', '1', 1, 2, 2, 2, 1, 1, '2024-04-02 17:45:13.384', '2024-04-02 17:47:15.219', NULL);
 
 
 INSERT INTO sys_post VALUES (1, '默认岗位', 'CEO', 0, '2','默认岗位', 1, 1, '2024-03-14 00:00:00.000', '2024-03-14 00:00:00.000', NULL);

+ 2 - 32
SERVER/IotAdmin/iot/db/device.go

@@ -4,16 +4,14 @@ import (
 	"IotAdmin/app/iot/models"
 	"IotAdmin/core/logger"
 	"IotAdmin/core/sdk"
-	"IotAdmin/core/sdk/config"
 	"IotAdmin/core/storage"
-	"IotAdmin/core/tools/writer"
 	"IotAdmin/iot/constant"
+	iotLog "IotAdmin/iot/log"
 	iotMap "IotAdmin/iot/map"
 	iotStruct "IotAdmin/iot/struct"
 	"encoding/json"
 	"errors"
 	"fmt"
-	"log"
 
 	"gorm.io/gorm"
 )
@@ -66,7 +64,7 @@ func addDtuDevice(db *gorm.DB, device models.IotDevice) error {
 		SN:     device.Sn,
 		Name:   device.Name,
 		Config: cfg,
-		Logger: logger.NewHelper(setupDeviceLogger(device.Sn)),
+		Logger: logger.NewHelper(iotLog.SetupDeviceLogger(device.Sn)),
 	}
 	logger.Infof("加载DTU设备: %s %v", dtu.SN, dtu.Config)
 	dtu.Logger.Infof("加载DTU设备 %v", *dtu.Config)
@@ -142,31 +140,3 @@ func DtuDeviceChange(message storage.Message) (err error) {
 	}
 	return
 }
-
-// setupDeviceLogger 设置设备日志组件
-func setupDeviceLogger(sn string) logger.Logger {
-	path := config.LoggerConfig.Path
-	logCap := config.LoggerConfig.Cap
-	if path == "" {
-		path = "_logs/"
-	} else if path[len(path)-1] != '/' {
-		path += "/"
-	}
-	path += "device/" + sn
-	if logCap == 0 {
-		logCap = 1024
-	}
-
-	output, err := writer.NewFileWriter(
-		writer.WithPath(path),
-		writer.WithCap(logCap<<10),
-	)
-	if err != nil {
-		log.Printf("device logger setup error: %s \r\n", err.Error())
-	}
-	level := logger.DebugLevel
-	if config.ApplicationConfig.Mode == "prod" {
-		level = logger.InfoLevel
-	}
-	return logger.NewLogger(logger.WithLevel(level), logger.WithOutput(output), logger.WithName(sn))
-}

+ 65 - 0
SERVER/IotAdmin/iot/log/clean.go

@@ -0,0 +1,65 @@
+package iotLog
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"time"
+)
+
+// Clean 清理日志文件
+func Clean(dataDays, deviceDays int) (err error) {
+	err = cleanDataLog(dataDays)
+	if err != nil {
+		return err
+	}
+	err = cleanDeviceLog(deviceDays)
+	if err != nil {
+		return err
+	}
+	return
+}
+
+func cleanDataLog(days int) error {
+	path := getDataLogPath()
+	//删除30天前的日志文件
+	return deleteLogsOlderThan(path, "data", days)
+}
+func cleanDeviceLog(days int) error {
+	path := getDeviceLogPath()
+	//删除30天前的日志文件
+	return deleteLogsOlderThan(path, "log", days)
+}
+
+// deleteLogsOlderThan 删除比指定日期早的日志文件。
+// days 参数表示需要删除的日志文件是几天前的。
+func deleteLogsOlderThan(path, suffix string, days int) error {
+	threshold := time.Now().AddDate(0, 0, -days)
+
+	files, err := filepath.Glob(filepath.Join(path, "*."+suffix)) // 假设日志文件以.log结尾
+	if err != nil {
+		return fmt.Errorf("failed to list files in %s: %w", path, err)
+	}
+
+	for _, file := range files {
+		fileInfo, err := os.Stat(file)
+		if err != nil {
+			if os.IsNotExist(err) {
+				fmt.Printf("File %s does not exist\n", file)
+			} else {
+				return fmt.Errorf("failed to get info for %s: %w", file, err)
+			}
+		}
+
+		// 检查文件修改时间是否早于阈值
+		if fileInfo.ModTime().Before(threshold) {
+			err = os.Remove(file)
+			if err != nil {
+				return fmt.Errorf("failed to delete %s: %w", file, err)
+			}
+			fmt.Printf("Deleted log file: %s\n", file)
+		}
+	}
+
+	return nil
+}

+ 75 - 0
SERVER/IotAdmin/iot/log/data.go

@@ -0,0 +1,75 @@
+package iotLog
+
+import (
+	"IotAdmin/core/sdk/config"
+	"IotAdmin/core/tools/writer"
+	iotStruct "IotAdmin/iot/struct"
+	"encoding/json"
+	"log"
+	"strings"
+	"time"
+)
+
+func init() {
+	mp = make(map[string]*writer.FileWriter)
+}
+
+// LogData 记录数据日志
+func LogData(data *iotStruct.CollectData, cfg *iotStruct.ReportConfig, dataStr *string) {
+	output := getWrite(data)
+	logData := &iotStruct.LogData{
+		Time:           time.Now().Format("20060102150400"),
+		No:             data.SlaveConfig.No,
+		Data:           *data,
+		ReportHost:     cfg.Host,
+		ReportProtocol: cfg.Protocol,
+		ReportMn:       cfg.MN,
+		ReportUser:     cfg.User,
+		ReportPwd:      cfg.Pwd,
+		ReportStr:      *dataStr,
+	}
+	str, err := json.Marshal(logData)
+	if err != nil {
+		log.Printf("Report Log Marshal error: %s \r\n", err.Error())
+		return
+	}
+	_, err = output.Write(str)
+	if err != nil {
+		log.Printf("Report Log Write error: %s \r\n", err.Error())
+		return
+	}
+	_, err = output.Write([]byte("\r\n"))
+}
+
+var mp map[string]*writer.FileWriter
+
+func getWrite(data *iotStruct.CollectData) *writer.FileWriter {
+	path := getDataLogPath()
+	path += strings.ReplaceAll(data.SlaveConfig.No, "_", "/")
+	var output *writer.FileWriter
+	var ok bool
+	if output, ok = mp[path]; !ok {
+		var err error
+		output, err = writer.NewFileWriter(
+			writer.WithPath(path),
+			// 不切割文件
+			writer.WithCap(0),
+			writer.WithSuffix(".data"),
+		)
+		if err != nil {
+			log.Printf("Report Log setup error: %s \r\n", err.Error())
+		}
+		mp[path] = output
+	}
+	return output
+}
+
+func getDataLogPath() string {
+	path := config.ApplicationConfig.DataLogFile
+	if path == "" {
+		path = "./_data/iot/"
+	} else if path[len(path)-1] != '/' {
+		path += "/"
+	}
+	return path
+}

+ 42 - 0
SERVER/IotAdmin/iot/log/device.go

@@ -0,0 +1,42 @@
+package iotLog
+
+import (
+	"IotAdmin/core/logger"
+	"IotAdmin/core/sdk/config"
+	"IotAdmin/core/tools/writer"
+	"log"
+)
+
+// SetupDeviceLogger 设置设备日志组件
+func SetupDeviceLogger(sn string) logger.Logger {
+	path := getDeviceLogPath()
+	path += "/" + sn
+	logCap := config.LoggerConfig.Cap
+	if logCap == 0 {
+		logCap = 1024
+	}
+	output, err := writer.NewFileWriter(
+		writer.WithPath(path),
+		writer.WithCap(logCap<<10),
+		writer.WithSuffix(".log"),
+	)
+	if err != nil {
+		log.Printf("device logger setup error: %s \r\n", err.Error())
+	}
+	level := logger.DebugLevel
+	if config.ApplicationConfig.Mode == "prod" {
+		level = logger.InfoLevel
+	}
+	return logger.NewLogger(logger.WithLevel(level), logger.WithOutput(output), logger.WithName(sn))
+}
+
+func getDeviceLogPath() string {
+	path := config.LoggerConfig.Path
+	if path == "" {
+		path = "_logs/"
+	} else if path[len(path)-1] != '/' {
+		path += "/"
+	}
+	path += "device"
+	return path
+}

+ 2 - 64
SERVER/IotAdmin/iot/service/downService/report.go

@@ -1,20 +1,12 @@
 package iotDownService
 
 import (
-	"IotAdmin/core/sdk/config"
-	"IotAdmin/core/tools/writer"
+	iotLog "IotAdmin/iot/log"
 	iotProtocol "IotAdmin/iot/protocol"
 	iotElProtocol "IotAdmin/iot/protocol/electric"
 	iotStruct "IotAdmin/iot/struct"
-	"encoding/json"
-	"log"
-	"strings"
-	"time"
 )
 
-func init() {
-	mp = make(map[string]*writer.FileWriter)
-}
 func reportData(dataArray *[]*iotStruct.CollectData) {
 	if dataArray == nil || len(*dataArray) == 0 {
 		return
@@ -34,62 +26,8 @@ func reportData(dataArray *[]*iotStruct.CollectData) {
 			go func(d *iotStruct.CollectData, cfg *iotStruct.ReportConfig) {
 				reportHandler.Adapter(d)
 				str := reportHandler.Report(d, cfg)
-				go logReport(d, cfg, str)
+				go iotLog.LogData(d, cfg, str)
 			}(data, &rc)
 		}
 	}
 }
-
-var mp map[string]*writer.FileWriter
-
-func logReport(data *iotStruct.CollectData, cfg *iotStruct.ReportConfig, dataStr *string) {
-	output := getWrite(data)
-	logData := &iotStruct.LogData{
-		Time:           time.Now().Format("20060102150400"),
-		No:             data.SlaveConfig.No,
-		Data:           *data,
-		ReportHost:     cfg.Host,
-		ReportProtocol: cfg.Protocol,
-		ReportMn:       cfg.MN,
-		ReportUser:     cfg.User,
-		ReportPwd:      cfg.Pwd,
-		ReportStr:      *dataStr,
-	}
-	str, err := json.Marshal(logData)
-	if err != nil {
-		log.Printf("Report Log Marshal error: %s \r\n", err.Error())
-		return
-	}
-	_, err = output.Write(str)
-	if err != nil {
-		log.Printf("Report Log Write error: %s \r\n", err.Error())
-		return
-	}
-	_, err = output.Write([]byte("\r\n"))
-}
-
-func getWrite(data *iotStruct.CollectData) *writer.FileWriter {
-	filePath := config.ApplicationConfig.DataLogFile
-	if filePath == "" {
-		filePath = "./_data/iot/"
-	} else if filePath[len(filePath)-1] != '/' {
-		filePath += "/"
-	}
-	filePath += strings.ReplaceAll(data.SlaveConfig.No, "_", "/")
-	var output *writer.FileWriter
-	var ok bool
-	if output, ok = mp[filePath]; !ok {
-		var err error
-		output, err = writer.NewFileWriter(
-			writer.WithPath(filePath),
-			// 不切割文件
-			writer.WithCap(0),
-			writer.WithSuffix(".data"),
-		)
-		if err != nil {
-			log.Printf("Report Log setup error: %s \r\n", err.Error())
-		}
-		mp[filePath] = output
-	}
-	return output
-}

+ 1 - 1
SERVER/IotAdmin/iot/service/downService/service.go

@@ -127,7 +127,7 @@ func dtuClientOnline(msg *iotStruct.DtuRegisterChanMsg) {
 		iotMap.MapDtuClient.Add(msg.SN, msg.Value)
 		// 设备上线
 		UpdateDtuStatus(msg.SN, constant.IotDeviceOnline)
-		dtu.Logger.Infof("设备上线:%s ;配置:  %v 上报配置:%v", msg.Value.FD.GetClientHost(), dtu.Config, dtu.Config.SlaveConfig)
+		dtu.Logger.Infof("设备上线:%s ;配置:  %v 从机配置:%v", msg.Value.FD.GetClientHost(), dtu.Config, dtu.Config.SlaveConfig)
 	} else {
 		logger.Errorf("【设备上线失败】[%s]设备不存在。", msg.SN)
 	}

+ 4 - 0
SERVER/IotAdmin/iot/struct/dtu_config.go

@@ -36,6 +36,10 @@ type ReportConfig struct {
 	BmYz     *BmYz  `json:"bmYz"` //编码因子
 }
 
+func (rc *ReportConfig) String() string {
+	return rc.Host + "|" + rc.Protocol + "|" + rc.MN + "|" + rc.User + "|" + rc.Pwd
+}
+
 type BmYz struct {
 	P          string
 	Pa         string