From 493a09c71521718e56ed283be10eeae043e9a96a Mon Sep 17 00:00:00 2001 From: shukan <755397041@qq.com> Date: Mon, 11 Aug 2025 10:41:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 + .idea/iot-mqtt-gin.iml | 9 + .idea/modules.xml | 8 + common/httpclient.go | 115 +++++++++ config/api.go | 6 + config/db.go | 5 + config/emqx.go | 9 + config/mqsdk.go | 62 +++++ config/tdengine.go | 32 +++ controllers/common.go | 82 +++++++ controllers/device.go | 320 ++++++++++++++++++++++++ controllers/message.go | 3 + controllers/mqttuser.go | 64 +++++ dao/dao.go | 42 ++++ dao/tdengine.go | 64 +++++ docs/docs.go | 174 +++++++++++++ docs/swagger.json | 154 ++++++++++++ docs/swagger.yaml | 105 ++++++++ dto/mqttuser_dto.go | 12 + dto/sys_dto.go | 10 + go.mod | 79 ++++++ go.sum | 224 +++++++++++++++++ main.go | 75 ++++++ models/baseDevice.go | 20 ++ models/device.go | 51 ++++ models/deviceMqttLog.go | 58 +++++ models/mqsdk.go | 69 ++++++ models/mqttuser.go | 34 +++ models/switch.go | 21 ++ mqtt/client.go | 109 +++++++++ msgtype/message.go | 100 ++++++++ pkg/logger/logger.go | 149 ++++++++++++ router/routers.go | 39 +++ runtime/log/error_2025-08-01.log | 40 +++ runtime/log/error_2025-08-02.log | 219 +++++++++++++++++ runtime/log/error_2025-08-04.log | 5 + runtime/log/error_2025-08-07.log | 378 +++++++++++++++++++++++++++++ runtime/log/error_2025-08-08.log | 2 + runtime/log/success_2025-07-30.log | 58 +++++ runtime/log/success_2025-07-31.log | 58 +++++ runtime/log/success_2025-08-01.log | 70 ++++++ runtime/log/success_2025-08-02.log | 61 +++++ runtime/log/success_2025-08-04.log | 21 ++ runtime/log/success_2025-08-07.log | 20 ++ runtime/log/success_2025-08-08.log | 22 ++ service/deviceService.go | 45 ++++ service/mq_service.go | 153 ++++++++++++ 47 files changed, 3464 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/iot-mqtt-gin.iml create mode 100644 .idea/modules.xml create mode 100644 common/httpclient.go create mode 100644 config/api.go create mode 100644 config/db.go create mode 100644 config/emqx.go create mode 100644 config/mqsdk.go create mode 100644 config/tdengine.go create mode 100644 controllers/common.go create mode 100644 controllers/device.go create mode 100644 controllers/message.go create mode 100644 controllers/mqttuser.go create mode 100644 dao/dao.go create mode 100644 dao/tdengine.go create mode 100644 docs/docs.go create mode 100644 docs/swagger.json create mode 100644 docs/swagger.yaml create mode 100644 dto/mqttuser_dto.go create mode 100644 dto/sys_dto.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 models/baseDevice.go create mode 100644 models/device.go create mode 100644 models/deviceMqttLog.go create mode 100644 models/mqsdk.go create mode 100644 models/mqttuser.go create mode 100644 models/switch.go create mode 100644 mqtt/client.go create mode 100644 msgtype/message.go create mode 100644 pkg/logger/logger.go create mode 100644 router/routers.go create mode 100644 runtime/log/error_2025-08-01.log create mode 100644 runtime/log/error_2025-08-02.log create mode 100644 runtime/log/error_2025-08-04.log create mode 100644 runtime/log/error_2025-08-07.log create mode 100644 runtime/log/error_2025-08-08.log create mode 100644 runtime/log/success_2025-07-30.log create mode 100644 runtime/log/success_2025-07-31.log create mode 100644 runtime/log/success_2025-08-01.log create mode 100644 runtime/log/success_2025-08-02.log create mode 100644 runtime/log/success_2025-08-04.log create mode 100644 runtime/log/success_2025-08-07.log create mode 100644 runtime/log/success_2025-08-08.log create mode 100644 service/deviceService.go create mode 100644 service/mq_service.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/iot-mqtt-gin.iml b/.idea/iot-mqtt-gin.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/iot-mqtt-gin.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6befa84 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/common/httpclient.go b/common/httpclient.go new file mode 100644 index 0000000..2f7ef13 --- /dev/null +++ b/common/httpclient.go @@ -0,0 +1,115 @@ +package common + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "iot-mqtt-gin/config" + "net/http" + "time" +) + +// HTTPClient 封装HTTP客户端 +type HTTPClient struct { + client *http.Client + headers map[string]string +} + +// NewHTTPClient 创建新的HTTP客户端实例 +// timeout: 超时时间(秒) +func NewHTTPClient(timeout int) *HTTPClient { + return &HTTPClient{ + client: &http.Client{ + Timeout: time.Duration(timeout) * time.Second, + }, + headers: make(map[string]string), + } +} + +// SetHeader 设置请求头 +func (c *HTTPClient) SetHeader(key, value string) { + c.headers[key] = value +} + +// Get 发送GET请求 +func (c *HTTPClient) Get(url string, params map[string]string) (response []byte, statusCode int, err error) { + // 创建请求 + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, 0, fmt.Errorf("创建GET请求失败: %v", err) + } + + // 设置请求头 + for k, v := range c.headers { + req.Header.Set(k, v) + } + + // 添加查询参数 + q := req.URL.Query() + for k, v := range params { + q.Add(k, v) + } + req.URL.RawQuery = q.Encode() + + // 发送请求 + resp, err := c.client.Do(req) + if err != nil { + return nil, 0, fmt.Errorf("发送GET请求失败: %v", err) + } + defer resp.Body.Close() + + // 读取响应内容 + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, resp.StatusCode, fmt.Errorf("读取GET响应失败: %v", err) + } + + return body, resp.StatusCode, nil +} + +// Post 发送POST请求 +func (c *HTTPClient) Post(url string, data interface{}) (response []byte, statusCode int, err error) { + // 序列化请求数据 + var jsonData []byte + switch v := data.(type) { + case string: + jsonData = []byte(v) + default: + var err error + jsonData, err = json.Marshal(data) + if err != nil { + return nil, 0, fmt.Errorf("POST数据序列化失败: %v", err) + } + } + + // 创建请求 + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) + if err != nil { + return nil, 0, fmt.Errorf("创建POST请求失败: %v", err) + } + + // 设置默认Header + if _, ok := c.headers["Content-Type"]; !ok { + c.SetHeader("Content-Type", "application/json") + c.SetHeader("Authorization", config.APIToken) + } + for k, v := range c.headers { + req.Header.Set(k, v) + } + + // 发送请求 + resp, err := c.client.Do(req) + if err != nil { + return nil, 0, fmt.Errorf("发送POST请求失败: %v", err) + } + defer resp.Body.Close() + + // 读取响应内容 + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, resp.StatusCode, fmt.Errorf("读取POST响应失败: %v", err) + } + + return body, resp.StatusCode, nil +} diff --git a/config/api.go b/config/api.go new file mode 100644 index 0000000..68005a8 --- /dev/null +++ b/config/api.go @@ -0,0 +1,6 @@ +package config + +const ( + APIToken = "Bearer kCVAha_qe4wM6i6C_cwrlmxbtHR40yCJ" + APIBaseUrl = "https://www.cdsrh.top:443/" +) diff --git a/config/db.go b/config/db.go new file mode 100644 index 0000000..2654eef --- /dev/null +++ b/config/db.go @@ -0,0 +1,5 @@ +package config + +const ( + Mysqldb = "device_management:12345678@tcp(124.220.236.38:3306)/device_management?charset=utf8" +) diff --git a/config/emqx.go b/config/emqx.go new file mode 100644 index 0000000..3b2a422 --- /dev/null +++ b/config/emqx.go @@ -0,0 +1,9 @@ +package config + +const ( + MQTTBroker = "tcp://124.220.236.38:1883" + MQTTClientID = "iot-server" + MQTTUsername = "emqx_u" + MQTTPassword = "public" + MQTTQoS = 1 +) diff --git a/config/mqsdk.go b/config/mqsdk.go new file mode 100644 index 0000000..2373688 --- /dev/null +++ b/config/mqsdk.go @@ -0,0 +1,62 @@ +package config + +import ( + mqsd "github.com/yyboo586/MQSDK" +) + +// MQ类型常量 +const ( + MQTypeNSQ = "nsq" + MQTypeKafka = "kafka" + MQTypeRabbitMQ = "rabbitmq" +) + +// 连接配置常量 +const ( + // NSQ配置 + NSQDAddress = "124.220.236.38:4150" + NSQLookupdAddres = "124.220.236.38:4161" + + // Kafka配置 + KafkaBrokerList = "124.220.236.38:9092" + KafkaConsumerGroup = "gin-demo-group" + KafkaVersion = "2.0.0" + + // RabbitMQ配置 + RabbitMQURL = "amqp://guest:guest@localhost:5672/" + RabbitMQExchange = "gin-demo-exchange" + RabbitMQRoutingKey = "demo.key" + + //Topic + DeviceOnlineTopic = "core.device.online" + DeviceOfflineTopic = "core.device.offline" + DeviceAlarmTopic = "core.device.alarm" +) + +// GetNSQConfig 获取NSQ配置 +func GetNSQConfig() *mqsd.NSQConfig { + return &mqsd.NSQConfig{ + Type: MQTypeNSQ, + NSQDAddr: NSQDAddress, + NSQLookup: []string{NSQLookupdAddres}, + } +} + +// GetKafkaConfig 获取Kafka配置 +func GetKafkaConfig() *mqsd.KafkaConfig { + return &mqsd.KafkaConfig{ + Type: MQTypeKafka, + Brokers: []string{KafkaBrokerList}, + GroupID: KafkaConsumerGroup, + Version: KafkaVersion, + } +} + +// GetRabbitMQConfig 获取RabbitMQ配置 +func GetRabbitMQConfig() *mqsd.RabbitMQConfig { + return &mqsd.RabbitMQConfig{ + Type: MQTypeRabbitMQ, + URL: RabbitMQURL, + Exchange: RabbitMQExchange, + } +} diff --git a/config/tdengine.go b/config/tdengine.go new file mode 100644 index 0000000..08eaaf2 --- /dev/null +++ b/config/tdengine.go @@ -0,0 +1,32 @@ +package config + +// TDengine数据库配置 +const ( + TDengineHost = "123.56.105.137" // TDengine服务器地址 + TDenginePort = 6030 // TDengine端口 + TDengineUser = "root" // 用户名 + TDenginePassword = "taosdata" // 密码 + TDengineDatabase = "iotdb" // 数据库名 + TDengineTimeout = 30 // 连接超时时间(秒) + TDengineCharset = "UTF8" // 字符集 +) + +// 数据表配置 +const ( + StableName = "device_data_stable" // 超级表名(设备数据超级表) + SubTablePrefix = "device_" // 子表前缀(每个设备一个子表) +) + +// 业务常量 +const ( + MaxQueryRecords = 1000 // 最大查询记录数 +) + +// 设备数据字段常量 +const ( + FieldOrgID = "org_id" + FieldDeviceID = "device_id" + FieldValue = "val" + FieldStatus = "status" + FieldTimestamp = "ts" +) diff --git a/controllers/common.go b/controllers/common.go new file mode 100644 index 0000000..94f2496 --- /dev/null +++ b/controllers/common.go @@ -0,0 +1,82 @@ +package controllers + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "fmt" + "github.com/gin-gonic/gin" + "net/http" +) + +type JsonStruct struct { + Code int `json:"code"` + Msg interface{} `json:"msg"` + Data interface{} `json:"data"` + Count int64 `json:"count"` +} + +func ReturnSuccess(c *gin.Context, code int, msg interface{}, data interface{}, count int64) { + json := &JsonStruct{ + Code: code, + Msg: msg, + Data: data, + Count: count, + } + c.JSON(http.StatusOK, json) +} + +func ReturnError(c *gin.Context, code int, msg interface{}) { + json := &JsonErrStruct{ + Code: code, + Msg: msg, + } + c.JSON(http.StatusBadRequest, json) +} + +type JsonErrStruct struct { + Code int `json:"code"` + Msg interface{} `json:"msg"` +} + +// 生成指定长度的随机盐值 +// length: 盐值的长度 +// 返回值: 生成的盐值字符串和可能的错误 +func GenerateRandomSalt(length int) (string, error) { + // 计算需要多少字节才能生成指定长度的base64字符串 + // base64编码中,每3字节会被编码为4个字符 + bytesNeeded := (length * 3) / 4 + if (length*3)%4 != 0 { + bytesNeeded++ + } + + // 生成随机字节 + randomBytes := make([]byte, bytesNeeded) + _, err := rand.Read(randomBytes) + if err != nil { + return "", err + } + + // 编码为base64字符串,去掉可能的填充字符'=' + salt := base64.URLEncoding.EncodeToString(randomBytes) + if len(salt) > length { + salt = salt[:length] + } + + return salt, nil +} + +// 生成带后缀盐的密码 +// password: 原始密码 +// salt: 盐值 +// 返回值: 密码+盐值的组合字符串sha256加密 +func Sha256Encrypt(password, salt string) string { + // 拼接密码和盐值(采用suffix模式:密码+盐值) + combined := []byte(password + salt) + + // 计算SHA256哈希 + hash := sha256.Sum256(combined) + + // 转换为十六进制字符串(32字节哈希 -> 64字符) + return fmt.Sprintf("%x", hash) +} diff --git a/controllers/device.go b/controllers/device.go new file mode 100644 index 0000000..34fc6cb --- /dev/null +++ b/controllers/device.go @@ -0,0 +1,320 @@ +package controllers + +import ( + "context" + "encoding/json" + "github.com/gin-gonic/gin" + mqsd "github.com/yyboo586/MQSDK" + "iot-mqtt-gin/common" + "iot-mqtt-gin/config" + "iot-mqtt-gin/dto" + "iot-mqtt-gin/models" + "iot-mqtt-gin/mqtt" + "iot-mqtt-gin/pkg/logger" + _ "iot-mqtt-gin/pkg/logger" + "iot-mqtt-gin/service" + "log" + "net/http" + "strings" + "sync" + "time" +) + +// DeviceController 设备控制器 +type DeviceController struct { + devices map[string]models.Device + mqttClient *mqtt.Client // 注意:这里是指针类型,需要确保不为nil + mu sync.RWMutex + client *common.HTTPClient + nsqProducer mqsd.Producer + kafkaProducer mqsd.Producer + rabbitProducer mqsd.Producer +} + +// NewDeviceController 创建设备控制器 +func NewDeviceController( + mqttClient *mqtt.Client, + nsqProducer mqsd.Producer, +) *DeviceController { + httpClient := common.NewHTTPClient(10) // 10秒超时 + controller := &DeviceController{ + devices: make(map[string]models.Device), + mqttClient: mqttClient, + client: httpClient, + nsqProducer: nsqProducer, + } + + return controller +} + +var ( + LogChan = make(chan models.DeviceMqttLog, 1000) // 日志通道,带缓冲 +) + +// 初始化批量写入协程 +func init() { + go StartLogWorker() +} + +func StartLogWorker() { + ticker := time.NewTicker(100 * time.Millisecond) // 缩短定时周期支持1条也写入 + defer ticker.Stop() + batchLogs := make([]models.DeviceMqttLog, 0, 10) + deviceLogModel := models.DeviceMqttLog{} + for { + select { + case log, ok := <-LogChan: + batchLogs = append(batchLogs, log) + if !ok { + // 数据通道已关闭,处理剩余数据 + if len(batchLogs) > 0 { + if err := deviceLogModel.BatchAddLogs(batchLogs); err != nil { + logger.Error(map[string]interface{}{"批量写入日志失败": err.Error()}) + } + } + return + } + // 当积累到1条时立即写入 + if len(batchLogs) >= 1 { + if err := deviceLogModel.BatchAddLogs(batchLogs); err != nil { + logger.Error(map[string]interface{}{"批量写入日志失败": err.Error()}) + } + // 如果只有一条就单条写入,如果多条就批量写入 + if len(batchLogs) == 1 { + if err := deviceLogModel.AddLog(); err != nil { + logger.Error(map[string]interface{}{"写入日志失败": err.Error()}) + } + } else { + if err := deviceLogModel.BatchAddLogs(batchLogs); err != nil { + logger.Error(map[string]interface{}{"批量写入日志失败": err.Error()}) + } + } + batchLogs = batchLogs[:0] // 清空切片 + } + case <-ticker.C: + // 定时写入剩余的日志 + if len(batchLogs) > 0 { + if len(batchLogs) == 1 { + if err := deviceLogModel.AddLog(); err != nil { + logger.Error(map[string]interface{}{"定时写入日志失败": err.Error()}) + } + } else { + if err := deviceLogModel.BatchAddLogs(batchLogs); err != nil { + logger.Error(map[string]interface{}{"定时批量写入日志失败": err.Error()}) + } + } + batchLogs = batchLogs[:0] // 清空切片 + } + } + } +} + +// HandleMQTTMessage 处理MQTT消息 +func (d *DeviceController) HandleMQTTMessage(topic string, payload []byte) { + log.Printf("收到MQTT消息 - 主题: %s, 内容: %s", topic, payload) + parts := strings.Split(topic, "/") + if len(parts) < 3 { + log.Printf("无效的主题格式: %s", topic) + return + } + deviceID := parts[1] + action := parts[2] + deviceModel := models.Device{} + // 检查设备是否存在 + d.mu.RLock() + deviceInfo, err := deviceModel.CheckDevice(deviceID) + d.mu.RUnlock() + if err != nil || deviceInfo.ID <= 0 { + return + } + switch action { + case "connected": + + //d.handleConnectedMessage(deviceInfo.ID, deviceInfo.DeviceKey, deviceInfo.OrgId, topic, payload) + // 创建消息 + // 构建日志数据 + deviceLogData := models.DeviceMqSdkLog{ + DeviceId: deviceInfo.ID, + DeviceKey: deviceInfo.DeviceKey, + DeviceName: deviceInfo.Name, + OrgId: deviceInfo.OrgId, + } + //body, _ := json.Marshal(deviceLogData) + msg := models.NewMessage(config.DeviceOnlineTopic, deviceLogData, "nsq-devonline") + // 发布消息 + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := d.nsqProducer.Publish(ctx, config.DeviceOnlineTopic, msg.ToMQSDMessage()); err != nil { + logger.Error(map[string]interface{}{"发布NSQ消息失败: ": err.Error()}) + return + } + case "disconnected": + //d.handleDisconnected(deviceInfo.ID, deviceInfo.DeviceKey, deviceInfo.OrgId, topic, payload) + // 构建日志数据 + deviceLogData := models.DeviceMqSdkLog{ + DeviceId: deviceInfo.ID, + DeviceKey: deviceInfo.DeviceKey, + DeviceName: deviceInfo.Name, + OrgId: deviceInfo.OrgId, + } + //body, _ := json.Marshal(deviceLogData) + msg := models.NewMessage(config.DeviceOfflineTopic, deviceLogData, "nsq-devonline") + // 发布消息 + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := d.nsqProducer.Publish(ctx, config.DeviceOfflineTopic, msg.ToMQSDMessage()); err != nil { + logger.Error(map[string]interface{}{"发布NSQ消息失败: ": err.Error()}) + return + } + default: + // 当所有case都不匹配时执行,不做处理 + return + } +} + +// 处理上线消息 +func (d *DeviceController) handleConnectedMessage(deviceID uint, deviceKey, orgId, topic string, payload []byte) { + // 转换payload为字符串并去除可能的空白字符 + payloadStr := strings.TrimSpace(string(payload)) + if payloadStr == "devconnected" { + // 构建日志数据 + deviceLogData := models.DeviceMqttLog{ + DeviceId: deviceID, + DeviceKey: deviceKey, + OrgId: orgId, + } + //fmt.Println("收到的消息", payload) + contentMap := make(map[string]interface{}) + currentTime := time.Now() + contentMap["createtime"] = currentTime.Format("2006-01-02 15:04:05") + contentMap["msg"] = "设备:" + deviceKey + "上线" + jsonBytes, _ := json.Marshal(contentMap) + deviceLogData.Type = 1 + deviceLogData.Content = string(jsonBytes) + /*if err := deviceLogData.AddLog(); err != nil { + logger.Error(map[string]interface{}{"写入日志失败": err.Error()}) + }*/ + select { + case LogChan <- deviceLogData: + default: + // 通道满时降级为直接写入 + if err := deviceLogData.AddLog(); err != nil { + logger.Error(map[string]interface{}{"通道满,直接写入日志失败": err.Error()}) + } + } + } +} + +// 处理下线消息 +func (d *DeviceController) handleDisconnected(deviceID uint, deviceKey, orgId, topic string, payload []byte) { + // 转换payload为字符串并去除可能的空白字符 + payloadStr := strings.TrimSpace(string(payload)) + if payloadStr == "devdisconnected" { + // 构建日志数据 + deviceLogData := models.DeviceMqttLog{ + DeviceId: deviceID, + DeviceKey: deviceKey, + OrgId: orgId, + } + //fmt.Println("收到的消息", payload) + contentMap := make(map[string]interface{}) + currentTime := time.Now() + contentMap["createtime"] = currentTime.Format("2006-01-02 15:04:05") + contentMap["msg"] = "设备:" + deviceKey + "下线" + jsonBytes, _ := json.Marshal(contentMap) + deviceLogData.Type = 2 + deviceLogData.Content = string(jsonBytes) + /*if err := deviceLogData.AddLog(); err != nil { + logger.Error(map[string]interface{}{"写入日志失败": err.Error()}) + }*/ + select { + case LogChan <- deviceLogData: + default: + // 通道满时降级为直接写入 + if err := deviceLogData.AddLog(); err != nil { + logger.Error(map[string]interface{}{"通道满,直接写入日志失败": err.Error()}) + } + } + //调用设备告警接口写入数据 + reqtUrl := config.APIBaseUrl + "api/v1/device-management/devices/logs" + // 构建POST请求参数 + contentLogMap := make(map[string]interface{}) + contentLogMap["details"] = contentMap + contentLogMap["message"] = "设备:" + deviceKey + "下线" + postData := make(map[string]interface{}) + postData["type"] = 3 + postData["created_at"] = currentTime.Format("2006-01-02 15:04:05") + postData["org_id"] = orgId + postData["device_id"] = deviceID + postData["device_key"] = deviceKey + postData["content"] = contentLogMap + go func() { + resp, _, _ := d.client.Post(reqtUrl, postData) + // 定义结构体对应JSON结构 + type Response struct { + Code int `json:"code"` + Message string `json:"message"` + } + var respJson Response + _ = json.Unmarshal([]byte(resp), &respJson) + if respJson.Code != 0 { + logger.Error(map[string]interface{}{"写入报警日志失败": respJson.Message}) + } + }() + } +} + +// DeviceOnline 订阅设备上下线 +// @Summary 订阅设备上下线 +// @Description 订阅设备上下线 +// @Tags 设备管理 +// @Accept json +// @Produce json +// @Param device_number path string true "设备编号" +// @Success 200 {object} map[string]interface{} +// @Failure 400 {object} map[string]interface{} +// @Failure 409 {object} map[string]interface{} +// @Failure 500 {object} map[string]interface{} +// @Router /devices/{device_number}/onoff [get] +func (d *DeviceController) DeviceOnOff(c *gin.Context) { + var req dto.SystemDeviceRequest + if err := c.ShouldBindUri(&req); err != nil { + ReturnError(c, 400, "请求参数错误: "+err.Error()) + } + //查询设备是否存在 + // 检查设备是否已存在 + deviceModel := models.Device{} + deviceInfo, err := deviceModel.CheckDevice(req.DeviceNumber) + if err != nil || deviceInfo.ID <= 0 { + ReturnError(c, 400, "设备不存在") + return + } + //订阅设备泛型 + //topic := "sys/" + req.DeviceNumber + "/connected" + topic := "sys/#" + if err := d.mqttClient.Subscribe(topic); err != nil { + ReturnError(c, 400, "订阅主题: "+topic+"失败"+err.Error()) + } + ReturnSuccess(c, 200, "订阅成功", "", 0) +} + +func (d *DeviceController) TDengineTest(c *gin.Context) { + var data models.DeviceData + currentTime := time.Now() + data.OrgID = "1" + data.DeviceID = "2" + data.Status = true + data.Value = 64 + data.Timestamp = currentTime + + if err := service.InsertDeviceData(&data); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "数据插入成功", + }) +} diff --git a/controllers/message.go b/controllers/message.go new file mode 100644 index 0000000..26e9aef --- /dev/null +++ b/controllers/message.go @@ -0,0 +1,3 @@ +package controllers + +type MessageController struct{} diff --git a/controllers/mqttuser.go b/controllers/mqttuser.go new file mode 100644 index 0000000..36a5260 --- /dev/null +++ b/controllers/mqttuser.go @@ -0,0 +1,64 @@ +package controllers + +import ( + "github.com/gin-gonic/gin" + "iot-mqtt-gin/dto" + "iot-mqtt-gin/models" +) + +type MqttuserController struct { + mqttuser map[string]models.Mqttuser +} + +func NewMqttuserController() *MqttuserController { + return &MqttuserController{ + mqttuser: make(map[string]models.Mqttuser), + } +} + +// User 定义用户模型 +/*type User struct { + ID int `json:"id" example:"1"` + Username string `json:"username" example:"john_doe"` +}*/ + +// AddUser 添加mqtt认证用户 +// @Summary 添加mqtt认证用户 +// @Description 添加mqtt认证用户信息 +// @Tags mqtt认证用户管理 +// @Accept json +// @Produce json +// @Param user body dto.CreateMqttuserRequest true "用户信息" +// @Success 200 {object} dto.CreateMqttuserResponse +// @Failure 400 {object} map[string]interface{} +// @Failure 409 {object} map[string]interface{} +// @Failure 500 {object} map[string]interface{} +// @Router /mqttuser/add [post] +func (u MqttuserController) AddUser(c *gin.Context) { + // 绑定请求参数到DTO + var req dto.CreateMqttuserRequest + if err := c.ShouldBindJSON(&req); err != nil { + ReturnError(c, 400, "请求参数错误: "+err.Error()) + } + randomSalt, _ := GenerateRandomSalt(6) + passwordHash := Sha256Encrypt(req.PasswordHash, randomSalt) + mqttuser := models.Mqttuser{ + Username: req.Username, + PasswordHash: passwordHash, + Salt: randomSalt, + } + // 检查用户是否已存在 + existsFlag, msg := mqttuser.Exists() + if existsFlag { + ReturnError(c, 400, msg) + } + // 创建用户 + if err := mqttuser.AddUser(); err != nil { + ReturnError(c, 400, "创建用户失败: "+err.Error()) + } + // 转换数据模型到响应DTO + response := dto.CreateMqttuserResponse{ + ID: mqttuser.ID, + } + ReturnSuccess(c, 200, "success", response, 0) +} diff --git a/dao/dao.go b/dao/dao.go new file mode 100644 index 0000000..de06a76 --- /dev/null +++ b/dao/dao.go @@ -0,0 +1,42 @@ +package dao + +import ( + "gorm.io/driver/mysql" + "gorm.io/gorm" + "iot-mqtt-gin/config" + "iot-mqtt-gin/pkg/logger" + "time" +) + +var ( + Db *gorm.DB + err error +) + +func init() { + Db, err = gorm.Open(mysql.Open(config.Mysqldb), &gorm.Config{ + //Logger: gormlog.Default.LogMode(gormlog.Info),//打印数据库sql + }) + if err != nil { + //打印数据库连接错误信息 + logger.Error(map[string]interface{}{"mysql connect error": err.Error()}) + } + if Db.Error != nil { + //打印数据库连接错误信息 + logger.Error(map[string]interface{}{"database error": Db.Error}) + } + sqlDB, err := Db.DB() + if err != nil { + panic("获取数据库连接池失败: " + err.Error()) + } + sqlDB.SetMaxIdleConns(10) // 最大空闲连接数 + sqlDB.SetMaxOpenConns(100) // 最大打开连接数 + sqlDB.SetConnMaxLifetime(time.Hour) // 连接最大存活时间 +} +func CloseDB() { + sqlDB, err := Db.DB() + if err != nil { + return + } + _ = sqlDB.Close() +} diff --git a/dao/tdengine.go b/dao/tdengine.go new file mode 100644 index 0000000..1f71e9c --- /dev/null +++ b/dao/tdengine.go @@ -0,0 +1,64 @@ +package dao + +import ( + "database/sql" + "fmt" + "iot-mqtt-gin/config" + "sync" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +var ( + dbTdEngine *sql.DB // 全局TDengine连接实例 + once sync.Once // 确保连接只初始化一次 +) + +// InitTDengine 初始化TDengine连接 +func InitTDengine() error { + var err error + once.Do(func() { + // 构建DSN + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?timeout=%ds&charset=%s", + config.TDengineUser, + config.TDenginePassword, + config.TDengineHost, + config.TDenginePort, + config.TDengineDatabase, + config.TDengineTimeout, + config.TDengineCharset, + ) + // 打开数据库连接 + dbTdEngine, err = sql.Open("taosSql", dsn) + if err != nil { + err = fmt.Errorf("无法打开数据库连接: %v", err) + return + } + // 设置连接池参数 + dbTdEngine.SetMaxOpenConns(20) + dbTdEngine.SetMaxIdleConns(5) + dbTdEngine.SetConnMaxLifetime(0) // 永不过期,TDengine长连接更高效 + // 测试连接 + if pingErr := dbTdEngine.Ping(); pingErr != nil { + err = fmt.Errorf("无法连接到TDengine: %v", pingErr) + return + } + }) + return err +} + +// GetDB 获取数据库连接 +func GetDB() (*sql.DB, error) { + if dbTdEngine == nil { + return nil, fmt.Errorf("数据库连接未初始化,请先调用InitTDengine") + } + return dbTdEngine, nil +} + +// Close 关闭数据库连接 +func Close() error { + if dbTdEngine != nil { + return dbTdEngine.Close() + } + return nil +} diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..ada984e --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,174 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/devices/{device_number}/onoff": { + "get": { + "description": "订阅设备上下线", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "订阅设备上下线", + "parameters": [ + { + "type": "string", + "description": "设备编号", + "name": "device_number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + }, + "/mqttuser/add": { + "post": { + "description": "添加mqtt认证用户信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "mqtt认证用户管理" + ], + "summary": "添加mqtt认证用户", + "parameters": [ + { + "description": "用户信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateMqttuserRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.CreateMqttuserResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + } + }, + "definitions": { + "dto.CreateMqttuserRequest": { + "type": "object", + "required": [ + "password_hash", + "username" + ], + "properties": { + "password_hash": { + "type": "string", + "minLength": 6 + }, + "username": { + "type": "string", + "maxLength": 50, + "minLength": 2 + } + } + }, + "dto.CreateMqttuserResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "127.0.0.1:9999", + BasePath: "/api/v1", + Schemes: []string{"http", "https"}, + Title: "物联网MQTT API", + Description: "物联网mqtt api接口", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..ae27aad --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,154 @@ +{ + "schemes": [ + "http", + "https" + ], + "swagger": "2.0", + "info": { + "description": "物联网mqtt api接口", + "title": "物联网MQTT API", + "contact": {}, + "version": "1.0" + }, + "host": "127.0.0.1:9999", + "basePath": "/api/v1", + "paths": { + "/devices/{device_number}/onoff": { + "get": { + "description": "订阅设备上下线", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "订阅设备上下线", + "parameters": [ + { + "type": "string", + "description": "设备编号", + "name": "device_number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + }, + "/mqttuser/add": { + "post": { + "description": "添加mqtt认证用户信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "mqtt认证用户管理" + ], + "summary": "添加mqtt认证用户", + "parameters": [ + { + "description": "用户信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateMqttuserRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.CreateMqttuserResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + } + }, + "definitions": { + "dto.CreateMqttuserRequest": { + "type": "object", + "required": [ + "password_hash", + "username" + ], + "properties": { + "password_hash": { + "type": "string", + "minLength": 6 + }, + "username": { + "type": "string", + "maxLength": 50, + "minLength": 2 + } + } + }, + "dto.CreateMqttuserResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..64158b7 --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,105 @@ +basePath: /api/v1 +definitions: + dto.CreateMqttuserRequest: + properties: + password_hash: + minLength: 6 + type: string + username: + maxLength: 50 + minLength: 2 + type: string + required: + - password_hash + - username + type: object + dto.CreateMqttuserResponse: + properties: + id: + type: integer + type: object +host: 127.0.0.1:9999 +info: + contact: {} + description: 物联网mqtt api接口 + title: 物联网MQTT API + version: "1.0" +paths: + /devices/{device_number}/onoff: + get: + consumes: + - application/json + description: 订阅设备上下线 + parameters: + - description: 设备编号 + in: path + name: device_number + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: true + type: object + "409": + description: Conflict + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: true + type: object + summary: 订阅设备上下线 + tags: + - 设备管理 + /mqttuser/add: + post: + consumes: + - application/json + description: 添加mqtt认证用户信息 + parameters: + - description: 用户信息 + in: body + name: user + required: true + schema: + $ref: '#/definitions/dto.CreateMqttuserRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.CreateMqttuserResponse' + "400": + description: Bad Request + schema: + additionalProperties: true + type: object + "409": + description: Conflict + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: true + type: object + summary: 添加mqtt认证用户 + tags: + - mqtt认证用户管理 +schemes: +- http +- https +swagger: "2.0" diff --git a/dto/mqttuser_dto.go b/dto/mqttuser_dto.go new file mode 100644 index 0000000..53a254f --- /dev/null +++ b/dto/mqttuser_dto.go @@ -0,0 +1,12 @@ +package dto + +// CreateMqttuserRequest 用户创建请求结构体 +type CreateMqttuserRequest struct { + Username string `json:"username" binding:"required,min=2,max=50"` + PasswordHash string `json:"password_hash" binding:"required,min=6"` +} + +// CreateMqttuserResponse 用户创建返回结构体 +type CreateMqttuserResponse struct { + ID uint `json:"id"` +} diff --git a/dto/sys_dto.go b/dto/sys_dto.go new file mode 100644 index 0000000..d10aa8e --- /dev/null +++ b/dto/sys_dto.go @@ -0,0 +1,10 @@ +package dto + +// SystemDeviceRequest 用户创建请求结构体 +type SystemDeviceRequest struct { + DeviceNumber string `uri:"device_number" binding:"required"` +} + +// SystemDeviceResponse 用户创建返回结构体 +type SystemDeviceResponse struct { +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..04802e3 --- /dev/null +++ b/go.mod @@ -0,0 +1,79 @@ +module iot-mqtt-gin + +go 1.23.7 + +require ( + github.com/eclipse/paho.mqtt.golang v1.5.0 + github.com/gin-gonic/gin v1.10.1 + github.com/sirupsen/logrus v1.9.3 + github.com/swaggo/files v1.0.1 + github.com/swaggo/gin-swagger v1.6.0 + github.com/swaggo/swag v1.16.6 + github.com/taosdata/driver-go/v3 v3.7.3 + github.com/yyboo586/MQSDK v0.0.0-20250808084533-bf2cfee987c9 + gorm.io/driver/mysql v1.6.0 + gorm.io/gorm v1.30.1 +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/Shopify/sarama v1.38.1 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/eapache/go-resiliency v1.7.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.9 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-openapi/jsonpointer v0.21.1 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/swag v0.23.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nsqio/go-nsq v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect + github.com/streadway/amqp v1.1.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + golang.org/x/arch v0.19.0 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/mod v0.27.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/tools v0.36.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d1b1535 --- /dev/null +++ b/go.sum @@ -0,0 +1,224 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A= +github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g= +github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc= +github.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= +github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o= +github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= +github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= +github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE= +github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM= +github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= +github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= +github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI= +github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg= +github.com/taosdata/driver-go/v3 v3.7.3 h1:bnzHF/GsChvzhgjkKrZCpCQrOe2LjwluC7l2bPtRjUM= +github.com/taosdata/driver-go/v3 v3.7.3/go.mod h1:gSxBEPOueMg0rTmMO1Ug6aeD7AwGdDGvUtLrsDTTpYc= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yyboo586/MQSDK v0.0.0-20250808084533-bf2cfee987c9 h1:bUy+CSJlAmN8wFIguwehXPprwLiX5tGU0usOwxqxAyU= +github.com/yyboo586/MQSDK v0.0.0-20250808084533-bf2cfee987c9/go.mod h1:Z8U8wbzPVHJBlMRBW/NEaaPqPtery4dK8+E4LzZ5iPU= +golang.org/x/arch v0.19.0 h1:LmbDQUodHThXE+htjrnmVD73M//D9GTH6wFZjyDkjyU= +golang.org/x/arch v0.19.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= +gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= +gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= +gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/main.go b/main.go new file mode 100644 index 0000000..76542ca --- /dev/null +++ b/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "iot-mqtt-gin/config" + "iot-mqtt-gin/controllers" + db "iot-mqtt-gin/dao" + _ "iot-mqtt-gin/docs" + "iot-mqtt-gin/mqtt" + "iot-mqtt-gin/router" + "iot-mqtt-gin/service" + "log" +) + +// @title 物联网MQTT API +// @version 1.0 +// @description 物联网mqtt api接口 + +// @host 127.0.0.1:9999 +// @BasePath /api/v1 +// @schemes http https +func main() { + // 初始化MQTT客户端 + mqttConfig := mqtt.Config{ + Broker: config.MQTTBroker, + ClientID: config.MQTTClientID, + Username: config.MQTTUsername, + Password: config.MQTTPassword, + QoS: config.MQTTQoS, + } + mqttClient, err := mqtt.NewClient(mqttConfig) + if err != nil { + log.Fatalf("无法初始化MQTT客户端: %v", err) + } + defer mqttClient.Disconnect(250) + // 连接到MQTT服务器 + if err := mqttClient.Connect(); err != nil { + log.Fatalf("连接到MQTT服务器失败: %v", err) + } + log.Println("成功连接到MQTT服务器") + + // 初始化TDengine连接 + if err := db.InitTDengine(); err != nil { + log.Fatalf("初始化TDengine失败: %v", err) + return // 确保不执行后续DB操作 + } + defer db.Close() + // 初始化MQ服务 + mqService := service.NewMQService() + defer mqService.Close() + + // 初始化生产者 + nsqProducer, _, _, err := mqService.InitProducers() + if err != nil { + log.Fatalf("初始化生产者失败: %v", err) + } + defer nsqProducer.Close() + //defer kafkaProducer.Close() + //defer rabbitProducer.Close() + + // 初始化消费者 + /*if err := mqService.InitConsumers(); err != nil { + log.Fatalf("初始化消费者失败: %v", err) + }*/ + // 启动消费 + //mqService.StartConsuming() + // 初始化所有控制器 + mqttUserCtrl := controllers.NewMqttuserController() + deviceCtrl := controllers.NewDeviceController(mqttClient, nsqProducer) + + // 设置MQTT消息处理 + mqttClient.SetMessageHandler(deviceCtrl.HandleMQTTMessage) + //引入路由 + r := router.SetupRouter(mqttUserCtrl, deviceCtrl) + r.Run(":9999") +} diff --git a/models/baseDevice.go b/models/baseDevice.go new file mode 100644 index 0000000..528f351 --- /dev/null +++ b/models/baseDevice.go @@ -0,0 +1,20 @@ +package models + +import "time" + +// BaseDevice 公共设备基础模板,包含所有设备共有的属性 +type BaseDevice struct { + ID string `json:"id" binding:"required"` // 设备唯一标识 + OrgID string `json:"org_id" binding:"required"` // 所属组织ID + DeviceCode string `json:"device_code" binding:"required"` // 设备编号(物理编号) + Name string `json:"name" binding:"required"` // 设备名称 + CreatedAt time.Time `json:"created_at"` // 创建时间 + UpdatedAt time.Time `json:"updated_at"` // 更新时间 + LastActive time.Time `json:"last_active"` // 最后活动时间 + Metadata struct { // 设备元数据(制造商、型号等) + Manufacturer string `json:"manufacturer"` + Model string `json:"model"` + FirmwareVer string `json:"firmware_ver"` + Location string `json:"location"` // 安装位置 + } `json:"metadata"` +} diff --git a/models/device.go b/models/device.go new file mode 100644 index 0000000..ab28065 --- /dev/null +++ b/models/device.go @@ -0,0 +1,51 @@ +package models + +import ( + "iot-mqtt-gin/dao" + "time" +) + +type Device struct { + ID uint `gorm:"primaryKey" json:"id"` + Name string `json:"name" gorm:"not null"` // 名称不为空 + DeviceKey string `json:"device_key" gorm:"unique;not null"` // 设备号唯一不为空 + OrgId string `json:"org_id" gorm:"not null"` // 组织不为空 +} + +// DeviceData 设备数据模型 +type DeviceData struct { + OrgID string `json:"org_id" binding:"required"` // 组织ID + DeviceID string `json:"device_id" binding:"required"` // 设备ID + Value float64 `json:"value"` // 设备数值(如温度、湿度等) + Status bool `json:"status"` // 设备状态(开关等) + Timestamp time.Time `json:"timestamp"` // 时间戳,可选,默认使用当前时间 +} + +func (Device) TableName() string { + return "t_device" +} + +// DeviceType 设备类型 +type DeviceType string + +// 定义设备类型常量 +const ( + DeviceTypeSmokeAlarm DeviceType = "smoke_alarm" // 烟雾报警器 + DeviceTypeDoorLock DeviceType = "door_lock" // 门锁 +) + +// Event 设备事件结构 +type Event struct { + EventType string `json:"event_type"` // 事件类型 + TriggerTime int64 `json:"trigger_time"` // 触发时间戳 + Priority int `json:"priority"` // 优先级: 1-紧急, 2-重要, 3-普通 + Description string `json:"description"` // 事件描述 + Parameters map[string]interface{} `json:"parameters"` // 事件参数 +} + +// Exists 检查设备是否存在 +func (d *Device) CheckDevice(device_key string) (Device, error) { + var device Device + err := dao.Db.Where("device_key = ?", device_key).First(&device).Error + return device, err +} diff --git a/models/deviceMqttLog.go b/models/deviceMqttLog.go new file mode 100644 index 0000000..35a5f00 --- /dev/null +++ b/models/deviceMqttLog.go @@ -0,0 +1,58 @@ +package models + +import ( + "gorm.io/gorm/clause" + "iot-mqtt-gin/dao" +) + +type DeviceMqttLogContent struct { + Message string `json:"message" gorm:"not null"` // 消息 + Details map[string]interface{} `json:"details" dc:"详情"` //详情 +} +type DeviceMqttLog struct { + ID uint `gorm:"primaryKey" json:"id"` + DeviceId uint `json:"device_id" gorm:"not null"` // 设备不为空 + DeviceKey string `json:"device_key" gorm:"not null"` // 设备号唯一不为空 + DeviceName string `json:"device_name"` // 设备名称 + OrgId string `json:"org_id" gorm:"not null"` // 组织不为空 + Type uint `json:"type" gorm:"not null"` // 事件类型 + Content string `json:"content"` +} + +type DeviceMqSdkLog struct { + DeviceId uint `json:"device_id" gorm:"not null"` // 设备不为空 + DeviceKey string `json:"device_key" gorm:"not null"` // 设备号唯一不为空 + DeviceName string `json:"device_name"` // 设备名称 + OrgId string `json:"org_id" gorm:"not null"` // 组织不为空 +} + +func (d *DeviceMqttLog) Validate() bool { + if d.DeviceId == 0 || d.DeviceKey == "" { + return false + } + return true +} +func (DeviceMqttLog) TableName() string { + return "t_device_log" +} +func (d *DeviceMqttLog) AddLog() error { + if !d.Validate() { + return nil // 直接返回nil表示成功处理(跳过) + } + return dao.Db.Clauses(clause.Insert{Modifier: "IGNORE"}).Create(d).Error +} +func (d *DeviceMqttLog) BatchAddLogs(logs []DeviceMqttLog) error { + // 过滤无效数据 + validLogs := make([]DeviceMqttLog, 0, len(logs)) + for _, log := range logs { + if !log.Validate() { + continue + } + validLogs = append(validLogs, log) + } + + if len(validLogs) == 0 { + return nil // 没有有效数据,直接返回 + } + return dao.Db.Clauses(clause.Insert{Modifier: "IGNORE"}).CreateInBatches(validLogs, len(validLogs)).Error +} diff --git a/models/mqsdk.go b/models/mqsdk.go new file mode 100644 index 0000000..e3af1fb --- /dev/null +++ b/models/mqsdk.go @@ -0,0 +1,69 @@ +package models + +import ( + "time" + + mqsd "github.com/yyboo586/MQSDK" +) + +// Message 扩展消息结构 +type Message struct { + ID string `json:"id"` + Topic string `json:"topic"` + Body interface{} `json:"body"` + Headers map[string]string `json:"headers"` + Timestamp int64 `json:"timestamp"` + Source string `json:"source"` // 消息来源 + RetryCount int `json:"retry_count"` // 重试次数 +} + +// ToMQSDMessage 转换为MQSDK所需的消息结构 +func (m *Message) ToMQSDMessage() *mqsd.Message { + return &mqsd.Message{ + ID: m.ID, + Topic: m.Topic, + Body: m.Body, + Headers: m.Headers, + Timestamp: m.Timestamp, + } +} + +// FromMQSDMessage 从MQSDK消息结构转换 +func FromMQSDMessage(msg *mqsd.Message) *Message { + return &Message{ + ID: msg.ID, + Topic: msg.Topic, + Body: msg.Body, + Headers: msg.Headers, + Timestamp: msg.Timestamp, + } +} + +// NewMessage 创建新消息 +func NewMessage(topic string, body interface{}, source string) *Message { + return &Message{ + ID: generateMessageID(), + Topic: topic, + Body: body, + Headers: make(map[string]string), + Timestamp: time.Now().Unix(), + //Source: source, + //RetryCount: 0, + } +} + +// 生成简单的消息ID +func generateMessageID() string { + return time.Now().Format("20060102150405") + "-" + randString(8) +} + +// 生成随机字符串 +func randString(n int) string { + const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + b := make([]byte, n) + for i := range b { + b[i] = letters[time.Now().UnixNano()%int64(len(letters))] + time.Sleep(time.Nanosecond) + } + return string(b) +} diff --git a/models/mqttuser.go b/models/mqttuser.go new file mode 100644 index 0000000..7ff44e3 --- /dev/null +++ b/models/mqttuser.go @@ -0,0 +1,34 @@ +package models + +import ( + "iot-mqtt-gin/dao" +) + +type Mqttuser struct { + ID uint `gorm:"primaryKey" json:"id"` + Username string `json:"username" gorm:"unique;not null"` // 用户名唯一且不为空 + PasswordHash string `json:"password_hash" gorm:"not null"` // 密码不为空 + Salt string `json:"salt" gorm:"not null"` // 密码盐不为空 +} + +// createUserRequest 定义添加参数结构 + +func (Mqttuser) TableName() string { + return "mqtt_user" +} + +func (u *Mqttuser) AddUser() error { + return dao.Db.Create(u).Error +} + +// Exists 检查用户名是否已存在 +func (u *Mqttuser) Exists() (bool, string) { + var count int64 + + // 检查用户名是否存在 + dao.Db.Model(&Mqttuser{}).Where("username = ?", u.Username).Count(&count) + if count > 0 { + return true, "用户名已" + } + return false, "" +} diff --git a/models/switch.go b/models/switch.go new file mode 100644 index 0000000..b1f1df6 --- /dev/null +++ b/models/switch.go @@ -0,0 +1,21 @@ +package models + +// SwitchDevice 开关设备物模型 +type SwitchDevice struct { + BaseDevice // 嵌入公共设备模板,继承所有公共属性 + Status bool `json:"status"` // 开关状态:true-开,false-关 + LastChanged string `json:"last_changed"` // 最后状态变更时间 +} + +// SwitchStatus 开关状态模型 +type SwitchStatus struct { + ID string `json:"id"` // 设备ID + Status bool `json:"status"` // 开关状态: true-开, false-关 +} + +// SwitchRequest 设置开关状态请求参数 +type SwitchRequest struct { + OrgID string `json:"org_id" binding:"required"` + DeviceID string `json:"device_id" binding:"required"` + Status bool `json:"status" binding:"required"` +} diff --git a/mqtt/client.go b/mqtt/client.go new file mode 100644 index 0000000..0af54dc --- /dev/null +++ b/mqtt/client.go @@ -0,0 +1,109 @@ +package mqtt + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "time" + + paho "github.com/eclipse/paho.mqtt.golang" +) + +// Config MQTT客户端配置 +type Config struct { + Broker string // MQTT服务器地址,如tcp://localhost:1883 + ClientID string // 客户端ID + Username string // 用户名 + Password string // 密码 + QoS int // 消息质量等级 +} + +// Client MQTT客户端封装 +type Client struct { + config Config + client paho.Client + msgHandler MessageHandler +} + +// MessageHandler 消息处理函数类型 +type MessageHandler func(topic string, payload []byte) + +// NewClient 创建新的MQTT客户端 +func NewClient(config Config) (*Client, error) { + if config.ClientID == "" { + config.ClientID = "iot-client-" + GenerateClientID() + } + + opts := paho.NewClientOptions() + opts.AddBroker(config.Broker) + opts.SetClientID(config.ClientID) + opts.SetUsername(config.Username) + opts.SetPassword(config.Password) + opts.SetCleanSession(true) + opts.SetAutoReconnect(true) + opts.SetMaxReconnectInterval(10 * time.Second) + + client := paho.NewClient(opts) + + return &Client{ + config: config, + client: client, + }, nil +} + +// Connect 连接到MQTT服务器 +func (c *Client) Connect() error { + if token := c.client.Connect(); token.Wait() && token.Error() != nil { + return token.Error() + } + return nil +} + +// Disconnect 断开与MQTT服务器的连接 +func (c *Client) Disconnect(quiesce uint) { + c.client.Disconnect(quiesce) +} + +// Publish 发布消息到指定主题 +func (c *Client) Publish(topic string, payload interface{}) error { + token := c.client.Publish(topic, byte(c.config.QoS), false, payload) + token.Wait() + return token.Error() +} + +// Subscribe 订阅指定主题 +func (c *Client) Subscribe(topic string) error { + fmt.Println("主题", topic) + token := c.client.Subscribe(topic, byte(c.config.QoS), c.defaultMessageHandler) + token.Wait() + return token.Error() +} + +// Unsubscribe 取消订阅指定主题 +func (c *Client) Unsubscribe(topic string) error { + token := c.client.Unsubscribe(topic) + token.Wait() + return token.Error() +} + +// SetMessageHandler 设置消息处理函数 +func (c *Client) SetMessageHandler(handler MessageHandler) { + c.msgHandler = handler +} + +// defaultMessageHandler 默认消息处理函数 +func (c *Client) defaultMessageHandler(client paho.Client, msg paho.Message) { + if c.msgHandler != nil { + c.msgHandler(msg.Topic(), msg.Payload()) + } +} + +// GenerateClientID 生成随机客户端ID +func GenerateClientID() string { + b := make([]byte, 8) + _, err := rand.Read(b) + if err != nil { + return fmt.Sprintf("client-%d", time.Now().UnixNano()) + } + return hex.EncodeToString(b) +} diff --git a/msgtype/message.go b/msgtype/message.go new file mode 100644 index 0000000..fada96a --- /dev/null +++ b/msgtype/message.go @@ -0,0 +1,100 @@ +package message + +import ( + "time" +) + +// 设备类型定义 +type DeviceType string + +const ( + DeviceTypeSmokeAlarm DeviceType = "smoke_alarm" // 烟雾报警器 + DeviceTypeDoorLock DeviceType = "door_lock" // 门锁 +) + +type OnOffMessage struct { + state string `json:"version"` // 上下线状态 +} + +// 状态消息 - 设备上报的状态数据 +type StateMessage struct { + DeviceID string `json:"device_id"` // 设备ID + Properties map[string]interface{} `json:"properties"` // 设备属性键值对 + Timestamp time.Time `json:"timestamp"` // 消息时间戳 + Version string `json:"version"` // 消息格式版本,默认为v1 +} + +// 命令消息 - 发送给设备的控制命令 +type CommandMessage struct { + DeviceID string `json:"device_id"` // 设备ID + Command string `json:"command"` // 命令名称 + Params map[string]interface{} `json:"params"` // 命令参数 + RequestID string `json:"request_id"` // 命令请求ID,用于跟踪 + ReceiveTime time.Time `json:"receive_time"` // 接收时间 +} + +// 事件消息 - 设备主动上报的事件 +type EventMessage struct { + DeviceID string `json:"device_id"` // 设备ID + EventType string `json:"event_type"` // 事件类型 + Description string `json:"description"` // 事件描述 + Parameters map[string]interface{} `json:"parameters"` // 事件参数 + Priority int `json:"priority"` // 优先级:1-紧急,2-重要,3-普通 + Timestamp int64 `json:"timestamp"` // 事件发生时间戳(秒) + ReceiveTime time.Time `json:"receive_time"` // 接收时间 +} + +// 响应消息 - 设备对命令的响应 +type ResponseMessage struct { + DeviceID string `json:"device_id"` // 设备ID + Command string `json:"command"` // 对应的命令 + Result interface{} `json:"result"` // 命令执行结果 + Success bool `json:"success"` // 是否成功 + Error string `json:"error"` // 错误信息,如果失败 + RequestID string `json:"request_id"` // 对应的请求ID + Timestamp int64 `json:"timestamp"` // 响应时间戳(秒) + ReceiveTime time.Time `json:"receive_time"` // 接收时间 +} + +// 设备注册消息 - 设备注册时的信息 +type RegisterMessage struct { + DeviceID string `json:"device_id"` // 设备ID + DeviceType DeviceType `json:"device_type"` // 设备类型 + Model string `json:"model"` // 设备型号 + Firmware string `json:"firmware"` // 固件版本 + MacAddress string `json:"mac_address"` // MAC地址 + Timestamp time.Time `json:"timestamp"` // 注册时间 +} + +// 设备心跳消息 - 设备定期发送的在线状态 +type HeartbeatMessage struct { + DeviceID string `json:"device_id"` // 设备ID + Status string `json:"status"` // 状态:online/offline + Battery int `json:"battery"` // 电池电量 电量(%),适用于电池设备 + Signal int `json:"signal"` // 信号强度,0-100 + Timestamp time.Time `json:"timestamp"` // 心跳时间 +} + +// 烟雾报警器特定状态 - 继承通用状态 +type SmokeAlarmState struct { + SmokeConcentration float64 `json:"smoke_concentration"` // 烟雾浓度(%) + AlarmStatus bool `json:"alarm_status"` // 报警状态 + BatteryLevel int `json:"battery_level"` // 电池电量(%) + SensitivityLevel int `json:"sensitivity_level"` // 灵敏度级别1-5 + AlarmThreshold float64 `json:"alarm_threshold"` // 报警阈值(%) +} + +// 门锁特定状态 - 继承通用状态 +type DoorLockState struct { + Locked bool `json:"locked"` // 是否锁定 + BatteryLevel int `json:"battery_level"` // 电池电量(%) + LastOpenedTime time.Time `json:"last_opened_time"` // 最后开锁时间 + ErrorCode int `json:"error_code"` // 错误代码,0表示无错误 +} + +// 门锁事件参数 +type LockEventParams struct { + Operation string `json:"operation"` // 操作:lock/unlock + Operator string `json:"operator"` // 操作者 + OperationTime time.Time `json:"operation_time"` // 操作时间 +} diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go new file mode 100644 index 0000000..db56eb4 --- /dev/null +++ b/pkg/logger/logger.go @@ -0,0 +1,149 @@ +package logger + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "io" + "net/http" + "os" + "path" + "runtime/debug" + "time" +) + +func init() { + // 设置日志格式为json格式 + logrus.SetFormatter(&logrus.JSONFormatter{ + TimestampFormat: "2006-01-02 15:04:05", + }) + logrus.SetReportCaller(false) +} + +func Write(msg string, filename string) { + setOutPutFile(logrus.InfoLevel, filename) + logrus.Info(msg) +} + +func Debug(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.DebugLevel, "debug") + logrus.WithFields(fields).Debug(args) +} + +func Info(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.InfoLevel, "info") + logrus.WithFields(fields).Info(args) +} + +func Warn(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.WarnLevel, "warn") + logrus.WithFields(fields).Warn(args) +} + +func Fatal(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.FatalLevel, "fatal") + logrus.WithFields(fields).Fatal(args) +} + +func Error(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.ErrorLevel, "error") + logrus.WithFields(fields).Error(args) +} + +func Panic(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.PanicLevel, "panic") + logrus.WithFields(fields).Panic(args) +} + +func Trace(fields logrus.Fields, args ...interface{}) { + setOutPutFile(logrus.TraceLevel, "trace") + logrus.WithFields(fields).Trace(args) +} + +func setOutPutFile(level logrus.Level, logName string) { + if _, err := os.Stat("./runtime/log"); os.IsNotExist(err) { + err = os.MkdirAll("./runtime/log", 0777) + if err != nil { + panic(fmt.Errorf("create log dir '%s' error: %s", "./runtime/log", err)) + } + } + + timeStr := time.Now().Format("2006-01-02") + fileName := path.Join("./runtime/log", logName+"_"+timeStr+".log") + + var err error + os.Stderr, err = os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + fmt.Println("open log file err", err) + } + logrus.SetOutput(os.Stderr) + logrus.SetLevel(level) + return +} + +func LoggerToFile() gin.LoggerConfig { + + if _, err := os.Stat("./runtime/log"); os.IsNotExist(err) { + err = os.MkdirAll("./runtime/log", 0777) + if err != nil { + panic(fmt.Errorf("create log dir '%s' error: %s", "./runtime/log", err)) + } + } + + timeStr := time.Now().Format("2006-01-02") + fileName := path.Join("./runtime/log", "success_"+timeStr+".log") + + os.Stderr, _ = os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + + var conf = gin.LoggerConfig{ + Formatter: func(param gin.LogFormatterParams) string { + return fmt.Sprintf("%s - %s \"%s %s %s %d %s \"%s\" %s\"\n", + param.TimeStamp.Format("2006-01-02 15:04:05"), + param.ClientIP, + param.Method, + param.Path, + param.Request.Proto, + param.StatusCode, + param.Latency, + param.Request.UserAgent(), + param.ErrorMessage, + ) + }, + Output: io.MultiWriter(os.Stdout, os.Stderr), + } + + return conf +} + +func Recover(c *gin.Context) { + defer func() { + if err := recover(); err != nil { + if _, errDir := os.Stat("./runtime/log"); os.IsNotExist(errDir) { + errDir = os.MkdirAll("./runtime/log", 0777) + if errDir != nil { + panic(fmt.Errorf("create log dir '%s' error: %s", "./runtime/log", errDir)) + } + } + + timeStr := time.Now().Format("2006-01-02") + fileName := path.Join("./runtime/log", "error_"+timeStr+".log") + + f, errFile := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + if errFile != nil { + fmt.Println(errFile) + } + timeFileStr := time.Now().Format("2006-01-02 15:04:05") + f.WriteString("panic error time:" + timeFileStr + "\n") + f.WriteString(fmt.Sprintf("%v", err) + "\n") + f.WriteString("stacktrace from panic:" + string(debug.Stack()) + "\n") + f.Close() + c.JSON(http.StatusOK, gin.H{ + "code": 500, + "msg": fmt.Sprintf("%v", err), + }) + //终止后续接口调用,不加的话recover到异常后,还会继续执行接口里后续代码 + c.Abort() + } + }() + c.Next() +} diff --git a/router/routers.go b/router/routers.go new file mode 100644 index 0000000..29dc070 --- /dev/null +++ b/router/routers.go @@ -0,0 +1,39 @@ +package router + +import ( + "github.com/gin-gonic/gin" + swaggerfiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" + "iot-mqtt-gin/controllers" + "iot-mqtt-gin/pkg/logger" +) + +func SetupRouter( + mqttuserCtrl *controllers.MqttuserController, + deviceCtrl *controllers.DeviceController, +) *gin.Engine { + r := gin.Default() + r.Use(gin.LoggerWithConfig(logger.LoggerToFile())) + r.Use(logger.Recover) + r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) + // 定义API路由组 + v1 := r.Group("/api/v1") + { + user := v1.Group("/mqttuser") + { + user.POST("/add", mqttuserCtrl.AddUser) + } + // 设备相关路由 + devices := v1.Group("/devices") + { + devices.GET("/:device_number/onoff", deviceCtrl.DeviceOnOff) // 设备上下线 + + devices.GET("/tdengine/test", deviceCtrl.TDengineTest) // TDengine测试 + /*devices.GET("/:device_number/properties", controllers.DeviceController{}.DeviceOnOff) // 获取设备属性 + devices.GET("/:device_number/properties/:property", controllers.DeviceController{}.DeviceOnOff) // 更新设备属性 + devices.GET("/:device_number/command", controllers.DeviceController{}.DeviceOnOff) // 发送命令 + devices.GET("/:device_number/events", controllers.DeviceController{}.DeviceOnOff) // 获取事件*/ + } + } + return r +} diff --git a/runtime/log/error_2025-08-01.log b/runtime/log/error_2025-08-01.log new file mode 100644 index 0000000..46c35ca --- /dev/null +++ b/runtime/log/error_2025-08-01.log @@ -0,0 +1,40 @@ +{"level":"error","msg":"[]","time":"2025-08-01 14:13:51","写入上线日志失败":"Error 1366: Incorrect integer value: '' for column 'online_status' at row 1"} +{"level":"error","msg":"[]","time":"2025-08-01 14:14:02","写入下线日志失败":"Error 1366: Incorrect integer value: '' for column 'online_status' at row 1"} +{"level":"error","msg":"[]","time":"2025-08-01 16:56:16","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:56:28","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:56:57","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:07","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:21","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:24","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:25","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:30","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:33","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 16:57:35","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:05:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:05:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:14:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:14:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:23:47","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:23:52","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:30:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:30:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:39:32","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:39:37","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:47:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:47:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:55:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 17:55:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:02:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:02:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:10:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:10:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:17:31","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:17:36","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:26:32","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:26:37","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:28:07","写入日志失败":"Error 1062 (23000): Duplicate entry '30' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:38:08","写入日志失败":"Error 1062 (23000): Duplicate entry '65' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:38:12","写入日志失败":"Error 1062 (23000): Duplicate entry '65' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:42:07","定时写入日志失败":"Error 1062 (23000): Duplicate entry '68' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:42:10","定时写入日志失败":"Error 1062 (23000): Duplicate entry '68' for key 't_device_online_log.PRIMARY'"} +{"level":"error","msg":"[]","time":"2025-08-01 18:42:14","定时写入日志失败":"Error 1062 (23000): Duplicate entry '68' for key 't_device_online_log.PRIMARY'"} diff --git a/runtime/log/error_2025-08-02.log b/runtime/log/error_2025-08-02.log new file mode 100644 index 0000000..bc25093 --- /dev/null +++ b/runtime/log/error_2025-08-02.log @@ -0,0 +1,219 @@ +{"level":"error","msg":"[]","time":"2025-08-02 14:07:05","批量写入日志失败":"failed to parse field: Content, error: invalid field found for struct iot-mqtt-gin/models.DeviceMqttLogContent's field Details: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +{"level":"error","msg":"[]","time":"2025-08-02 14:07:08","批量写入日志失败":"failed to parse field: Content, error: invalid field found for struct iot-mqtt-gin/models.DeviceMqttLogContent's field Details: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +{"level":"error","msg":"[]","time":"2025-08-02 14:07:11","批量写入日志失败":"failed to parse field: Content, error: invalid field found for struct iot-mqtt-gin/models.DeviceMqttLogContent's field Details: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +{"level":"error","msg":"[]","time":"2025-08-02 14:15:50","批量写入日志失败":"failed to parse field: Content, error: invalid field found for struct iot-mqtt-gin/models.DeviceMqttLogContent's field Details: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +{"level":"error","msg":"[]","time":"2025-08-02 14:15:55","批量写入日志失败":"failed to parse field: Content, error: invalid field found for struct iot-mqtt-gin/models.DeviceMqttLogContent's field Details: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +{"level":"error","msg":"[]","time":"2025-08-02 14:17:30","批量写入日志失败":"failed to parse field: Content, error: failed to parse field: Details, error: unsupported data type: \u0026map[]: Table not set, please set it like: db.Model(\u0026user) or db.Table(\"users\")"} +{"level":"error","msg":"[]","time":"2025-08-02 14:18:51","批量写入日志失败":"failed to parse field: Content, error: failed to parse field: Details, error: unsupported data type: \u0026map[]: Table not set, please set it like: db.Model(\u0026user) or db.Table(\"users\")"} +{"level":"error","msg":"[]","time":"2025-08-02 14:24:40","批量写入日志失败":"invalid field found for struct iot-mqtt-gin/models.DeviceMqttLog's field Content: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +{"level":"error","msg":"[]","time":"2025-08-02 14:29:06","批量写入日志失败":"invalid field found for struct iot-mqtt-gin/models.DeviceMqttLog's field Content: define a valid foreign key for relations or implement the Valuer/Scanner interface"} +panic error time:2025-08-02 16:44:01 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 39 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0xcd32c0?, 0x1e561e0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +iot-mqtt-gin/mqtt.(*Client).Subscribe(0x0, {0xdb41ac, 0x5}) + E:/iot-mqtt-gin/mqtt/client.go:76 +0x5a +iot-mqtt-gin/controllers.DeviceController.DeviceOnOff({0x0, 0x0, {{0x0, 0x0}, 0x0, 0x0, {{}, 0x0}, {{}, 0x0}}}, ...) + E:/iot-mqtt-gin/controllers/device.go:124 +0x2b6 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc0002a8300) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0002a8300) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc0002a8300) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0002a8300) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000172000, 0xc0002a8300) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000172000, {0xfadf50, 0xc0000ae2a0}, 0xc0001ae000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc00019a6f0?}, {0xfadf50?, 0xc0000ae2a0?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0005f01b0, {0xfafbc8, 0xc000111ce0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-02 16:47:42 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 49 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x19a32c0?, 0x2b251e0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +iot-mqtt-gin/mqtt.(*Client).Subscribe(0x0, {0x1a841ac, 0x5}) + E:/iot-mqtt-gin/mqtt/client.go:77 +0xbc +iot-mqtt-gin/controllers.DeviceController.DeviceOnOff({0x0, 0x0, {{0x0, 0x0}, 0x0, 0x0, {{}, 0x0}, {{}, 0x0}}}, ...) + E:/iot-mqtt-gin/controllers/device.go:124 +0x2b6 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc000764100) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000764100) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc000764100) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000764100) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000172000, 0xc000764100) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000172000, {0x1c7ded0, 0xc0006ee2a0}, 0xc0001a0b40) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc000111c80?}, {0x1c7ded0?, 0xc0006ee2a0?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0000b0510, {0x1c7fb48, 0xc00019a210}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-02 16:49:40 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 60 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x11a32c0?, 0x23251e0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +iot-mqtt-gin/mqtt.(*Client).Subscribe(0x0, {0x12841ac, 0x5}) + E:/iot-mqtt-gin/mqtt/client.go:77 +0xbc +iot-mqtt-gin/controllers.DeviceController.DeviceOnOff({0x0, 0x0, {{0x0, 0x0}, 0x0, 0x0, {{}, 0x0}, {{}, 0x0}}}, ...) + E:/iot-mqtt-gin/controllers/device.go:124 +0x2b6 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc000670000) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000670000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc000670000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000670000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc00014a000, 0xc000670000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc00014a000, {0x147ded0, 0xc0000ae1c0}, 0xc0001a2780) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc00011c1b0?}, {0x147ded0?, 0xc0000ae1c0?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0000b03f0, {0x147fb48, 0xc0001ce1e0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-02 16:51:01 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 53 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x13732c0?, 0x24f51e0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +iot-mqtt-gin/mqtt.(*Client).Subscribe(0x0, {0x14541ac, 0x5}) + E:/iot-mqtt-gin/mqtt/client.go:77 +0xbc +iot-mqtt-gin/controllers.DeviceController.DeviceOnOff({0x0, 0x0, {{0x0, 0x0}, 0x0, 0x0, {{}, 0x0}, {{}, 0x0}}}, ...) + E:/iot-mqtt-gin/controllers/device.go:124 +0x2b2 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc000296400) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000296400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc000296400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000296400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc00016c000, 0xc000296400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc00016c000, {0x164de70, 0xc0000ae1c0}, 0xc0001e6780) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc00025de30?}, {0x164de70?, 0xc0000ae1c0?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc000152120, {0x164fae8, 0xc00019b8f0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-02 16:52:39 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 50 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0xf91f00?, 0x2113180?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +iot-mqtt-gin/mqtt.(*Client).Subscribe(0x0, {0x1072c8c, 0x5}) + E:/iot-mqtt-gin/mqtt/client.go:77 +0xbc +iot-mqtt-gin/controllers.DeviceController.DeviceOnOff({0x0, 0x0, {{0x0, 0x0}, 0x0, 0x0, {{}, 0x0}, {{}, 0x0}}}, ...) + E:/iot-mqtt-gin/controllers/device.go:124 +0x2b2 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc00058c400) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc00058c400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc00058c400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc00058c400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000172000, 0xc00058c400) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000172000, {0x126c700, 0xc0000ae1c0}, 0xc00016ab40) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc0002b5a70?}, {0x126c700?, 0xc0000ae1c0?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0002fc000, {0x126e5d0, 0xc00019bce0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + diff --git a/runtime/log/error_2025-08-04.log b/runtime/log/error_2025-08-04.log new file mode 100644 index 0000000..1619949 --- /dev/null +++ b/runtime/log/error_2025-08-04.log @@ -0,0 +1,5 @@ +{"level":"error","msg":"[]","time":"2025-08-04 15:35:18","写入报警日志失败":"reflect.Value.Convert: value of type string cannot be converted to type model.DeviceLogContent"} +{"level":"error","msg":"[]","time":"2025-08-04 15:37:35","写入报警日志失败":"reflect.Value.Convert: value of type string cannot be converted to type model.DeviceLogContent"} +{"level":"error","msg":"[]","time":"2025-08-04 15:39:20","写入报警日志失败":"reflect.Value.Convert: value of type string cannot be converted to type model.DeviceLogContent"} +{"level":"error","msg":"[]","time":"2025-08-04 15:49:51","写入报警日志失败":"gomail: could not send email 1: gomail: invalid address \"11111111111\": mail: missing '@' or angle-addr"} +{"level":"error","msg":"[]","time":"2025-08-04 15:52:36","写入报警日志失败":"OK"} diff --git a/runtime/log/error_2025-08-07.log b/runtime/log/error_2025-08-07.log new file mode 100644 index 0000000..9070ac1 --- /dev/null +++ b/runtime/log/error_2025-08-07.log @@ -0,0 +1,378 @@ +panic error time:2025-08-07 11:36:10 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 55 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff63a0dd8c0?, 0x7ff63a002f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff63a3e71c0, 0x7ff63ab29f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff63a3e71c0, 0x7ff63ab29f40}, {0xc00118a0f0, 0x4a}, {0x0, 0x0, 0x0}, 0x65?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0xfd?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x3b?, 0xc0011b3368) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0xc0011820e0?, {0x7ff63a3e71c0?, 0x7ff63ab29f40?}, {0xc00118a0f0?, 0x4?}, {0x0?, 0xc00118a0f0?, 0xc00117e0d0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x7ff63a2135b2?, {0xc00118a0f0?, 0xc0011b34a0?}, {0x0?, 0x4?, 0x6?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc0011b3530) + E:/iot-mqtt-gin/service/deviceService.go:30 +0x1e7 +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff638ef6653?, 0xc001192200) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc001192200) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001192200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc001192200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001192200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0002e6000, 0xc001192200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0002e6000, {0x7ff63a3e5950, 0xc00014c460}, 0xc0002da3c0) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc0001bd680?}, {0x7ff63a3e5950?, 0xc00014c460?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc00014e5a0, {0x7ff63a3e7ab8, 0xc0001bd440}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-07 11:48:21 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 39 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff7aca2d8c0?, 0x7ff7ac952f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff7acd37180, 0x7ff7ad479f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff7acd37180, 0x7ff7ad479f40}, {0xc001118400, 0x37}, {0xc001135470, 0x3, 0x3}, 0x59?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0x28?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x7ff7ab612acb?, 0xc001135348) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0x0?, {0x7ff7acd37180?, 0x7ff7ad479f40?}, {0xc001118400?, 0x7ff7ab60a49b?}, {0xc001135470?, 0x7ff7ac9e26c0?, 0xc001100000?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x4050000000000000?, {0xc001118400?, 0x7ff7ad432900?}, {0xc001135470?, 0x4?, 0xc0000a6c58?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc001135530) + E:/iot-mqtt-gin/service/deviceService.go:31 +0x2ed +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff7ab846653?, 0xc001114200) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc001114200) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001114200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc001114200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001114200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000b6000, 0xc001114200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000b6000, {0x7ff7acd35910, 0xc00014c380}, 0xc00008e3c0) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc000283050?}, {0x7ff7acd35910?, 0xc00014c380?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0000b2360, {0x7ff7acd37a78, 0xc000282f60}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-07 11:55:17 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 59 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff6031fd8c0?, 0x7ff603122f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff603507160, 0x7ff603c49f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff603507160, 0x7ff603c49f40}, {0xc00002ea00, 0x35}, {0xc000047480, 0x3, 0x3}, 0x59?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0x38?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x7ff601de2acb?, 0xc000047358) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0x0?, {0x7ff603507160?, 0x7ff603c49f40?}, {0xc00002ea00?, 0x7ff601dda49b?}, {0xc000047480?, 0x7ff6031b26c0?, 0x0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x4050000000000000?, {0xc00002ea00?, 0x7ff603c02900?}, {0xc000047480?, 0x2?, 0x30?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc000047530) + E:/iot-mqtt-gin/service/deviceService.go:31 +0x285 +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff602016653?, 0xc00041a500) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc00041a500) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc00041a500) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc00041a500) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc00041a500) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000b6000, 0xc00041a500) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000b6000, {0x7ff6035058f0, 0xc000168380}, 0xc00020e8c0) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc0001fa570?}, {0x7ff6035058f0?, 0xc000168380?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc00014c120, {0x7ff603507a58, 0xc0001fa3f0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-07 11:59:48 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 38 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff7e366d8c0?, 0x7ff7e3592f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff7e3977160, 0x7ff7e40b9f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff7e3977160, 0x7ff7e40b9f40}, {0xc00002e480, 0x33}, {0xc000047480, 0x3, 0x3}, 0x59?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0x38?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x7ff7e2252acb?, 0xc000047358) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0x0?, {0x7ff7e3977160?, 0x7ff7e40b9f40?}, {0xc00002e480?, 0x7ff7e224a49b?}, {0xc000047480?, 0x7ff7e36226c0?, 0x0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x4050000000000000?, {0xc00002e480?, 0x7ff7e4072900?}, {0xc000047480?, 0x2?, 0x30?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc000047530) + E:/iot-mqtt-gin/service/deviceService.go:31 +0x285 +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff7e2486653?, 0xc001214000) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc001214000) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000172000, 0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000172000, {0x7ff7e39758f0, 0xc0000b0380}, 0xc000234140) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc00003c5d0?}, {0x7ff7e39758f0?, 0xc0000b0380?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0001181b0, {0x7ff7e3977a58, 0xc000244f90}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-07 12:00:18 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 38 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff7e366d8c0?, 0x7ff7e3592f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff7e3977160, 0x7ff7e40b9f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff7e3977160, 0x7ff7e40b9f40}, {0xc00002e640, 0x33}, {0xc000047480, 0x3, 0x3}, 0x59?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0x38?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x7ff7e2252acb?, 0xc000047358) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0x0?, {0x7ff7e3977160?, 0x7ff7e40b9f40?}, {0xc00002e640?, 0x7ff7e224a49b?}, {0xc000047480?, 0x7ff7e36226c0?, 0x0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x4050000000000000?, {0xc00002e640?, 0x7ff7e4072900?}, {0xc000047480?, 0x2?, 0x650000006e?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc000047530) + E:/iot-mqtt-gin/service/deviceService.go:31 +0x285 +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff7e2486653?, 0xc001214000) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc001214000) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000172000, 0xc001214000) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000172000, {0x7ff7e39758f0, 0xc0000b0460}, 0xc000234280) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc00003c5d0?}, {0x7ff7e39758f0?, 0xc0000b0460?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0001181b0, {0x7ff7e3977a58, 0xc000244f90}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-07 13:43:26 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 57 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff7958dd8c0?, 0x7ff795802f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff795be71c0, 0x7ff796329f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff795be71c0, 0x7ff796329f40}, {0xc000122b40, 0x33}, {0xc0010c1480, 0x3, 0x3}, 0x59?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0xf8?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x7ff7944c2acb?, 0xc0010c1318) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0x0?, {0x7ff795be71c0?, 0x7ff796329f40?}, {0xc000122b40?, 0x7ff7944ba49b?}, {0xc0010c1480?, 0x7ff7958926c0?, 0x0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x4050000000000000?, {0xc000122b40?, 0x7ff7962e2900?}, {0xc0010c1480?, 0x2?, 0xc0001ce660?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc0010c1530) + E:/iot-mqtt-gin/service/deviceService.go:31 +0x2a6 +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff7946f6653?, 0xc0010a4200) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc0010a4200) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000b64e0, 0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000b64e0, {0x7ff795be5950, 0xc0000b02a0}, 0xc00008e3c0) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc0001ce540?}, {0x7ff795be5950?, 0xc0000b02a0?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0000b25a0, {0x7ff795be7ab8, 0xc0001ce2a0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + +panic error time:2025-08-07 13:43:41 +runtime error: invalid memory address or nil pointer dereference +stacktrace from panic:goroutine 57 [running]: +runtime/debug.Stack() + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/debug/stack.go:26 +0x5e +iot-mqtt-gin/pkg/logger.Recover.func1() + E:/iot-mqtt-gin/pkg/logger/logger.go:138 +0x26f +panic({0x7ff7958dd8c0?, 0x7ff795802f70?}) + E:/go-version/go1.23.7.windows-amd64/go/src/runtime/panic.go:791 +0x132 +database/sql.(*DB).conn(0x0, {0x7ff795be71c0, 0x7ff796329f40}, 0x1) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1309 +0x54 +database/sql.(*DB).exec(0x0, {0x7ff795be71c0, 0x7ff796329f40}, {0xc000122d00, 0x33}, {0xc0010c1480, 0x3, 0x3}, 0x59?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1681 +0x54 +database/sql.(*DB).ExecContext.func1(0xf8?) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1664 +0x4f +database/sql.(*DB).retry(0x7ff7944c2acb?, 0xc0010c1318) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1568 +0x42 +database/sql.(*DB).ExecContext(0x0?, {0x7ff795be71c0?, 0x7ff796329f40?}, {0xc000122d00?, 0x7ff7944ba49b?}, {0xc0010c1480?, 0x7ff7958926c0?, 0x0?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1663 +0xc8 +database/sql.(*DB).Exec(0x4050000000000000?, {0xc000122d00?, 0x7ff7962e2900?}, {0xc0010c1480?, 0x2?, 0x2f00000031?}) + E:/go-version/go1.23.7.windows-amd64/go/src/database/sql/sql.go:1677 +0x3a +iot-mqtt-gin/service.InsertDeviceData(0xc0010c1530) + E:/iot-mqtt-gin/service/deviceService.go:31 +0x2a6 +iot-mqtt-gin/controllers.(*DeviceController).TDengineTest(0x7ff7946f6653?, 0xc0010a4200) + E:/iot-mqtt-gin/controllers/device.go:275 +0x9e +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +iot-mqtt-gin/pkg/logger.Recover(0xc0010a4200) + E:/iot-mqtt-gin/pkg/logger/logger.go:148 +0x5c +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/recovery.go:102 +0x6f +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/logger.go:249 +0xe5 +github.com/gin-gonic/gin.(*Context).Next(...) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/context.go:185 +github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000b64e0, 0xc0010a4200) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:644 +0x892 +github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000b64e0, {0x7ff795be5950, 0xc0000b0380}, 0xc00008e640) + C:/Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:600 +0x1b2 +net/http.serverHandler.ServeHTTP({0xc0001ce540?}, {0x7ff795be5950?, 0xc0000b0380?}, 0x6?) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3210 +0x8e +net/http.(*conn).serve(0xc0000b25a0, {0x7ff795be7ab8, 0xc0001ce2a0}) + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:2092 +0x5d0 +created by net/http.(*Server).Serve in goroutine 1 + E:/go-version/go1.23.7.windows-amd64/go/src/net/http/server.go:3360 +0x485 + diff --git a/runtime/log/error_2025-08-08.log b/runtime/log/error_2025-08-08.log new file mode 100644 index 0000000..8f6a5af --- /dev/null +++ b/runtime/log/error_2025-08-08.log @@ -0,0 +1,2 @@ +{"level":"error","msg":"[]","time":"2025-08-08 16:25:45","发布NSQ消息失败: ":"aaa"} +{"level":"error","msg":"[]","time":"2025-08-08 16:27:47","发布NSQ消息失败: ":"aaa"} diff --git a/runtime/log/success_2025-07-30.log b/runtime/log/success_2025-07-30.log new file mode 100644 index 0000000..6ef060b --- /dev/null +++ b/runtime/log/success_2025-07-30.log @@ -0,0 +1,58 @@ +2025-07-30 15:55:07 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 525.3µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 15:55:07 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 532.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 15:55:07 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 2.4203ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 15:55:07 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 9.1765ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 15:55:08 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:01:00 - 127.0.0.1 "POST /api/v1/users/add HTTP/1.1 404 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:01:57 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 531.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:01:57 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 529.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:01:57 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.055ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:01:57 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.5446ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:01:58 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:02:09 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 500 142.4599ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:24:11 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 500 147.1968ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:28:03 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0611ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:28:03 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 527.7µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:28:03 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.5885ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:28:03 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.2883ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:28:04 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:28:25 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 500 148.9433ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:30:04 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 2.6989ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:30:04 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 2.3968ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:30:04 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 2.1781ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:30:04 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 7.1488ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:30:05 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 517µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:30:18 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 500 158.6516ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:40:22 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 4.289ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:40:23 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 4.3853ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:40:23 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 6.3975ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:40:23 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 18.1871ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:40:23 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:40:36 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 500 175.6903ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:42:22 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 558.5µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:42:22 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 999.6µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:42:22 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0007ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:42:22 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 2.9985ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:42:23 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 1.0009ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:42:39 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 500 179.8003ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:43:23 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 532.7µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:43:23 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 526.4µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:43:23 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.5411ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:43:23 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 2.5451ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:43:23 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 1.7835ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:43:36 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 409 78.6288ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:00 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.6122ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:00 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.1278ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:00 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.5251ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:00 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 9.1279ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:01 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 998.9µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:34 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 409 69.8489ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:55:44 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 200 211.0508ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:57:46 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 520.3µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:57:46 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.1222ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:57:46 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.7364ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:57:46 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 5.1217ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:57:47 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:58:09 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 409 76.324ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:58:10 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 409 76.6761ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-30 16:58:18 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 200 236.4315ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " diff --git a/runtime/log/success_2025-07-31.log b/runtime/log/success_2025-07-31.log new file mode 100644 index 0000000..7219813 --- /dev/null +++ b/runtime/log/success_2025-07-31.log @@ -0,0 +1,58 @@ +2025-07-31 15:18:09 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0964ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:18:09 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 684.9µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:18:09 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0442ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:18:09 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.8016ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:18:10 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 524.2µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:18:48 - 127.0.0.1 "GET /api/v1/devices/online/{device_id} HTTP/1.1 400 117.2224ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:20:03 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 525.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:20:03 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 527.5µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:20:03 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 528.7µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:20:03 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.0033ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:20:03 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 524.3µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:20:16 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 400 108.5836ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:22:26 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 531.4µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:22:26 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 524.9µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:22:26 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0694ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:22:26 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.3704ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:22:26 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 519.6µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:22:41 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 400 115.5238ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:25:21 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0442ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:25:21 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.0553ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:25:21 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.5844ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:25:21 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.248ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:25:21 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:25:34 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 404 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:26:16 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0511ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:26:16 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 524.5µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:26:16 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0965ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:26:16 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.9223ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:26:16 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:26:28 - 127.0.0.1 "GET /api/v1/devices/online HTTP/1.1 400 110.6415ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:31:51 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0959ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:31:51 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.5932ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:31:51 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0889ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:31:51 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.7093ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:31:52 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 526.7µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:32:04 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 400 110.9269ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:38:09 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.5942ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:38:09 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.1239ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:38:09 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0688ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:38:09 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.2281ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:38:09 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:38:19 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 400 135.1098ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:41:18 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0881ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:41:18 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.0507ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:41:18 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0603ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:41:18 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.7328ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:41:19 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:41:28 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 400 108.302ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:49:47 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0515ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:49:47 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.0509ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:49:47 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.6686ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:49:47 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 2.7679ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:49:47 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:49:59 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 200 110.5417ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:56:25 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 200 108.9329ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 15:59:00 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 200 122.054ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 16:06:06 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 200 115.5261ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-07-31 16:17:59 - 127.0.0.1 "GET /api/v1/devices/online/test001 HTTP/1.1 200 113.0256ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " diff --git a/runtime/log/success_2025-08-01.log b/runtime/log/success_2025-08-01.log new file mode 100644 index 0000000..e6624ac --- /dev/null +++ b/runtime/log/success_2025-08-01.log @@ -0,0 +1,70 @@ +2025-08-01 09:44:50 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0465ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:44:50 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 522.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:44:50 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.053ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:44:50 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.7618ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:44:50 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:44:51 - 127.0.0.1 "GET /swagger/favicon-32x32.png HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:51:49 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 517.8µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:51:49 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 527.2µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:51:49 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0578ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:51:49 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.825ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:51:50 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 999.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:51:50 - 127.0.0.1 "GET /swagger/favicon-32x32.png HTTP/1.1 200 1.0008ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:52:04 - 127.0.0.1 "POST /api/v1/devices/test001/online HTTP/1.1 404 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:53:58 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.147ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:53:59 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 524.9µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:53:59 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.5735ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:53:59 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.2014ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:53:59 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 09:54:10 - 127.0.0.1 "GET /api/v1/devices/test001/online HTTP/1.1 200 34.9332ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:29:03 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 524.2µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:29:03 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 524.3µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:29:03 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.05ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:29:03 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 2.0992ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:29:04 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:29:20 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 37.1695ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 10:35:40 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 34.481ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:09:29 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 400 71.7295ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:11:16 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 2.0953ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:11:16 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.0678ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:11:16 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 655.6µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:11:16 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 2.7891ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:11:17 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:12:00 - 127.0.0.1 "GET /api/v1/devices/test002/onoff HTTP/1.1 400 108.7722ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:14 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 517.7µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:14 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 523.7µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:14 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.6992ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:14 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.8067ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:15 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 522.6µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:26 - 127.0.0.1 "GET /api/v1/devices/test002/onoff HTTP/1.1 400 70.9611ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:13:37 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 113.9314ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:15:22 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:15:22 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 304 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:15:22 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 304 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:15:22 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 304 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:15:22 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:17:06 - 127.0.0.1 "GET /api/v1/devices/test002/onoff HTTP/1.1 400 74.8769ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:17:10 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 114.3223ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:35:40 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 524.9µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:35:40 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:35:40 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.9987ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:35:40 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.9976ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 14:35:40 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:34 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 530.6µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:34 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.058ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:34 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.169ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:34 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 2.7306ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:35 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:35 - 127.0.0.1 "GET /swagger/favicon-32x32.png HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:49 - 127.0.0.1 "GET /api/v1/devices/test002/onoff HTTP/1.1 400 69.9941ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:16:55 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.1202ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 16:55:58 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 103.7162ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:37:41 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 104.5181ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:41:59 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 107.9305ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:45:33 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 105.9445ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:46:22 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 105.2668ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:49:03 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 105.9009ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:51:15 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 107.6924ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:52:59 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.6643ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 18:54:05 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 115.5263ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-01 19:02:29 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 108.9289ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " diff --git a/runtime/log/success_2025-08-02.log b/runtime/log/success_2025-08-02.log new file mode 100644 index 0000000..e23c308 --- /dev/null +++ b/runtime/log/success_2025-08-02.log @@ -0,0 +1,61 @@ +2025-08-02 14:06:38 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:06:38 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 578.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:06:38 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 667.5µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:06:38 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 3.4661ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:06:38 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:06:48 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 113.3982ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:17:21 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.055ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:18:40 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.9011ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:24:37 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 107.0917ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:29:02 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.3639ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:31:01 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 119.6805ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:36:41 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 108.6759ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 14:39:35 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 117.6633ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:43:45 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 2.1487ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:43:45 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.7422ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:43:45 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 2.252ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:43:45 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 6.2183ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:43:46 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:43:58 - 127.0.0.1 "GET /api/v1/devices/test0010/onoff HTTP/1.1 400 80.8702ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:44:01 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 74.5893ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:25 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 2.9825ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:25 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.7645ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:25 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 2.9536ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:25 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 12.1051ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:26 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:37 - 127.0.0.1 "GET /api/v1/devices/test0010/onoff HTTP/1.1 400 68.5067ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:47:42 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 66.9079ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:49:40 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 75.1122ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:51:01 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 68.6448ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 16:52:39 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 73.9212ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:05:25 - 127.0.0.1 "GET /api/v1/devices/test0010/onoff HTTP/1.1 400 73.5588ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:05:28 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 103.794ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:14:47 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 3.1093ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:14:47 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.0088ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:14:47 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 2.011ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:14:47 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.9854ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:14:48 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 999.1µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:18:58 - 127.0.0.1 "POST /api/v1/mqttuser/add HTTP/1.1 200 222.8678ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:25 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:25 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 304 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:25 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 304 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:25 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 304 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:26 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:37 - 127.0.0.1 "GET /api/v1/devices/test0010/onoff HTTP/1.1 400 69.9026ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:19:41 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.4687ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:32:22 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 116.1631ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:33:20 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 109.6692ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:35:25 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 117.2604ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:38:31 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 103.1939ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:41:25 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 116.5049ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:43:02 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 109.9111ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:44:07 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 104.1896ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:46:00 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 111.3403ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:48:45 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 107.9489ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:49:32 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 113.6651ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 17:55:06 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 110.7404ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 18:18:08 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 123.6243ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 18:21:58 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 105.7457ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 18:31:28 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 117.9846ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 18:42:41 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 112.0142ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-02 18:52:08 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 111.8547ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " diff --git a/runtime/log/success_2025-08-04.log b/runtime/log/success_2025-08-04.log new file mode 100644 index 0000000..1577998 --- /dev/null +++ b/runtime/log/success_2025-08-04.log @@ -0,0 +1,21 @@ +2025-08-04 11:20:23 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0458ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:20:23 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 545.6µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:20:23 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.0304ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:20:23 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.5128ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:20:23 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:20:34 - 127.0.0.1 "GET /api/v1/devices/test002/onoff HTTP/1.1 400 70.8045ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:20:39 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 104.5479ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:28:08 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 112.1495ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:49:14 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 122.1715ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:53:05 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 108.8308ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 11:54:19 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 105.4534ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 12:02:59 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 112.8117ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 13:44:23 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.4547ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 15:35:09 - 127.0.0.1 "GET /api/v1/devices/test0011/onoff HTTP/1.1 400 78.2686ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 15:35:12 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 113.7714ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 15:37:23 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 109.1676ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 15:39:12 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 110.891ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 15:49:38 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 112.2678ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 15:52:26 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 109.8225ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 16:38:59 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 114.4061ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-04 17:23:06 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 102.0925ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " diff --git a/runtime/log/success_2025-08-07.log b/runtime/log/success_2025-08-07.log new file mode 100644 index 0000000..40b0392 --- /dev/null +++ b/runtime/log/success_2025-08-07.log @@ -0,0 +1,20 @@ +2025-08-07 11:33:04 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0496ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:33:04 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.0535ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:33:04 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.5898ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:33:04 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.2544ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:33:04 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:33:10 - 127.0.0.1 "GET /swagger/favicon-32x32.png HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:33:22 - 127.0.0.1 "GET /api/v1/devices/t/onoff HTTP/1.1 400 84.1097ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-07 11:34:09 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 400 0s "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 11:36:10 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 1.5637ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 11:48:21 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 1.04ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 11:55:17 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 1.0318ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 11:59:48 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 1.0328ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 12:00:18 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 608.2µs "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 13:43:26 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 2.0987ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 13:43:41 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 999.6µs "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 14:17:39 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 500 525.1µs "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 14:19:25 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 500 0s "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 14:30:39 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 500 70.0139ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 14:48:19 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 500 69.4181ms "PostmanRuntime-ApipostRuntime/1.1.0" " +2025-08-07 15:14:02 - 127.0.0.1 "GET /api/v1/devices/tdengine/test HTTP/1.1 200 111.1398ms "PostmanRuntime-ApipostRuntime/1.1.0" " diff --git a/runtime/log/success_2025-08-08.log b/runtime/log/success_2025-08-08.log new file mode 100644 index 0000000..65c7d15 --- /dev/null +++ b/runtime/log/success_2025-08-08.log @@ -0,0 +1,22 @@ +2025-08-08 15:38:24 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 1.0571ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:38:24 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 527.4µs "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:38:24 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.3394ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:38:24 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 4.7699ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:38:24 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:38:59 - 127.0.0.1 "GET /api/v1/devices/test0010/onoff HTTP/1.1 400 72.4429ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:39:05 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 400 70.7438ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:39:36 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 104.0549ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 15:59:16 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 112.2301ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 16:19:13 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.9259ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 16:21:14 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 107.4204ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 16:23:51 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 107.17ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 16:25:40 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 108.815ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 16:27:43 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 108.3744ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 16:29:24 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 108.4883ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 17:32:58 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 110.1685ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 18:13:45 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 106.1567ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 18:19:27 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 105.6406ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 18:29:50 - 127.0.0.1 "GET /api/v1/devices/test0010/onoff HTTP/1.1 400 76.495ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 18:29:57 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 400 70.7311ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 18:29:59 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 400 69.6559ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " +2025-08-08 18:30:45 - 127.0.0.1 "GET /api/v1/devices/test001/onoff HTTP/1.1 200 104.4584ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" " diff --git a/service/deviceService.go b/service/deviceService.go new file mode 100644 index 0000000..0bbdcfd --- /dev/null +++ b/service/deviceService.go @@ -0,0 +1,45 @@ +package service + +import ( + "fmt" + "iot-mqtt-gin/config" + "iot-mqtt-gin/dao" + "iot-mqtt-gin/models" + "time" +) + +// InsertDeviceData 插入设备数据 +func InsertDeviceData(data *models.DeviceData) error { + db, err := dao.GetDB() + if err != nil { + return err + } + // 如果未提供时间戳,使用当前时间 + if data.Timestamp.IsZero() { + data.Timestamp = time.Now() + } + + // 表名规则:使用设备ID作为子表名 + tableName := "t" + + // 插入数据 + insertSQL := fmt.Sprintf(` + INSERT INTO %s (%s, %s, %s) VALUES ('%s', %v, %v)`, + tableName, + config.FieldTimestamp, + config.FieldValue, + config.FieldStatus, + data.Timestamp.Format("2006-01-02 15:04:05"), // 注意这里添加了单引号 + data.Value, + data.Status, + ) + + fmt.Println("插入sql语句", insertSQL) + _, err = db.Exec(insertSQL) + + if err != nil { + return fmt.Errorf("插入数据失败: %v", err) + } + + return nil +} diff --git a/service/mq_service.go b/service/mq_service.go new file mode 100644 index 0000000..ebeab98 --- /dev/null +++ b/service/mq_service.go @@ -0,0 +1,153 @@ +package service + +import ( + "context" + "fmt" + "log" + + mqsd "github.com/yyboo586/MQSDK" + "iot-mqtt-gin/config" + "iot-mqtt-gin/models" +) + +// MQService 消息队列服务 +type MQService struct { + factory *mqsd.Factory + nsqConsumer mqsd.Consumer + kafkaConsumer mqsd.Consumer + rabbitConsumer mqsd.Consumer +} + +// NewMQService 创建消息队列服务 +func NewMQService() *MQService { + return &MQService{ + factory: mqsd.NewFactory(), + } +} + +// InitProducers 初始化生产者 +func (s *MQService) InitProducers() ( + nsqProducer mqsd.Producer, + kafkaProducer mqsd.Producer, + rabbitProducer mqsd.Producer, + err error, +) { + // 初始化NSQ生产者 + nsqProducer, err = s.factory.NewProducer(config.GetNSQConfig()) + if err != nil { + return nil, nil, nil, fmt.Errorf("初始化NSQ生产者失败: %w", err) + } + + // 初始化Kafka生产者 + /*kafkaProducer, err = s.factory.NewProducer(config.GetKafkaConfig()) + if err != nil { + nsqProducer.Close() + return nil, nil, nil, fmt.Errorf("初始化Kafka生产者失败: %w", err) + } + + // 初始化RabbitMQ生产者 + rabbitProducer, err = s.factory.NewProducer(config.GetRabbitMQConfig()) + if err != nil { + nsqProducer.Close() + kafkaProducer.Close() + return nil, nil, nil, fmt.Errorf("初始化RabbitMQ生产者失败: %w", err) + }*/ + + //return nsqProducer, kafkaProducer, rabbitProducer, nil + return nsqProducer, nil, nil, nil +} + +// InitConsumers 初始化消费者 +func (s *MQService) InitConsumers() error { + var err error + + // 初始化NSQ消费者 + s.nsqConsumer, err = s.factory.NewConsumer(config.GetNSQConfig()) + if err != nil { + return fmt.Errorf("初始化NSQ消费者失败: %w", err) + } + + // 初始化Kafka消费者 + s.kafkaConsumer, err = s.factory.NewConsumer(config.GetKafkaConfig()) + if err != nil { + s.nsqConsumer.Close() + return fmt.Errorf("初始化Kafka消费者失败: %w", err) + } + + // 初始化RabbitMQ消费者 + s.rabbitConsumer, err = s.factory.NewConsumer(config.GetRabbitMQConfig()) + if err != nil { + s.nsqConsumer.Close() + s.kafkaConsumer.Close() + return fmt.Errorf("初始化RabbitMQ消费者失败: %w", err) + } + + return nil +} + +// StartConsuming 开始消费消息 +func (s *MQService) StartConsuming() { + // 启动NSQ消费 + go func() { + if err := s.nsqConsumer.Subscribe(context.Background(), "test-topic", handleNSQMessage); err != nil { + log.Printf("NSQ消费失败: %v", err) + } + }() + + // 启动Kafka消费 + go func() { + if err := s.kafkaConsumer.Subscribe(context.Background(), "test-topic", handleKafkaMessage); err != nil { + log.Printf("Kafka消费失败: %v", err) + } + }() + + // 启动RabbitMQ消费 + go func() { + if err := s.rabbitConsumer.Subscribe(context.Background(), "test-topic", handleRabbitMessage); err != nil { + log.Printf("RabbitMQ消费失败: %v", err) + } + }() + + log.Println("所有消费者已启动") +} + +// Close 关闭所有连接 +func (s *MQService) Close() { + if s.nsqConsumer != nil { + s.nsqConsumer.Close() + } + if s.kafkaConsumer != nil { + s.kafkaConsumer.Close() + } + if s.rabbitConsumer != nil { + s.rabbitConsumer.Close() + } + log.Println("所有MQ连接已关闭") +} + +// 处理NSQ消息 +func handleNSQMessage(msg *mqsd.Message) error { + message := models.FromMQSDMessage(msg) + log.Printf("[NSQ] 收到消息 - ID: %s, Topic: %s, Content: %s", + message.ID, message.Topic, message.Body) + // 这里添加消息处理逻辑 + return nil +} + +// 处理Kafka消息 +func handleKafkaMessage(msg *mqsd.Message) error { + message := models.FromMQSDMessage(msg) + log.Printf("[Kafka] 收到消息 - ID: %s, Topic: %s, Content: %s", + message.ID, message.Topic, message.Body) + // 这里添加消息处理逻辑 + return nil +} + +// 处理RabbitMQ消息 +func handleRabbitMessage(msg *mqsd.Message) error { + message := models.FromMQSDMessage(msg) + log.Printf("[RabbitMQ] 收到消息 - ID: %s, Topic: %s, Content: %s", + message.ID, message.Topic, message.Body) + // 这里添加消息处理逻辑 + return nil +}