gorm/gin: 传递gin.context给gorm,记录异常发生时的信息

一,安装第三方库:

$ go get -u gorm.io/gorm
go: added github.com/jinzhu/inflection v1.0.0
go: added github.com/jinzhu/now v1.1.5
go: added gorm.io/gorm v1.25.12
$ go get -u gorm.io/driver/mysql
go: added filippo.io/edwards25519 v1.1.0
go: added github.com/go-sql-driver/mysql v1.8.1
go: added gorm.io/driver/mysql v1.5.7

二,代码:

1,global/dblink.go

package globalimport ("fmt""github.com/gin-gonic/gin""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""runtime""runtime/debug""time"
)var (DBLink *gorm.DB
)func SetupDBLink() (error) {var err errordsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=Local","root","rootpassword","127.0.0.1:3306","gysy","utf8",true, )DBLink, err = gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Info),})if err != nil {return err}sqlDB, _ := DBLink.DB()// SetMaxIdleConns 设置空闲连接池中连接的最大数量sqlDB.SetMaxIdleConns(10)// SetMaxOpenConns 设置打开数据库连接的最大数量sqlDB.SetMaxOpenConns(30)// SetConnMaxLifetime 设置了连接可复用的最大时间sqlDB.SetConnMaxLifetime(time.Hour)//"query:before"DBLink.Callback().Create().Register("create:before", func(db *gorm.DB) {fmt.Println("==================create:create======================")c, ok := db.Statement.Context.(*gin.Context)if ok {fmt.Println("转换成功")}url:=c.Request.URL.String()fmt.Println("url:",url)timeStr := time.Now().Format("2006-01-02 15:04:05")fmt.Println("当前时间:", timeStr)fmt.Println("当前访问path:", c.FullPath())fmt.Println("当前完整地址:", c.Request.URL.String())fmt.Println("当前协议:", c.Request.Proto)fmt.Println("当前get参数:",GetAllGetParams(c))fmt.Println("当前post参数:",GetAllPostParams(c))fmt.Println("当前访问方法:", c.Request.Method)fmt.Println("当前访问Host:", c.Request.Host)fmt.Println("当前IP:",c.ClientIP())fmt.Println("当前浏览器:",c.Request.UserAgent())if db.Error == nil { // 只打印成功的查询//db.Statement.SQL.sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)} else {var pc [1]uintptrruntime.Callers(4, pc[:]) // 获取调用者的位置,4 表示跳过 logError 和当前函数本身f := runtime.FuncForPC(pc[0])file, line := f.FileLine(pc[0])fmt.Printf("Error at %s:%d - %v\n", file, line, db.Error)sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)fmt.Println("dblink中:查询前发生错误:",db.Error)fmt.Println("dblink:stack打印开始")fmt.Println(string(debug.Stack()))fmt.Println("dblink:stack打印结束")}})DBLink.Callback().Query().Register("query:before", func(db *gorm.DB) {fmt.Println("==================query:before======================")c, ok := db.Statement.Context.(*gin.Context)if ok {fmt.Println("转换成功")}url:=c.Request.URL.String()fmt.Println("url:",url)timeStr := time.Now().Format("2006-01-02 15:04:05")fmt.Println("当前时间:", timeStr)fmt.Println("当前访问path:", c.FullPath())fmt.Println("当前完整地址:", c.Request.URL.String())fmt.Println("当前协议:", c.Request.Proto)fmt.Println("当前get参数:",GetAllGetParams(c))fmt.Println("当前post参数:",GetAllPostParams(c))fmt.Println("当前访问方法:", c.Request.Method)fmt.Println("当前访问Host:", c.Request.Host)fmt.Println("当前IP:",c.ClientIP())fmt.Println("当前浏览器:",c.Request.UserAgent())fmt.Println("报错:",db.Error)if db.Error == nil { // 只打印成功的查询//db.Statement.SQL.sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)} else {var pc [1]uintptrruntime.Callers(4, pc[:]) // 获取调用者的位置,4 表示跳过 logError 和当前函数本身f := runtime.FuncForPC(pc[0])file, line := f.FileLine(pc[0])fmt.Printf("Error at %s:%d - %v\n", file, line, db.Error)sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)fmt.Println("dblink中:查询前发生错误:",db.Error)fmt.Println("dblink:stack打印开始")fmt.Println(string(debug.Stack()))fmt.Println("dblink:stack打印结束")}})DBLink.Callback().Update().Register("update:before", func(db *gorm.DB) {fmt.Println("==================update:before======================")c, ok := db.Statement.Context.(*gin.Context)if ok {fmt.Println("转换成功")}url:=c.Request.URL.String()fmt.Println("url:",url)timeStr := time.Now().Format("2006-01-02 15:04:05")fmt.Println("当前时间:", timeStr)fmt.Println("当前访问path:", c.FullPath())fmt.Println("当前完整地址:", c.Request.URL.String())fmt.Println("当前协议:", c.Request.Proto)fmt.Println("当前get参数:",GetAllGetParams(c))fmt.Println("当前post参数:",GetAllPostParams(c))fmt.Println("当前访问方法:", c.Request.Method)fmt.Println("当前访问Host:", c.Request.Host)fmt.Println("当前IP:",c.ClientIP())fmt.Println("当前浏览器:",c.Request.UserAgent())if db.Error == nil { // 只打印成功的查询//db.Statement.SQL.sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)} else {var pc [1]uintptrruntime.Callers(4, pc[:]) // 获取调用者的位置,4 表示跳过 logError 和当前函数本身f := runtime.FuncForPC(pc[0])file, line := f.FileLine(pc[0])fmt.Printf("Error at %s:%d - %v\n", file, line, db.Error)sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)fmt.Println("dblink中:查询前发生错误:",db.Error)fmt.Println("dblink:stack打印开始")fmt.Println(string(debug.Stack()))fmt.Println("dblink:stack打印结束")}})return nil
}

2,service/articleService.go

注意用 withContext传递*gin.Context

package serviceimport ("fmt""github.com/gin-gonic/gin""imagebank/global""imagebank/model"
)
//select一个article
func GetOneArticleById(c *gin.Context,id int) (*model.ArticleModel, error) {fields := []string{"id", "title","demo","content1"}articleOne:=&model.ArticleModel{}err := global.DBLink.WithContext(c).Select(fields).Where("id=?",id).First(&articleOne).Errorif (err != nil) {fmt.Println("service:发生了错误:")fmt.Println(err)return nil,err} else {return articleOne,nil}
}//add一个article
func InsertOneArticle(c *gin.Context,articleOne model.ArticleModel) (uint,error) {result := global.DBLink.WithContext(c).Create(&articleOne)return articleOne.Id,result.Error
}

三,测试效果:

新加一行数据:

转换成功
url: /image/add
当前时间: 2025-02-02 12:32:46
当前访问path: /image/add
当前完整地址: /image/add
当前协议: HTTP/1.1
当前get参数: 
当前post参数: key:cid,value:123
key:title,value:12当前访问方法: POST
当前访问Host: 192.168.219.3:8080
当前IP: 192.168.219.1
当前浏览器: PostmanRuntime/7.43.0
Error at /data/goapp/imagebank/service/articleService.go:28 - Error 1062 (23000): Duplicate entry '1000' for key 'zr_article.PRIMARY'
sql: INSERT INTO `zr_article` (`title`,`demo`,`content`,`id`) VALUES (?,?,?,?)
values: [aaaa bbbb cccc 1000]
dblink中:查询前发生错误: Error 1062 (23000): Duplicate entry '1000' for key 'zr_article.PRIMARY'
dblink:stack打印开始
12:32:46 app         | goroutine 6 [running]:
runtime/debug.Stack()/usr/local/soft/go/src/runtime/debug/stack.go:26 +0x5e
imagebank/global.SetupDBLink.func1(0xc000277ef0)/data/goapp/imagebank/global/dblink.go:82 +0xaab
gorm.io/gorm.(*processor).Execute(0xc0002426e0, 0xc000277b00?)/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/callbacks.go:130 +0x3cb
gorm.io/gorm.(*DB).Create(0xc000162eb8?, {0x983d60, 0xc00024ab80})/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/finisher_api.go:24 +0xa8
imagebank/service.InsertOneArticle(0xc000146600, {0x3e8, {0xa27a30, 0x4}, {0xa27a34, 0x4}, {0xa27a38, 0x4}})/data/goapp/imagebank/service/articleService.go:27 +0xbc
imagebank/controller.(*ImageController).Add(0xc000162fe0?, 0xc000146600)/data/goapp/imagebank/controller/ImageController.go:47 +0x90
github.com/gin-gonic/gin.(*Context).Next(0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185 +0x2b
imagebank/routes.Routes.AccessLog.func2(0xc000146600)/data/goapp/imagebank/middleware/accesslog.go:84 +0x2ba
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
imagebank/routes.Recover(0xc000146600)/data/goapp/imagebank/routes/routes.go:87 +0x5c
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/recovery.go:102 +0x6f
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/logger.go:249 +0xe5
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000a6000, 0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:633 +0x892
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000a6000, {0xb1c030, 0xc00019e1c0}, 0xc0000c4000)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:589 +0x1b2
net/http.serverHandler.ServeHTTP({0xb19f30?}, {0xb1c030?, 0xc00019e1c0?}, 0x6?)/usr/local/soft/go/src/net/http/server.go:3210 +0x8e
net/http.(*conn).serve(0xc0000be000, {0xb1d070, 0xc000096390})/usr/local/soft/go/src/net/http/server.go:2092 +0x5d0
created by net/http.(*Server).Serve in goroutine 1/usr/local/soft/go/src/net/http/server.go:3360 +0x48512:32:46 app         | dblink:stack打印结束

查询数据:

12:29:33 app         | ==================query:before======================
转换成功
url: /image/detail?id=123
当前时间: 2025-02-02 12:29:33
当前访问path: /image/detail
当前完整地址: /image/detail?id=123
当前协议: HTTP/1.1
当前get参数: key:id,value:123当前post参数: 
当前访问方法: GET
当前访问Host: 192.168.219.3:8080
当前IP: 192.168.219.1
当前浏览器: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
报错: Error 1054 (42S22): Unknown column 'content1' in 'field list'
Error at /data/goapp/imagebank/service/articleService.go:14 - Error 1054 (42S22): Unknown column 'content1' in 'field list'
sql: SELECT `id`,`title`,`demo`,content1 FROM `zr_article` WHERE id=? ORDER BY `zr_article`.`id` LIMIT ?
values: [21 1]
dblink中:查询前发生错误: Error 1054 (42S22): Unknown column 'content1' in 'field list'
dblink:stack打印开始
12:29:33 app         | goroutine 5 [running]:
runtime/debug.Stack()/usr/local/soft/go/src/runtime/debug/stack.go:26 +0x5e
imagebank/global.SetupDBLink.func1(0xc0000942d0)/data/goapp/imagebank/global/dblink.go:124 +0xb2b
gorm.io/gorm.(*processor).Execute(0xc000242730, 0xc000277b00?)/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/callbacks.go:130 +0x3cb
gorm.io/gorm.(*DB).First(0xc000094240?, {0x9608a0, 0xc00005a010}, {0x0, 0x0, 0x0})/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/finisher_api.go:129 +0x1b2
imagebank/service.GetOneArticleById(0xc00009a500, 0x15)/data/goapp/imagebank/service/articleService.go:14 +0x1b1
imagebank/controller.(*ImageController).Detail(0xc00015efe0?, 0xc00009a500)/data/goapp/imagebank/controller/ImageController.go:79 +0x27
github.com/gin-gonic/gin.(*Context).Next(0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185 +0x2b
imagebank/routes.Routes.AccessLog.func2(0xc00009a500)/data/goapp/imagebank/middleware/accesslog.go:84 +0x2ba
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
imagebank/routes.Recover(0xc00009a500)/data/goapp/imagebank/routes/routes.go:87 +0x5c
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/recovery.go:102 +0x6f
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/logger.go:249 +0xe5
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000167040, 0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:633 +0x892
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000167040, {0xb1bb90, 0xc0000b0000}, 0xc00009e000)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:589 +0x1b2
net/http.serverHandler.ServeHTTP({0xc0000940c0?}, {0xb1bb90?, 0xc0000b0000?}, 0x6?)/usr/local/soft/go/src/net/http/server.go:3210 +0x8e
net/http.(*conn).serve(0xc000096000, {0xb1cbd0, 0xc0002d6120})/usr/local/soft/go/src/net/http/server.go:2092 +0x5d0
created by net/http.(*Server).Serve in goroutine 1/usr/local/soft/go/src/net/http/server.go:3360 +0x485dblink:stack打印结束

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/877972.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lazarus4Android 环境搭建

Lazarus4Android 开发环境搭建Lazarus4Android 开发环境搭建 一、下载相关文件最关键的就是这两个文件,其他的JDK、NDK、Java环境另说。 这里要注意,gradle版本必须小于7,不然无法使用。 二、IDE内部设置 安装完成laz4A之后可能会报错,无需理会,启动IDE即可。安装卸载软件…

14-断点调试单个用例

在pycharm的Terminal输入hytest,其实是输入了python -m hytest.run,意思就是执行了hytest包里面的run.py文件 然后再点击debug按钮的时候就可以进行调试了,相当于执行了cd H:\my\autotest后 python.exe -m hytest.run --test *0101

博图18安装过程记录

博图V18安装过程记录刚开通博客园,搬运一些之前的帖子过来。 博图18安装过程记录 下载 西门子中智赛官网给的链接,是正版软件。 安装 TIA Potral STEP7将ISO解压或装载。管理员身份运行。 选择典型安装,等待安装完成。 插曲1 无法更改安装路径 这是因为之前安装过博图15.1(或…

题解:P11617 递推

前言 第一次在 OI 中见到求数列极限的题,有点意思。 但是为什么会过这么多人啊。 思路分析 做一点尝试: \[\sum_{i=m} \sum_{j=0}^{m} r_ja_{i-j}=0 \]然后对于相同的 \(a_i\),合并同类项: \[\sum_{i=m}\sum_{j=0}^{m} r_ja_i + \sum_{i=0}^{m-1}\sum_{j=0}^{i} r_{m-j}a_i…

AI编程助手带来的洞察和启发——程序员职业的变革

前言 从chatgpt的横空出世到国内大模型的强势崛起, 从AI只会写诗作画到辅助编程, AI作为新质生产力的重要角色逐渐进入各行各业,为行业带来新的可能性。Cursor、通义灵码这类"AI程序员"的出现一方面给编码工作带来了便利,另一方面也对软件从业人员带来极大的冲击…

个人数据保全计划:部署joplin server笔记同步服务

前言 在这个数据爆炸的时代,个人数据的价值愈发凸显,成为我们生活与工作中无可替代的重要资产。上一篇文章里,我介绍了从印象笔记迁移至 Joplin 的过程,这是我寻求数据自主掌控的关键一步。在探索同步方案时,我尝试了 OneDrive,原以为它能提供稳定高效的同步服务,可实际…

【deepseek】在deepin系统上部署运行deepseek-r1

环境配置LM-Studio官网:https://lmstudio.ai/修改“镜像源”cd /opt/apps/ai.lmstudio/files/LM_Studio/resources/app/.webpack/main 使用vscode打开进行编辑,./resources/app/.webpack/main/index.js./resources/app/.webpack/main/llmworker.js./resources/app/.webpack/m…

C++ 编译静态链接 (-static)

因为很长一段时间内并不知道这个编译参数究竟是干什么用的,只知道这个参数在 NOI 系列赛事中普遍使用,并且会导致编译输出文件变大,直到碰到具体问题了才发现这个参数的作用 -static 参数是静态链接开关,不加这个参数默认是动态链接,加上这个参数以后是静态链接,先说一下…

https://avoid.overfit.cn/post/e57ca7e30ea74ad380b093a2599c9c01

DeepSeekMoE是一种创新的大规模语言模型架构,通过整合专家混合系统(Mixture of Experts, MoE)、改进的注意力机制和优化的归一化策略,在模型效率与计算能力之间实现了新的平衡。DeepSeekMoE架构融合了专家混合系统(MoE)、多头潜在注意力机制(Multi-Head Latent Attention, ML…

DeepSeekV3+Roo Code,智能编码好助手

前言 硅基流动最近上线了deepseek-ai/DeepSeek-R1与deepseek-ai/DeepSeek-V3,感兴趣快来试试吧! 邀请注册得14元不过期额度:https://cloud.siliconflow.cn/i/Ia3zOSCU。实践 最近VS Code中的自动编程插件Cline很火爆,Roo Code也是Cline的一个fork版本。 Cline 自主编码代理…

Cisco Catalyst 8000V Edge Software, IOS XE Release 17.16.1a ED - 思科虚拟路由器系统软件

Cisco Catalyst 8000V Edge Software, IOS XE Release 17.16.1a ED - 思科虚拟路由器系统软件Cisco Catalyst 8000V Edge Software, IOS XE Release 17.16.1a ED 思科 Catalyst 8000V 边缘软件 - 虚拟路由器 请访问原文链接:https://sysin.org/blog/cisco-catalyst-8000v/ 查看…

Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release 17.16.1a ED - 思科路由器系统软件

Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release 17.16.1a ED - 思科路由器系统软件Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release 17.16.1a ED 思科 Catalyst 8000 边缘平台系列 IOS XE 系统软件 请访问原文链接:https://sysin.org/blog/cisco-cat…