From 28fe74161d5de1133e94767592cc01fa9a648ff7 Mon Sep 17 00:00:00 2001 From: liyp Date: Sat, 17 Aug 2024 19:37:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0logrus=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=B9=B6=E4=BC=98=E5=8C=96=E9=85=8D=E7=BD=AE=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.go | 54 ++++++++++--------- go.mod | 1 + go.sum | 3 ++ main.go | 132 ++++++++++++++++++++++++++--------------------- 4 files changed, 106 insertions(+), 84 deletions(-) diff --git a/config/config.go b/config/config.go index 148358d..be15b14 100644 --- a/config/config.go +++ b/config/config.go @@ -11,50 +11,54 @@ import ( var ( config map[string]interface{} - mu sync.Mutex + mu sync.RWMutex + once sync.Once ) -func loadConfig() { - // mu.Lock() - // defer mu.Unlock() - - if _, err := toml.DecodeFile("config.toml", &config); err != nil { - panic(err) - } - +// loadConfig 加载配置文件 +func loadConfig() error { + _, err := toml.DecodeFile("config.toml", &config) + return err } + +// GetConfig 获取配置,使用 sync.Once 确保只加载一次 func GetConfig() map[string]interface{} { - mu.Lock() - defer mu.Unlock() - // print(config) - if config == nil { - loadConfig() - } + once.Do(func() { + mu.Lock() + defer mu.Unlock() + if err := loadConfig(); err != nil { + fmt.Printf("加载配置文件失败: %v\n", err) + os.Exit(1) + } + }) return config } -func ReloadConfig() { - loadConfig() + +// ReloadConfig 重新加载配置文件 +func ReloadConfig() error { + mu.Lock() + defer mu.Unlock() + return loadConfig() } -func ModifyConfig(key string, value interface{}) { + +// ModifyConfig 修改配置并写回文件 +func ModifyConfig(key string, value interface{}) error { mu.Lock() defer mu.Unlock() - // 修改配置 config[key] = value - // fmt.Println("修改后的配置:") - // 将修改后的配置写回文件 + file, err := os.Create("config.toml") if err != nil { - panic(err) + return err } defer file.Close() encoder := toml.NewEncoder(file) - if err := encoder.Encode(config); err != nil { - panic(err) - } + return encoder.Encode(config) } +// PrintConfig 递归打印配置内容 func PrintConfig(m map[string]interface{}, indent string) { for key, value := range m { switch v := value.(type) { diff --git a/go.mod b/go.mod index 01074d2..94e01ab 100644 --- a/go.mod +++ b/go.mod @@ -45,6 +45,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/moul/http2curl v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/sirupsen/logrus v1.9.3 github.com/smartystreets/goconvey v1.8.1 // indirect golang.org/x/net v0.26.0 // indirect ) diff --git a/go.sum b/go.sum index 5133e0d..7d51c1a 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= @@ -115,6 +117,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h 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= diff --git a/main.go b/main.go index 09184df..2f34735 100644 --- a/main.go +++ b/main.go @@ -2,10 +2,8 @@ package main import ( "database/sql" - "fmt" "go-bot/config" "go-bot/utils" - "log" "net" "net/http" "strings" @@ -13,15 +11,54 @@ import ( "github.com/gin-gonic/gin" _ "github.com/mattn/go-sqlite3" + "github.com/sirupsen/logrus" ) -func insertMessage(db *sql.DB, data map[string]interface{}) error { +type App struct { + DB *sql.DB + Logger *logrus.Logger +} + +func NewApp() (*App, error) { + db, err := sql.Open("sqlite3", "./data.db") + if err != nil { + return nil, err + } + + logger := logrus.New() + + return &App{ + DB: db, + Logger: logger, + }, nil +} + +func (app *App) initDB() error { + + _, err := app.DB.Exec(`CREATE TABLE IF NOT EXISTS messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + post_type TEXT, + message_type TEXT, + time DATETIME, + group_id INTEGER, + message_id INTEGER UNIQUE NOT NULL, + raw_message TEXT, + sender_user_id INTEGER, + sender_nickname TEXT, + sender_card TEXT, + sender_role TEXT, + message_seq INTEGER + )`) + return err +} + +func (app *App) insertMessage(data map[string]interface{}) error { if data["post_type"] == "message" || data["post_type"] == "message_sent" { post_type := data["post_type"].(string) message_type := data["message_type"].(string) loc, err := time.LoadLocation("Asia/Shanghai") if err != nil { - log.Fatal(err) + return err } message_time := (time.Unix(int64(data["time"].(float64)), 0).In(loc)).Format("2006-01-02 15:04:05") group_id := data["group_id"].(float64) @@ -37,32 +74,25 @@ func insertMessage(db *sql.DB, data map[string]interface{}) error { sender_role := sender["role"].(string) message_seq := data["message_seq"].(float64) - fmt.Println("消息类型:", post_type, " 发送时间:", message_time, " 群号:", int64(group_id), " 消息id:", int64(message_id), " 原始消息:", raw_message, " 发送者id:", sender_user_id, " 发送者昵称:", sender_nickname, " 发送者名片:", sender_card, " 发送者角色:", sender_role, " 消息序列:", int64(message_seq)) - _, err = db.Exec("INSERT INTO messages ( post_type, message_type, time, group_id, message_id, raw_message, sender_user_id, sender_nickname, sender_card, sender_role, message_seq) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + app.Logger.Infof("消息类型:%s 发送时间:%s 群号:%d 消息id:%d 原始消息:%s 发送者id:%d 发送者昵称:%s 发送者名片:%s 发送者角色:%s 消息序列:%d", + post_type, message_time, int64(group_id), int64(message_id), raw_message, int64(sender_user_id), sender_nickname, sender_card, sender_role, int64(message_seq)) + + _, err = app.DB.Exec("INSERT INTO messages (post_type, message_type, time, group_id, message_id, raw_message, sender_user_id, sender_nickname, sender_card, sender_role, message_seq) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", post_type, message_type, message_time, group_id, message_id, raw_message, sender_user_id, sender_nickname, sender_card, sender_role, message_seq) - fmt.Println("Data inserted successfully!") + if err != nil { - log.Fatal(err) + return err } } return nil } // handlePost 处理 POST 请求 -func handlePost(c *gin.Context) { - - // 从请求体中读取数据 - // body, err := io.ReadAll(c.Request.Body) - // if err != nil { - // // 请求体数据读取失败 - // c.JSON(http.StatusBadRequest, gin.H{"error": "Error reading request body"}) - // return - // } - // 将 JSON 数据解析为 map 类型 +func handlePost(c *gin.Context, app *App) { var data map[string]interface{} err := c.BindJSON(&data) if err != nil { - c.JSON(400, gin.H{"error": gin.H{ + c.JSON(http.StatusBadRequest, gin.H{"error": gin.H{ "message": "Request must be proper JSON", "type": "invalid_request_error", "param": nil, @@ -71,68 +101,52 @@ func handlePost(c *gin.Context) { return } - // 打开数据库 - db, err := sql.Open("sqlite3", "./data.db") - if err != nil { - // 数据库打开失败 - log.Fatal(err) - } - defer db.Close() - - // 创建表 - _, err = db.Exec(`CREATE TABLE IF NOT EXISTS messages ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - post_type TEXT, - message_type TEXT, - time DATETIME, - group_id INTEGER, - message_id INTEGER UNIQUE NOT NULL, - raw_message TEXT, - sender_user_id INTEGER, - sender_nickname TEXT, - sender_card TEXT, - sender_role TEXT, - message_seq INTEGER - )`) - if err != nil { - // 表创建失败 - log.Fatal(err) - } - // 插入数据 - err = insertMessage(db, data) + err = app.insertMessage(data) if err != nil { - // 数据插入失败 - log.Fatal(err) + app.Logger.Error("Failed to insert message: ", err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to insert message"}) + return } // 调用路由处理函数 if data["post_type"] == "message" || data["post_type"] == "message_sent" { utils.Router(data) - c.JSON(http.StatusOK, gin.H{"message": data}) + // c.JSON(http.StatusOK, gin.H{"message": data}) } } func main() { + // 使用自定义 Logger 处理 App 初始化中的错误 + app, err := NewApp() + if err != nil { + logrus.Fatalf("Failed to initialize app: %v", err) + } cfg := config.GetConfig() APIURL, ok := cfg["APIURL"].(string) if !ok { - log.Fatal("加载配置失败!") + logrus.Fatalf("加载配置失败!") } + + // 在 App 初始化后统一使用 app.Logger + if err := app.initDB(); err != nil { + app.Logger.Fatalf("Failed to initialize database: %v", err) + } + gin.SetMode(gin.ReleaseMode) - r := gin.Default() + r.POST("/", func(c *gin.Context) { + handlePost(c, app) + }) - r.POST("/", handlePost) - - fmt.Println("Server listening on", APIURL, "...") + app.Logger.Infof("Server listening on %s...", APIURL) if err := r.Run(APIURL); err != nil { if opError, ok := err.(*net.OpError); ok && opError.Op == "listen" { - log.Fatal("服务器启动失败:端口被占用。") + app.Logger.Fatal("服务器启动失败:端口被占用。") } else if strings.Contains(err.Error(), "address already in use") { - log.Fatal("服务器启动失败:端口被占用。") + app.Logger.Fatal("服务器启动失败:端口被占用。") } else { - log.Fatal("服务器启动失败:", err) + app.Logger.Fatal("服务器启动失败:", err) } } }