内容简介:上一篇中我们已经把日志写入文件中了,但是还有一些问题,可以看到我们日志内容没有记录时间,也没有日志级别。错误日志,没有错误的文件和行号,也不知道在哪个函数出错的,这些我们也是需要加入进去的。所以,我们的日志打印的内容应该是这样的:我们现在
上一篇中我们已经把日志写入文件中了,但是还有一些问题,可以看到我们日志内容没有记录时间,也没有日志级别。错误日志,没有错误的文件和行号,也不知道在哪个函数出错的,这些我们也是需要加入进去的。
所以,我们的日志打印的内容应该是这样的:
2018-11-08 18:18:18.888 DEBUG [logDebug.go/logDebug.Debug:20] this is a debug log 复制代码
我们现在 file.go
的Debug方法中将时间加入进去:
func (f *FileLog) Debug(format string, args ...interface{}) { now := time.Now() nowStr := now.Format("2006-01-02 15:04:05.999")// 这个数字格式是固定的不能改变的,但是-和:可以更换 fmt.Fprintf(f.file, nowStr) fmt.Fprintf(f.file, format, args...) fmt.Fprintln(f.file) } 复制代码
然后我们再讲日志级别加进去,我们之前定义了日志级别常量,但是因为使用的iota,所以使用常量的时候,常量的值都是012,这种基本是没人看的懂的,所以我们需要将日志级别已字符串的形式打印。我们在 log_const.go
中新增一个方法:
func LogLevelString(level int) (levelStr string) { switch level { case DebugLevel: levelStr = "DEBUG" case TraceLevel: levelStr = "TRACE" case InfoLevel: levelStr = "INFO" case WarnLevel: levelStr = "WARN" case ErrorLevel: levelStr = "ERROR" case FatalLevel: levelStr = "FATAL" } return } 复制代码
可以看到我们制定制定的日志格式里面还有一个行号,文件名,所以我们还需要获取错误日志所在的行号的文件名,新建 util.go
:
package hm_log import( "runtime" ) func GetLineInfo() (fileName, funcName string, lineNo int) { //pc 计数器, file 文件名, line 行号, ok 是否 // runtime.Caller(4)这里的4是一个层级关系,可以尝试使用0 1 2 3来看看 // 4 在其他项目中使用的时候,如果在log的test中,使用3 pc, file, line, ok := runtime.Caller(4) if ok { fileName = file funcName = runtime.FuncForPC(pc).Name() // 获取当前的方法 lineNo = line } return } 复制代码
继续完善Debug方法:
func (f *FileLog) Debug(format string, args ...interface{}) { now := time.Now() nowStr := now.Format("2006-01-02 15:04:05.999") // 这个数字格式是固定的不能改变的,但是-和:可以更换 levelStr := LogLevelString(DebugLevel) fileName, funcName, lineNo := GetLineInfo() //由于这里返回的是全路径的,但是我们不需要,所以我们只需要文件名以及相关的即可 fileName = path.Base(fileName) funcName = path.Base(funcName) msg := fmt.Sprintf(format, args...) fmt.Fprintf(f.file, "%s %s [%s/%s:%d] %s\n", nowStr, levelStr, fileName, funcName, lineNo, msg) } 复制代码
然后再执行go.test,查看我们的日志文件,可以看到日志内容和之前定义的格式相同了。然后就其他方法修改为Debug方法相同的代码即可。但是这样太麻烦了,我们提取一个公共函数来回省点我们很多时间。
func (f *FileLog) writeLog(file *os.File, level int, format string, args... interface{} { now := time.Now() nowStr := now.Format("2006-01-02 15:04:05.999") // 这个数字格式是固定的不能改变的,但是-和:可以更换 levelStr := LogLevelString(level) fileName, funcName, lineNo := GetLineInfo() //由于这里返回的是全路径的,但是我们不需要,所以我们只需要文件名以及相关的即可 fileName = path.Base(fileName) funcName = path.Base(funcName) msg := fmt.Sprintf(format, args...) fmt.Fprintf(file, "%s %s [%s/%s:%d] %s\n", nowStr, levelStr, fileName, funcName, lineNo, msg) } func (f *FileLog) Debug(format string, args ...interface{}) { f.writeLog(f.file, DebugLevel, format, args...) } ... func (f *FileLog) Warn(format string, args ...interface{}) { f.writeLog(f.warnFile, WarnLevel, format, args...) } ... 复制代码
基本上这个文件日志库就写的差不多了,也基本实现了文件日志库的功能。下一篇我们继续将console日志库也实现了。
以上所述就是小编给大家介绍的《go开发属于自己的日志库-文件日志库实现》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- go开发属于自己的日志库-日志库优化
- go 开发属于自己的日志库-文件日志库原型实现
- 打造属于你自己的instagram!
- 属于 Unity 的 Flutter——UIWidgets
- 利用Python写属于自己的翻译命令行
- 打造属于自己的underscore系列(六)- 洗牌算法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Blockchain Basics
Daniel Drescher / Apress / 2017-3-16 / USD 20.99
In 25 concise steps, you will learn the basics of blockchain technology. No mathematical formulas, program code, or computer science jargon are used. No previous knowledge in computer science, mathema......一起来看看 《Blockchain Basics》 这本书的介绍吧!
RGB CMYK 转换工具
RGB CMYK 互转工具
HEX CMYK 转换工具
HEX CMYK 互转工具