data.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package iotLog
  2. import (
  3. "IotAdmin/core/sdk/config"
  4. "IotAdmin/core/tools/writer"
  5. iotStruct "IotAdmin/iot/struct"
  6. "encoding/json"
  7. "fmt"
  8. "log"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "time"
  13. )
  14. func init() {
  15. mp = make(map[string]*writer.FileWriter)
  16. }
  17. // LogData 记录数据日志
  18. func LogData(data *iotStruct.CollectData, cfg *iotStruct.ReportConfig, dataStr *string) {
  19. output := getWrite(data)
  20. logData := &iotStruct.LogData{
  21. Time: time.Now().Format("20060102150400"),
  22. No: data.SlaveConfig.No,
  23. Data: *data,
  24. ReportHost: cfg.Host,
  25. ReportProtocol: cfg.Protocol,
  26. ReportMn: cfg.MN,
  27. ReportUser: cfg.User,
  28. ReportPwd: cfg.Pwd,
  29. ReportStr: *dataStr,
  30. }
  31. str, err := json.Marshal(logData)
  32. if err != nil {
  33. log.Printf("Report Log Marshal error: %s \r\n", err.Error())
  34. return
  35. }
  36. _, err = output.Write(str)
  37. if err != nil {
  38. log.Printf("Report Log Write error: %s \r\n", err.Error())
  39. return
  40. }
  41. _, err = output.Write([]byte("\r\n"))
  42. }
  43. var mp map[string]*writer.FileWriter
  44. func getWrite(data *iotStruct.CollectData) *writer.FileWriter {
  45. path := getDataLogPath()
  46. path += strings.ReplaceAll(data.SlaveConfig.No, "_", "/")
  47. var output *writer.FileWriter
  48. var ok bool
  49. if output, ok = mp[path]; !ok {
  50. var err error
  51. output, err = writer.NewFileWriter(
  52. writer.WithPath(path),
  53. // 不切割文件
  54. writer.WithCap(0),
  55. writer.WithSuffix("data"),
  56. writer.WithTimeFormat("2006010215"),
  57. )
  58. if err != nil {
  59. log.Printf("Report Log setup error: %s \r\n", err.Error())
  60. }
  61. mp[path] = output
  62. }
  63. return output
  64. }
  65. func getDataLogPath() string {
  66. path := config.ApplicationConfig.DataLogFile
  67. if path == "" {
  68. path = "./_data/iot/"
  69. } else if path[len(path)-1] != '/' {
  70. path += "/"
  71. }
  72. return path
  73. }
  74. func GetLastData(sn string) (*iotStruct.LogData, error) {
  75. path := getDataLogPath()
  76. path += strings.ReplaceAll(sn, "_", "/")
  77. dirPath := path
  78. latestFilePath, err := getLatestFilePath(dirPath)
  79. if err != nil {
  80. return nil, err
  81. }
  82. bytes, err := os.ReadFile(latestFilePath)
  83. if err != nil {
  84. return nil, err
  85. }
  86. str := string(bytes)
  87. arr := strings.Split(str, "\r\n")
  88. if len(arr) <= 1 {
  89. return nil, fmt.Errorf("数据为空")
  90. }
  91. dataStr := arr[len(arr)-1]
  92. data := &iotStruct.LogData{}
  93. if err = json.Unmarshal([]byte(dataStr), data); err != nil {
  94. return nil, err
  95. }
  96. return data, nil
  97. }
  98. // getLatestFilePath 返回给定目录中最新被修改的文件的路径。
  99. // 如果目录不存在或者不是一个目录,或者发生任何错误,函数将返回相应的错误信息。
  100. func getLatestFilePath(dirPath string) (string, error) {
  101. // 判断目录是否存在
  102. info, err := os.Stat(dirPath)
  103. if err != nil {
  104. if os.IsNotExist(err) {
  105. return "", fmt.Errorf("目录 %s 不存在", dirPath)
  106. }
  107. return "", fmt.Errorf("获取目录信息失败: %w", err)
  108. }
  109. if !info.IsDir() {
  110. return "", fmt.Errorf("%s 不是目录", dirPath)
  111. }
  112. // 查找目录下最新修改的文件
  113. var latestModTime time.Time
  114. var latestFilePath string
  115. files, err := os.ReadDir(dirPath) // 更新为使用os.ReadDir代替ioutil.ReadDir
  116. if err != nil {
  117. return "", fmt.Errorf("读取目录失败: %w", err)
  118. }
  119. for _, f := range files {
  120. file, err := f.Info()
  121. if err != nil {
  122. return "", fmt.Errorf("获取文件信息失败: %w", err)
  123. }
  124. if !file.Mode().IsRegular() {
  125. continue // 跳过非普通文件(如目录、符号链接等)
  126. }
  127. fileModTime := file.ModTime()
  128. if fileModTime.After(latestModTime) {
  129. latestModTime = fileModTime
  130. latestFilePath = filepath.Join(dirPath, file.Name())
  131. }
  132. }
  133. // 确保找到的文件是有效的普通文件
  134. fileInfo, err := os.Stat(latestFilePath)
  135. if err != nil {
  136. return "", fmt.Errorf("获取文件信息失败: %s: %w", latestFilePath, err)
  137. }
  138. if !fileInfo.Mode().IsRegular() {
  139. return "", fmt.Errorf("%s 不是普通文件", latestFilePath)
  140. }
  141. return latestFilePath, nil
  142. }