当前位置: 首页 > news >正文

网站建设制作方法网站设计昆明

网站建设制作方法,网站设计昆明,常州制作公司网站,微信营销模式gin内置日志组件的使用 前言 在之前我们要使用Gin框架定义路由的时候我们一般会使用Default方法来实现#xff0c;我们来看一下他的实现#xff1a; func Default(opts ...OptionFunc) *Engine {debugPrintWARNINGDefault()engine : New()engine.Use(Logger(), Recovery())…gin内置日志组件的使用 前言 在之前我们要使用Gin框架定义路由的时候我们一般会使用Default方法来实现我们来看一下他的实现 func Default(opts ...OptionFunc) *Engine {debugPrintWARNINGDefault()engine : New()engine.Use(Logger(), Recovery())return engine.With(opts...) }我们可以看到它注册了两个中间件Logger()和Recovery(),而Logger就是我们今天的主角:gin框架自带的日志组件。 输出日志到文件中 package mainimport (fmtgithub.com/gin-gonic/ginioos )func main() {file, err : os.Create(ginlog)if err ! nil {fmt.Println(Create file error! err:, err)}gin.DefaultWriter io.MultiWriter(file)r : gin.Default()r.GET(/, func(c *gin.Context) {c.JSON(200, gin.H{message: Hello World!,})})r.Run() } 运行上面代码我们会发现控制台不再会有相关日志的输出而是打印到了ginlog文件中: [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.[GIN-debug] [WARNING] Running in debug mode. Switch to release mode in production.- using env: export GIN_MODErelease- using code: gin.SetMode(gin.ReleaseMode)[GIN-debug] GET / -- main.main.func1 (3 handlers) [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details. [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080当然我们也可以选择既在控制台输出也在文件内输出 package mainimport (fmtgithub.com/gin-gonic/ginioos )func main() {file, err : os.Create(ginlog)if err ! nil {fmt.Println(Create file error! err:, err)}gin.DefaultWriter io.MultiWriter(file, os.Stdout)r : gin.Default()r.GET(/, func(c *gin.Context) {c.JSON(200, gin.H{message: Hello World!,})})r.Run() } 我们可以看到无论是日志文件ginlog和控制台都实现了对日志的打印 定义日志中的路由格式 当我们运行Gin框架的时候,它会自动打印当前所有被定义的路由比如下面这样的格式: [GIN-debug] GET / -- main.main.func1 (3 handlers)而在Gin框架中它允许我们去自己定义路由的输出格式我们可以自己去定义我们的路由格式: func _Router_print_init() {gin.DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string,nuHandlers int) {fmt.Printf([三玖]: %v %v %v %v \n,httpMethod, absolutePath, handlerName, nuHandlers)} }输出的路由格式是这样的: [三玖]: GET / main.main.func1 3 生产模式与开发模式 在我们程序其实是有两种模式的: debug:开发模式release生产模式 如果我们希望控制台不在显示日志,可以将模式切换到release模式: gin.SetMode(gin.ReleaseMode)r : gin.Default()我们可以看到控制台已不再输出日志信息了。 第三方包logrus日志包的使用 logrus包的安装与基本使用 logrus包的安装 logrus的安装很简单只需要终端输入以下命令即可: go get github.com/sirupsen/logruslogrus包的基本使用 logrus常用方法: logrus.Debug(debug)logrus.Info(info)logrus.Warn(warn)logrus.Error(error)logrus.Println(println)当我们运行该代码的时候会发现打印结果只有四行: 这主要是因为logrus默认的打印等级是info在这个等级之下的不会打印在我们生产环境下一般会要求不打印Warn以下的日志我们可以对打印等级进行调整: logrus.SetLevel(logrus.WarnLevel)再次运行上面的代码运行结果就会有所不同: 我们还可以查看当前的打印等级: fmt.Println(logrus.GetLevel())设置特定字段 如果我们希望某条日志记录的打印中添加某一条特定的字段我们可以使用WithField方法 log1 : logrus.WithField(key1, value1) log1.Info(hello world)通常在一个应用中、或者应用的一部分中都有一些固定的Field。比如我们在处理用户http请求时上下文中所有的日志都会有request_id和user_ip为了避免每次记录日志都要使用log.WithFields(log.Fields{“request_id”: request_id, “user_ip”: user_ip})我们可以创建一个logrus.Entry实例为这个实例设置默认Fields在上下文中使用这个logrus.Entry实例记录日志即可这里我写了一个demo仅做参考 package mainimport (github.com/sirupsen/logrus )type DefaultLogger struct {*logrus.EntrydefaultFields logrus.Fields }func NewDefaultLogger() *DefaultLogger {logger : logrus.New()entry : logrus.NewEntry(logger)return DefaultLogger{Entry: entry,defaultFields: logrus.Fields{},} }func (l *DefaultLogger) WithFields(fields logrus.Fields) *logrus.Entry {allFields : make(logrus.Fields, len(fields))for k, v : range fields {allFields[k] v}return l.Entry.WithFields(allFields) }func (l *DefaultLogger) WithDefaultField() {l.Entry l.Entry.WithFields(l.defaultFields) }func (l *DefaultLogger) Info(msg string) {l.WithDefaultField()l.Entry.Info(msg) }func (l *DefaultLogger) AddDefaultField(key string, value interface{}) {l.defaultFields[key] value }func main() {defaultLogger : NewDefaultLogger()defaultLogger.AddDefaultField(request_id, 123)defaultLogger.AddDefaultField(user_ip, 127.0.0.1)// 使用默认字段记录日志defaultLogger.Info(This is a log message with default fields)// 添加额外字段记录日志defaultLogger.WithFields(logrus.Fields{additional_field: abc,}).Info(This is a log message with additional field)}输出结果为 设置显示样式 虽然日志的打印默认是txt格式的但是我们也可以将格式修改为json格式的 logrus.SetFormatter(logrus.TextFormatter{})将日志输入到文件 package mainimport (github.com/sirupsen/logrusos )func main() {file, err : os.OpenFile(./logrus.log, os.O_CREATE|os.O_WRONLY, 0666)if err ! nil {panic(err)}logrus.SetOutput(file)logrus.Error(error) }我们还可以让控制台和日志文件一起输出: package mainimport (github.com/sirupsen/logrusgolang.org/x/sys/windowsioos )func main() {file, err : os.OpenFile(./logrus.log, os.O_CREATE|os.O_WRONLY|windows.O_APPEND, 0666)if err ! nil {panic(err)}writers : []io.Writer{file,os.Stdout,}lod : io.MultiWriter(writers...)logrus.SetOutput(lod)logrus.Error(error)logrus.Info(info) }显示行号 logrus.SetReportCaller(true)logus的Hook机制 在使用logrus这一第三方包的时候,我们可以基于Hook机制来为logrus添加一些拓展功能。 首先我们先定义Hook结构体: type Hook struct {Levels() []logrus.Level // 返回日志级别Fire(entry *logrus.Entry) error // 日志处理 }我们Hook结构体中一般会有两个成员 Levels:Hook机制起作用的日志级别Fire对应的日志处理方式 这里我们举一个例子如果我们希望将所有Error级别的日志单独拎出来我们可以基于Hook机制来实现: package mainimport (fmtgithub.com/sirupsen/logrusos )type Hook struct {Writer *os.File }func (MyHook *Hook) Fire(entry *logrus.Entry) error {line, err : entry.String()if err ! nil {fmt.Fprintf(os.Stderr, Failed to write to log, %v\n, err)}MyHook.Writer.Write([]byte(line))return nil }func (MyHook *Hook) Levels() []logrus.Level {return []logrus.Level{logrus.ErrorLevel,} }func main() {logrus.SetFormatter(logrus.TextFormatter{ForceColors: true, TimestampFormat: 2006-01-02 15:04:05, FullTimestamp: true})logrus.SetReportCaller(true)file, _ : os.OpenFile(./error.log, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)hook : Hook{Writer: file}logrus.AddHook(hook)logrus.Error(error) }日志分割 按时间分割 Write写法 package mainimport (fmtgithub.com/sirupsen/logrusioospath/filepathstringstime )type LogFormatter struct{}// Format 格式详情 func (s *LogFormatter) Format(entry *logrus.Entry) ([]byte, error) {timestamp : time.Now().Local().Format(2006-01-02 15:04:05)var file stringvar len intif entry.Caller ! nil {file filepath.Base(entry.Caller.File)len entry.Caller.Line}//fmt.Println(entry.Data)msg : fmt.Sprintf([%s] %s [%s:%d] %s\n, strings.ToUpper(entry.Level.String()), timestamp, file, len, entry.Message)return []byte(msg), nil }type LogWriter struct {Writer *os.FilelogPath stringfileDate string //判断是否需要切换日志文件fileName string //日志文件名 }func (writer *LogWriter) Write(p []byte) (n int, err error) {if writer nil {logrus.Error(writer is nil)return 0, nil}if writer.Writer nil {logrus.Error(writer.Writer is nil)return 0, nil}timer : time.Now().Format(2006-01-02 04:12)//需要切换日志文件if writer.fileDate ! timer {writer.fileDate timerwriter.Writer.Close()err os.MkdirAll(writer.logPath, os.ModePerm)if err ! nil {logrus.Error(err)return 0, nil}filename : fmt.Sprintf(%s/%s.log, writer.logPath, writer.fileDate)writer.Writer, err os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)if err ! nil {logrus.Error(err)return 0, nil}}return writer.Writer.Write(p) }func Initing(logPath string, fileName string) {fileDate : time.Now().Format(20060102)filepath : fmt.Sprintf(%s/%s, logPath, fileDate)err : os.MkdirAll(filepath, os.ModePerm)if err ! nil {logrus.Error(err)return}filename : fmt.Sprintf(%s/%s.log, filepath, fileName)writer, err : os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)if err ! nil {logrus.Error(err)return}Logwriter : LogWriter{logPath: logPath, fileDate: fileDate, fileName: fileName, Writer: writer}logrus.SetOutput(os.Stdout)writers : []io.Writer{Logwriter.Writer,os.Stdout,}multiWriter : io.MultiWriter(writers...)logrus.SetOutput(multiWriter)logrus.SetReportCaller(true)logrus.SetFormatter(new(LogFormatter)) }func main() {Initing(./, fengxu)logrus.Warn(fengxu)logrus.Error(fengxu)logrus.Info(fengxu)}Hook写法 package mainimport (fmtgithub.com/sirupsen/logrusostime )type Hook struct {writer *os.FilelogPath stringfileName stringfileDate string }func (MyHook *Hook) Levels() []logrus.Level {return logrus.AllLevels }func (MyHook *Hook) Fire(entry *logrus.Entry) error {timer : time.Now().Format(2006-01-02)line, _ : entry.String()//需要切换日志文件if MyHook.fileDate ! timer {MyHook.fileDate timerMyHook.writer.Close()filepath : fmt.Sprintf(%s/%s, MyHook.logPath, MyHook.fileDate)err : os.MkdirAll(filepath, os.ModePerm)if err ! nil {logrus.Error(err)return err}filename : fmt.Sprintf(%s/%s.log, filepath, MyHook.fileName)MyHook.writer, _ os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)}MyHook.writer.Write([]byte(line))return nil }func InitFile(logPath string, fileName string) {timer : time.Now().Format(2006-01-02)filepath : fmt.Sprintf(%s/%s, logPath, timer)err : os.MkdirAll(filepath, os.ModePerm)if err ! nil {logrus.Error(err)return}filename : fmt.Sprintf(%s/%s.log, filepath, fileName)writer, err : os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)if err ! nil {logrus.Error(err)return}logrus.AddHook(Hook{writer: writer,logPath: logPath,fileName: fileName,fileDate: timer,}) }func main() {InitFile(./log, fengxu)logrus.Error(test)} 按日志等级分割 package mainimport (fmtgithub.com/sirupsen/logrusos )const (alllog allerrorlog errorwarnlog warn )type Hook struct {allLevel *os.FileerrorLevel *os.FilewarnLevel *os.File }func (MyHook *Hook) Levels() []logrus.Level {return logrus.AllLevels }func (MyHook *Hook) Fire(entry *logrus.Entry) error {line, _ : entry.String()switch entry.Level {case logrus.ErrorLevel:MyHook.errorLevel.Write([]byte(line))case logrus.WarnLevel:MyHook.warnLevel.Write([]byte(line))}MyHook.allLevel.Write([]byte(line))return nil }func InitLevel(logPath string) {err : os.MkdirAll(logPath, os.ModePerm)if err ! nil {logrus.Error(创建目录失败)return}allFile, err : os.OpenFile((fmt.Sprintf(%s/%s, logPath, alllog)), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0600)errFile, err : os.OpenFile((fmt.Sprintf(%s/%s, logPath, errorlog)), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0600)warnFile, err : os.OpenFile((fmt.Sprintf(%s/%s, logPath, warnlog)), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0600)logrus.AddHook(Hook{allLevel: allFile, errorLevel: errFile, warnLevel: warnFile}) }func main() {InitLevel(./log)logrus.SetReportCaller(true)logrus.Errorln(你好)logrus.Errorln(err)logrus.Warnln(warn)logrus.Infof(info)logrus.Println(print)}gin集成logrus main函数(main.go) package mainimport (gin/Logger/gin/gin_logrus/loggin/Logger/gin/gin_logrus/middlewaregithub.com/gin-gonic/gin )func main() {log.InitFile(./log, fengxu)r : gin.New()r.Use(middleware.Logmiddleware())r.GET(/, func(c *gin.Context) {c.JSON(200, gin.H{message: pong,})})r.Run(:8080) } log.go’ package logimport (bytesfmtgithub.com/sirupsen/logrusostime )type Hook struct {writer *os.FilelogPath stringfileName stringfileDate string }func (MyHook *Hook) Levels() []logrus.Level {return logrus.AllLevels }func (MyHook *Hook) Fire(entry *logrus.Entry) error {timer : time.Now().Format(2006-01-02)line, _ : entry.String()//需要切换日志文件if MyHook.fileDate ! timer {MyHook.fileDate timerMyHook.writer.Close()filepath : fmt.Sprintf(%s/%s, MyHook.logPath, MyHook.fileDate)err : os.MkdirAll(filepath, os.ModePerm)if err ! nil {logrus.Error(err)return err}filename : fmt.Sprintf(%s/%s.log, filepath, MyHook.fileName)MyHook.writer, _ os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)}MyHook.writer.Write([]byte(line))return nil }type LogFormat struct { }func (l *LogFormat) Format(entry *logrus.Entry) ([]byte, error) {var buff *bytes.Bufferif entry.Buffer ! nil {buff entry.Buffer} else {buff bytes.Buffer{}}_, _ fmt.Fprintf(buff, %s\n, entry.Message) //这里可以自己去设置输出格式return buff.Bytes(), nil }func InitFile(logPath string, fileName string) {logrus.SetFormatter(LogFormat{})timer : time.Now().Format(2006-01-02)filepath : fmt.Sprintf(%s/%s, logPath, timer)err : os.MkdirAll(filepath, os.ModePerm)if err ! nil {logrus.Error(err)return}filename : fmt.Sprintf(%s/%s.log, filepath, fileName)writer, err : os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)if err ! nil {logrus.Error(err)return}logrus.AddHook(Hook{writer: writer,logPath: logPath,fileName: fileName,fileDate: timer,}) } 中间件(lmiddleware.go) package middlewareimport (github.com/gin-gonic/gingithub.com/sirupsen/logrustime )const ( //自定义状态码和方法的显示颜色status200 42status404 43status500 41methodGET 44 )func Logmiddleware() gin.HandlerFunc {return func(c *gin.Context) {start : time.Now()path : c.Request.URL.Pathraw : c.Request.URL.RawQueryif raw ! {path path ? raw}c.Next() //执行其他中间件//end : time.Now()//timesub : end.Sub(start) //响应所需时间//ClientIp : c.ClientIP() //客户端ipstatuscode : c.Writer.Status()//var statusColor string //switch c.Writer.Status() {//case 200:// statusColor fmt.Sprintf(\033[%dm%d\033[0m, status200, statuscode)//case 404:// statusColor fmt.Sprintf(\033[%dm%d\033[0m, status404, statuscode)//default:// statusColor fmt.Sprintf(\033[%dm%d\033[0m, status500, statuscode)//}////var methodColor string//switch c.Request.Method {//case GET:// methodColor fmt.Sprintf(\033[%dm%s\033[0m, methodGET, c.Request.Method)//}logrus.Infof([GIN] %s |%d |%s |%s,start.Format(2006-01-02 15:04:06),statuscode,c.Request.Method,path,)} }项目结构: 结语 至此我们对Gin框架的简单学习就到此为止了更多的学习大家可以前去查看Gin框架官方文档: Gin框架官方文档 后面就要开始对Gorm的学习了下篇见
http://www.zqtcl.cn/news/502709/

相关文章:

  • 设计一个自己的电商网站中国建设银行官网首页登录
  • 肇庆自助网站建设系统南通网站建设项目
  • 道农网站建设工作网站开发制作
  • 网页游戏网站快手wordpress hppts
  • 男男做h的视频网站德邦公司网站建设特点
  • 嘉兴市建设教育网站html5从入门到精通
  • 双语言网站源码在哪个网站可以找到做国珍的人
  • 广州建设网站哪家好烟台网站建设地址
  • 网址注册了怎么做网站wordpress截取标题
  • 网站备案一个主体龙岩网站建设行情
  • 深圳做网站的公司烟台网站开发技术
  • 网站开发就业前景分析手机网站导航设计
  • 山西焦煤集团公司网站推广公司一般都怎么推广
  • 前端视频教程网站燕郊网站建设哪家好
  • 加强校园网站建设方案做核酸检测收费标准
  • 主机开通成功网站正在建设中中国建设银行登录官网
  • 12306的网站是哪个公司做的wordpress搜索页分类
  • 众筹网站的分析与设计wordpress 主题制作教程
  • 淘宝放单网站怎么做app制作公司哪个好
  • 地税城市维护建设税网站是什么意思订阅号怎么开通小程序
  • 网站添加二级域名wordpress火车头免登录发布
  • 大美工设计网站官网中山网站建设找丁生
  • 做算命网站标准版网站制作
  • 建设网站是普通办公吗温州 网站 公司
  • 哪里做外贸网站汉服网站开发背景
  • 建模外包网站企业代码查询入口
  • wordpress快速仿站视频教程广州知名网站建设哪家好
  • 楼盘网站开发网站服务理念
  • 私人ftp服务器seo整站如何优化
  • 做网站的工作叫什么美工需要会哪些软件