| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- package iotLog
- import (
- "IotAdmin/core/sdk/config"
- "IotAdmin/core/tools/writer"
- iotStruct "IotAdmin/iot/struct"
- "encoding/json"
- "fmt"
- "log"
- "os"
- "path/filepath"
- "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"),
- writer.WithTimeFormat("2006010215"),
- )
- 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
- }
- func GetLastData(sn string) (*iotStruct.LogData, error) {
- path := getDataLogPath()
- path += strings.ReplaceAll(sn, "_", "/")
- dirPath := path
- latestFilePath, err := getLatestFilePath(dirPath)
- if err != nil {
- return nil, err
- }
- bytes, err := os.ReadFile(latestFilePath)
- if err != nil {
- return nil, err
- }
- str := string(bytes)
- arr := strings.Split(str, "\r\n")
- if len(arr) <= 1 {
- return nil, fmt.Errorf("数据为空")
- }
- dataStr := arr[len(arr)-1]
- data := &iotStruct.LogData{}
- if err = json.Unmarshal([]byte(dataStr), data); err != nil {
- return nil, err
- }
- return data, nil
- }
- // getLatestFilePath 返回给定目录中最新被修改的文件的路径。
- // 如果目录不存在或者不是一个目录,或者发生任何错误,函数将返回相应的错误信息。
- func getLatestFilePath(dirPath string) (string, error) {
- // 判断目录是否存在
- info, err := os.Stat(dirPath)
- if err != nil {
- if os.IsNotExist(err) {
- return "", fmt.Errorf("目录 %s 不存在", dirPath)
- }
- return "", fmt.Errorf("获取目录信息失败: %w", err)
- }
- if !info.IsDir() {
- return "", fmt.Errorf("%s 不是目录", dirPath)
- }
- // 查找目录下最新修改的文件
- var latestModTime time.Time
- var latestFilePath string
- files, err := os.ReadDir(dirPath) // 更新为使用os.ReadDir代替ioutil.ReadDir
- if err != nil {
- return "", fmt.Errorf("读取目录失败: %w", err)
- }
- for _, f := range files {
- file, err := f.Info()
- if err != nil {
- return "", fmt.Errorf("获取文件信息失败: %w", err)
- }
- if !file.Mode().IsRegular() {
- continue // 跳过非普通文件(如目录、符号链接等)
- }
- fileModTime := file.ModTime()
- if fileModTime.After(latestModTime) {
- latestModTime = fileModTime
- latestFilePath = filepath.Join(dirPath, file.Name())
- }
- }
- // 确保找到的文件是有效的普通文件
- fileInfo, err := os.Stat(latestFilePath)
- if err != nil {
- return "", fmt.Errorf("获取文件信息失败: %s: %w", latestFilePath, err)
- }
- if !fileInfo.Mode().IsRegular() {
- return "", fmt.Errorf("%s 不是普通文件", latestFilePath)
- }
- return latestFilePath, nil
- }
|