[TOC]html
首先同步下项目概况:git
上篇文章分享了,路由中间件 - 日志记录,这篇文章我们分享:路由中间件 - 捕获异常。当系统发生异常时,提示 “系统异常,请联系管理员!”,同时并发送 panic 告警邮件。github
在 Go 中异常就是 panic,它是在程序运行的时候抛出的,当 panic 抛出以后,若是在程序里没有添加任何保护措施的话,控制台就会在打印出 panic 的详细状况,而后终止运行。api
咱们能够将 panic 分为两种:并发
一种是有意抛出的,好比,异步
panic("自定义的 panic 信息")
输出:函数
2019/09/10 20:25:27 http: panic serving [::1]:61547: 自定义的 panic 信息 goroutine 8 [running]: ...
一种是无心抛出的,写程序马虎形成,好比,测试
var slice = [] int {1, 2, 3, 4, 5} slice[6] = 6
输出:spa
2019/09/10 15:27:05 http: panic serving [::1]:61616: runtime error: index out of range goroutine 6 [running]: ...
想象一下,若是在线上环境出现了 panic,命令行输出的,由于我们没法捕获就没法定位问题呀,想一想均可怕,那么问题来了,怎么捕获异常?命令行
当程序发生 panic 后,在 defer(延迟函数) 内部能够调用 recover 进行捕获。
很少说,直接上代码:
defer func() { if err := recover(); err != nil { fmt.Println(err) } }()
在运行一下 “无心抛出的 panic ”,输出:
runtime error: index out of range
OK,错误捕获到了,这时咱们能够进行作文章了。
作啥文章,你们应该都知道了吧:
那么,Go 怎么发邮件呀,有没有开源包呀?
固然有,请往下看。
使用包:gopkg.in/gomail.v2
直接上代码:
func SendMail(mailTo string, subject string, body string) error { if config.ErrorNotifyOpen != 1 { return nil } m := gomail.NewMessage() //设置发件人 m.SetHeader("From", config.SystemEmailUser) //设置发送给多个用户 mailArrTo := strings.Split(mailTo, ",") m.SetHeader("To", mailArrTo...) //设置邮件主题 m.SetHeader("Subject", subject) //设置邮件正文 m.SetBody("text/html", body) d := gomail.NewDialer(config.SystemEmailHost, config.SystemEmailPort, config.SystemEmailUser, config.SystemEmailPass) err := d.DialAndSend(m) if err != nil { fmt.Println(err) } return err }
在这块我加了一个开关,想开想关,您随意。
如今会发送邮件了,再整个邮件模板就完美了。
如图:
这就是告警邮件的模板,还不错吧,你们还想记录什么,能够自定义去修改。
最后,封装一下。
直接上代码:
func SetUp() gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err := recover(); err != nil { DebugStack := "" for _, v := range strings.Split(string(debug.Stack()), "\n") { DebugStack += v + "<br>" } subject := fmt.Sprintf("【重要错误】%s 项目出错了!", config.AppName) body := strings.ReplaceAll(MailTemplate, "{ErrorMsg}", fmt.Sprintf("%s", err)) body = strings.ReplaceAll(body, "{RequestTime}", util.GetCurrentDate()) body = strings.ReplaceAll(body, "{RequestURL}", c.Request.Method + " " + c.Request.Host + c.Request.RequestURI) body = strings.ReplaceAll(body, "{RequestUA}", c.Request.UserAgent()) body = strings.ReplaceAll(body, "{RequestIP}", c.ClientIP()) body = strings.ReplaceAll(body, "{DebugStack}", DebugStack) _ = util.SendMail(config.ErrorNotifyUser, subject, body) utilGin := util.Gin{Ctx: c} utilGin.Response(500, "系统异常,请联系管理员!", nil) } }() c.Next() } }
当发生 panic 异常时,输出:
{ "code": 500, "msg": "系统异常,请联系管理员!", "data": null }
同时,还会收到一封 panic 告警邮件。
便于截图,DebugStack 删减了一些信息。
到这,就结束了。
https://github.com/xinliangnote/go-gin-api
原文出处:https://www.cnblogs.com/xinliangcoder/p/11505645.html