做兼职打字员的网站,网站建设套餐128000,百度上传自己个人简介,计算机程序网站开发是什么一、Log
1.1 logger基本使用
Go语言内置的log包实现了简单的日志服务。本包也提供了一个预定义的“标准”logger#xff0c;可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列#xff08;Fatal|Fatalf|Fatalln)、和Panic系列#xff08;Panic|Panicf|Panicln)来…一、Log
1.1 logger基本使用
Go语言内置的log包实现了简单的日志服务。本包也提供了一个预定义的“标准”logger可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列Fatal|Fatalf|Fatalln)、和Panic系列Panic|Panicf|Panicln)来使用比自行创建一个logger对象更容易使用。
Fatal系列用于输出一条致命错误信息并调用 os.Exit(1) 终止程序运行。这个函数会在打印完错误信息之后立即调用 os.Exit 退出程序。
package mainimport (log
)func main() {log.Println(卡卡西的日志)x : 鸣人log.Printf(%s的日志\n, x)log.Fatalln(会触发fatal的日志)// 这里的代码不会被执行因为程序已经在 log.Fatalln 后退出了log.Panicln(会触发panic的日志)
}2024/05/16 23:03:24 卡卡西的日志
2024/05/16 23:03:24 鸣人的日志
2024/05/16 23:03:24 会触发fatal的日志
exit status 1 1.2 logger配置
基础的logger只提供日志的时间信息如果需要获取更多的信息或者输出方式可以通过进一步配置实现。
1.2.1 标准配置 log.SetFlags.SetFlags
log.SetFlags() 函数用于设置日志的输出格式log.Flags() 函数来获取当前日志包的配置标志并将其打印输出。
以下是 log 包中定义的一些常用选项
log.Ldate日期2009/01/23log.Ltime时间01:23:23log.Lmicroseconds微秒级时间01:23:23.123123log.Llongfile文件名和行号/a/b/c/d.go:23log.Lshortfile文件名和行号d.go:23log.LUTC使用 UTC 时间
下面在记录日志之前先设置一下logger的输出选项
package mainimport (fmtlog
)func main() {log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)log.Println(卡卡西的日志)flags : log.Flags()fmt.Println(Flags:, flags)
}输出结果
2024/05/16 23:25:39.519510 d:/go/练习/main.go:10: 卡卡西的日志
Flags: 131.2.2 前缀配置 log.SetPrefix 和 log.Prefix
log.SetPrefix 用于设置日志输出的前缀它接受一个字符串作为参数这个字符串将会作为日志信息的前缀显示在每条日志的最前面。log.Prefix 则是一个属性用于获取当前日志输出的前缀。
func main() {log.SetPrefix(复制忍者)log.Println(卡卡西)prefix : log.Prefix()fmt.Println(prefix)
}输出结果是
复制忍者2024/05/18 10:06:56 卡卡西
复制忍者 1.2.3 输出位置 log.SetOutput
log.SetOutput 用于设置日志输出的目标。这个函数接受一个 io.Writer 类型的参数将日志输出到指定的 io.Writer 实现。
func main() {file, err : os.OpenFile(logfile.log, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err ! nil {log.Fatal(Failed to open logfile.log, err)}defer file.Close()log.SetOutput(file)log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)log.Println(卡卡西)log.SetPrefix(复制忍者)
}1.3 logger对象创建
log.New 用于创建一个新的 Logger 对象。这个函数接受三个参数一个实现了 io.Writer 接口的目标输出流、一个用于添加前缀的字符串、以及一个用于指定日志属性的标志选项。
func main() {// 创建一个新的 Logger 对象将日志输出到标准错误输出并添加前缀 ERROR: logger : log.New(os.Stderr, ERROR: , log.LstdFlags)// 使用新创建的 Logger 对象输出日志logger.Println(This is an error message.)
}输出结果
ERROR: 2024/05/18 10:27:40 This is an error message.二、第三方日志库 Zap
注意Zap并不是Go的标准库而是为了解决Go内置log库功能有限的问题所引入的第三方日志库。在此处介绍Zap是为了方便与log库进行对比学习。
Zap的优点快、结构化分日志级别。
Zap 日志库提供了两种类型的日志记录器Sugared Logger 和 Logger。它们分别适用于不同的日志记录场景。 Sugared Logger: Sugared Logger 提供了结构化和格式化的日志记录功能支持使用类似 Printf 风格的方法记录日志。它使用了结构化的上下文字段可以方便地记录关键-值对形式的日志信息。Sugared Logger 适合用于一般的日志记录需求提供了更直观、易用的 API。 Logger: Logger 提供了更底层的、零分配zero-allocation的日志记录功能适用于高性能、高吞吐量的日志记录需求。它的 API 相对更加简洁不支持结构化的上下文字段但在性能方面有优势。Logger 适合用于需要尽量减少内存分配和提升性能的场景。
根据具体的需求和场景可以选择使用 Zap 提供的 Sugared Logger 或 Logger 来实现相应的日志记录功能。
2.1 Logger
调用zap.NewProduction()或者zap.NewDevelopment()或者zap.Example()创建了一个 Zap 日志记录器通过Logger调用Info/Error等程序结束前调用 logger.Sync() 来确保所有日志都被输出
zap.NewProduction()会配置 Logger 以适应生产环境的需求例如默认会将日志输出到标准错误输出并且会禁用堆栈跟踪等详细的调试信息以减少对性能的影响。适合用于生产环境中记录稳定运行日志的场景。 zap.NewDevelopment()会配置 Logger 以便于开发过程中更好地跟踪和调试日志例如会输出更详细的调试信息和堆栈跟踪。适合用于开发和调试过程中辅助定位问题、跟踪日志的场景。 zap.Example()是一个示例方法提供了一个简单的例子演示了如何创建 Logger 实例、记录不同级别的日志、以及如何添加结构化的上下文字段等操作。
下面通过简单的http get介绍logger的用法
package mainimport (net/httpgo.uber.org/zap
)var logger *zap.Logger// 初始化日志记录器
func InitLogger() {logger, _ zap.NewProduction()
}// 发送 HTTP GET 请求
func httpGet(url string){resp, err : http.Get(url)if err ! nil {// 如果请求中出现错误记录错误日志logger.Error(Error fetching url: ,zap.String(url,url),zap.Error(err))} else {// 如果请求成功记录成功日志logger.Info(Success: ,zap.String(statusCode, resp.Status),zap.String(url, url))resp.Body.Close()}
}func main() {InitLogger()// 使用了 defer 关键字来延迟执行 logger.Sync()以确保在程序退出前执行同步操作defer logger.Sync()httpGet(https://blog.csdn.net/Ricardo2/article/details/134253323)httpGet(www.google.com)
}输出结果
{level:info,ts:1716001211.442937,caller:练习/main.go:26,msg:Success: ,statusCode:403 Forbidden,url:https://blog.csdn.net/Ricardo2/article/details/134253323}
{level:error,ts:1716001211.443463,caller:练习/main.go:20,msg:Error fetching url: ,url:www.google.com,error:Get \www.google.com\: unsupported protocol scheme \\,stacktrace:main.httpGet\n\td:/go/练习/main.go:20\nmain.main\n\td:/go/练习/main.go:41\nruntime.main\n\tE:/goland/src/runtime/proc.go:250}2.2 SugaredLogger
大部分的实现基本都相同。 惟一的区别是我们通过logger.Sugar()方法来获取一个SugaredLogger。
package mainimport (net/httpgo.uber.org/zap
)var sugarLogger *zap.SugaredLogger// 初始化日志记录器
func InitLogger() {logger, _ : zap.NewProduction()sugarLogger logger.Sugar()
}// 发送 HTTP GET 请求
func httpGet(url string){sugarLogger.Debugf(Trying to grt request for %s, url)resp, err : http.Get(url)if err ! nil {// 如果请求中出现错误记录错误日志sugarLogger.Error(Error fetching url: ,zap.String(url,url),zap.Error(err))} else {// 如果请求成功记录成功日志sugarLogger.Info(Success: ,zap.String(statusCode, resp.Status),zap.String(url, url))resp.Body.Close()}
}func main() {InitLogger()// 使用了 defer 关键字来延迟执行 logger.Sync()以确保在程序退出前执行同步操作defer sugarLogger.Sync()httpGet(https://blog.csdn.net/Ricardo2/article/details/134253323)httpGet(www.google.com)
}输出结果
{level:info,ts:1716001865.691326,caller:练习/main.go:28,msg:Success: {statusCode 15 0 403 Forbidden nil} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 nil}}
{level:error,ts:1716001865.6924412,caller:练习/main.go:22,msg:Error fetching url: {url 15 0 www.google.com nil} {error 26 0 Get \www.google.com\: unsupported protocol scheme \\},stacktrace:main.httpGet\n\td:/go/练习/main.go:22\nmain.main\n\td:/go/练习/main.go:43\nruntime.main\n\tE:/goland/src/runtime/proc.go:250}2.3 日志级别
Zap 日志库支持以下几种日志级别可以根据不同的需求来选择合适的级别记录日志
Debug: 用于记录调试过程中的详细信息通常在开发和调试阶段使用。 使用 logger.Debug() 方法记录 Debug 级别的日志。Info: 用于记录程序运行过程中的一般信息例如启动信息、关键事件等。 使用 logger.Info() 方法记录 Info 级别的日志。Warn: 用于记录可能出现问题但不会影响程序正常运行的警告信息例如参数使用不当、潜在的问题等。 使用 logger.Warn() 方法记录 Warn 级别的日志。Error: 用于记录程序中的错误信息例如异常、错误状态等。 使用 logger.Error() 方法记录 Error 级别的日志。DPanic: 用于记录严重的错误会导致程序进入恐慌状态的错误。 使用 logger.DPanic() 方法记录 DPanic 级别的日志。Panic: 用于记录导致程序无法继续正常运行的错误记录后会触发程序 panic。 使用 logger.Panic() 方法记录 Panic 级别的日志。Fatal: 用于记录导致程序无法继续运行的严重错误记录后会触发程序退出。 使用 logger.Fatal() 方法记录 Fatal 级别的日志。
2.4 Zap配置
2.4.1 标准配置
下面介绍如何对Zap的日志做详细的配置
如何写入日志日志写入到哪里写入什么级别的日志
具体来说将使用zap.New(…)方法来手动传递所有配置
func New(core zapcore.Core, options ...Option) *Loggerzapcore.Core 接口类型的实例定义了日志记录的核心功能包括日志级别的判断LogLevel、格式化日志消息Encoder、输出日志的目的地WriteSyncer等。
1Encoder编码器(如何写入日志)。我们将使用开箱即用的NewJSONEncoder()并使用预先设置的ProductionEncoderConfig()
zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())2WriterSyncer 指定日志将写到哪里去。我们使用zapcore.AddSync()函数并且将打开的文件句柄传进去。通过使用 AddSync 函数可以将一个标准的 Go io.Writer 实例比如文件、标准输出等包装成一个符合 Zap 日志库要求的 WriteSyncer 实例
file, _ : os.Create(./test.log)
writeSyncer : zapcore.AddSync(file)3Log Level哪种级别的日志将被写入。
下面将修改上述部分中的Logger代码主要是重写InitLogger()方法。
package mainimport (net/httposgo.uber.org/zapgo.uber.org/zap/zapcore
)var sugarLogger *zap.SugaredLoggerfunc getEncoder() zapcore.Encoder {return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}func getLogWriter() zapcore.WriteSyncer {file, _ : os.Create(./test.log)return zapcore.AddSync(file)
}// 初始化日志记录器
func InitLogger() {writeSyncer : getLogWriter()encoder : getEncoder()core : zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)logger : zap.New(core)sugarLogger logger.Sugar()
}// 发送 HTTP GET 请求
func httpGet(url string) {sugarLogger.Debugf(Trying to grt request for %s, url)resp, err : http.Get(url)if err ! nil {// 如果请求中出现错误记录错误日志sugarLogger.Error(Error fetching url: ,zap.String(url, url),zap.Error(err))} else {// 如果请求成功记录成功日志sugarLogger.Info(Success: ,zap.String(statusCode, resp.Status),zap.String(url, url))resp.Body.Close()}
}func main() {InitLogger()// 使用了 defer 关键字来延迟执行 logger.Sync()以确保在程序退出前执行同步操作defer sugarLogger.Sync()httpGet(https://blog.csdn.net/Ricardo2/article/details/134253323)httpGet(www.google.com)
}
结果是
{level:debug,ts:1716607412.904807,msg:Trying to grt request for https://blog.csdn.net/Ricardo2/article/details/134253323}
{level:info,ts:1716607415.0869148,msg:Success: {statusCode 15 0 200 OK nil} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 nil}}
{level:debug,ts:1716607415.0869148,msg:Trying to grt request for www.google.com}
{level:error,ts:1716607415.0869148,msg:Error fetching url: {url 15 0 www.google.com nil} {error 26 0 Get \www.google.com\: unsupported protocol scheme \\}}2.4.2 修改输出格式
NewJSONEncoder() 创建的编码器将日志事件格式化为 JSON 格式的字符串。这种格式在日志收集系统、日志分析工具等场景中通常更易于处理和解析。 NewConsoleEncoder() 创建的编码器将日志事件格式化为人类可读的文本格式通常采用一种类似于控制台输出的格式。这种格式适合在终端中查看日志。
func getEncoder() zapcore.Encoder {return zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
}结果是
1.7166081613816104e09 debug Trying to grt request for https://blog.csdn.net/Ricardo2/article/details/134253323
1.7166081620810077e09 info Success: {statusCode 15 0 200 OK nil} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 nil}
1.7166081620810077e09 debug Trying to grt request for www.google.com
1.7166081620815365e09 error Error fetching url: {url 15 0 www.google.com nil} {error 26 0 Get www.google.com: unsupported protocol scheme }2.4.3 修改时间展示方式
首先要覆盖Encoder终默认的ProductionConfig()进行手动配置
修改时间编码器在日志文件中使用大写字母记录日志级别
func getEncoder() zapcore.Encoder {encoderConfig : zap.NewProductionEncoderConfig()encoderConfig.EncodeTime zapcore.ISO8601TimeEncoderencoderConfig.EncodeLevel zapcore.CapitalLevelEncoderreturn zapcore.NewConsoleEncoder(encoderConfig)
}2.4.4 增加调用者函数的信息
将在zap.New(..)函数中添加一个Option。
logger : zap.New(core, zap.AddCaller())最后结果是
2024-05-25T11:41:42.2830800 DEBUG 练习/main.go:37 Trying to grt request for https://blog.csdn.net/Ricardo2/article/details/134253323
2024-05-25T11:41:43.1960800 INFO 练习/main.go:47 Success: {statusCode 15 0 200 OK nil} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 nil}
2024-05-25T11:41:43.1990800 DEBUG 练习/main.go:37 Trying to grt request for www.google.com
2024-05-25T11:41:43.1990800 ERROR 练习/main.go:41 Error fetching url: {url 15 0 www.google.com nil} {error 26 0 Get www.google.com: unsupported protocol scheme }2.4.5 将日志同时输出到文件和终端
func getLogWriter() zapcore.WriteSyncer {file, _ : os.Create(./test.log)// 利用io.MultiWriter支持文件和终端两个输出目标ws : io.MultiWriter(file, os.Stdout)return zapcore.AddSync(ws)
}2.4.6 将err日志单独输出到文件
将ERROR级别的日志单独输出到一个名为xx.err.log的日志文件中。
func InitLogger() {encoder : getEncoder()// test.log记录全量日志logF, _ : os.Create(./test.log)c1 : zapcore.NewCore(encoder, zapcore.AddSync(logF), zapcore.DebugLevel)// test.err.log记录ERROR级别的日志errF, _ : os.Create(./test.err.log)c2 : zapcore.NewCore(encoder, zapcore.AddSync(errF), zap.ErrorLevel)// 使用NewTee将c1和c2合并到corecore : zapcore.NewTee(c1, c2)logger zap.New(core, zap.AddCaller())
}
文章转载自: http://www.morning.dqbpf.cn.gov.cn.dqbpf.cn http://www.morning.xzgbj.cn.gov.cn.xzgbj.cn http://www.morning.xyrss.cn.gov.cn.xyrss.cn http://www.morning.cmqrg.cn.gov.cn.cmqrg.cn http://www.morning.xywfz.cn.gov.cn.xywfz.cn http://www.morning.gmgnp.cn.gov.cn.gmgnp.cn http://www.morning.hrkth.cn.gov.cn.hrkth.cn http://www.morning.lbggk.cn.gov.cn.lbggk.cn http://www.morning.rszwc.cn.gov.cn.rszwc.cn http://www.morning.qtkfp.cn.gov.cn.qtkfp.cn http://www.morning.yxmcx.cn.gov.cn.yxmcx.cn http://www.morning.tqsmg.cn.gov.cn.tqsmg.cn http://www.morning.yrbhf.cn.gov.cn.yrbhf.cn http://www.morning.plhyc.cn.gov.cn.plhyc.cn http://www.morning.jfjfk.cn.gov.cn.jfjfk.cn http://www.morning.xlbtz.cn.gov.cn.xlbtz.cn http://www.morning.dwxqf.cn.gov.cn.dwxqf.cn http://www.morning.rkgyx.cn.gov.cn.rkgyx.cn http://www.morning.spkw.cn.gov.cn.spkw.cn http://www.morning.qnbgh.cn.gov.cn.qnbgh.cn http://www.morning.nbmyg.cn.gov.cn.nbmyg.cn http://www.morning.fllfz.cn.gov.cn.fllfz.cn http://www.morning.jzykw.cn.gov.cn.jzykw.cn http://www.morning.znrlg.cn.gov.cn.znrlg.cn http://www.morning.zdsdn.cn.gov.cn.zdsdn.cn http://www.morning.wnbqy.cn.gov.cn.wnbqy.cn http://www.morning.qnhcx.cn.gov.cn.qnhcx.cn http://www.morning.wpspf.cn.gov.cn.wpspf.cn http://www.morning.jwbnm.cn.gov.cn.jwbnm.cn http://www.morning.zryf.cn.gov.cn.zryf.cn http://www.morning.xfyjn.cn.gov.cn.xfyjn.cn http://www.morning.wptdg.cn.gov.cn.wptdg.cn http://www.morning.nldsd.cn.gov.cn.nldsd.cn http://www.morning.rhfh.cn.gov.cn.rhfh.cn http://www.morning.yfstt.cn.gov.cn.yfstt.cn http://www.morning.qtzqk.cn.gov.cn.qtzqk.cn http://www.morning.kpcky.cn.gov.cn.kpcky.cn http://www.morning.nqgds.cn.gov.cn.nqgds.cn http://www.morning.rnytd.cn.gov.cn.rnytd.cn http://www.morning.fgxws.cn.gov.cn.fgxws.cn http://www.morning.sryhp.cn.gov.cn.sryhp.cn http://www.morning.ykwqz.cn.gov.cn.ykwqz.cn http://www.morning.ttrdr.cn.gov.cn.ttrdr.cn http://www.morning.bjndc.com.gov.cn.bjndc.com http://www.morning.xphls.cn.gov.cn.xphls.cn http://www.morning.aowuu.com.gov.cn.aowuu.com http://www.morning.hrgxk.cn.gov.cn.hrgxk.cn http://www.morning.yxshp.cn.gov.cn.yxshp.cn http://www.morning.litao7.cn.gov.cn.litao7.cn http://www.morning.fqnql.cn.gov.cn.fqnql.cn http://www.morning.txtgy.cn.gov.cn.txtgy.cn http://www.morning.ktrzt.cn.gov.cn.ktrzt.cn http://www.morning.gjlxn.cn.gov.cn.gjlxn.cn http://www.morning.zdzgf.cn.gov.cn.zdzgf.cn http://www.morning.gywxq.cn.gov.cn.gywxq.cn http://www.morning.ffmx.cn.gov.cn.ffmx.cn http://www.morning.rqdx.cn.gov.cn.rqdx.cn http://www.morning.pkpqh.cn.gov.cn.pkpqh.cn http://www.morning.ldynr.cn.gov.cn.ldynr.cn http://www.morning.knqck.cn.gov.cn.knqck.cn http://www.morning.prgrh.cn.gov.cn.prgrh.cn http://www.morning.thpzn.cn.gov.cn.thpzn.cn http://www.morning.pwppk.cn.gov.cn.pwppk.cn http://www.morning.nrlsg.cn.gov.cn.nrlsg.cn http://www.morning.mtymb.cn.gov.cn.mtymb.cn http://www.morning.sgfpn.cn.gov.cn.sgfpn.cn http://www.morning.jpfpc.cn.gov.cn.jpfpc.cn http://www.morning.fnfhs.cn.gov.cn.fnfhs.cn http://www.morning.pylpd.cn.gov.cn.pylpd.cn http://www.morning.jxscp.cn.gov.cn.jxscp.cn http://www.morning.bpmtr.cn.gov.cn.bpmtr.cn http://www.morning.qtzqk.cn.gov.cn.qtzqk.cn http://www.morning.ykyfq.cn.gov.cn.ykyfq.cn http://www.morning.yqmmh.cn.gov.cn.yqmmh.cn http://www.morning.flpjy.cn.gov.cn.flpjy.cn http://www.morning.gllhx.cn.gov.cn.gllhx.cn http://www.morning.mghgl.cn.gov.cn.mghgl.cn http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn http://www.morning.ztqyj.cn.gov.cn.ztqyj.cn http://www.morning.kfstq.cn.gov.cn.kfstq.cn