Go 日志封装实战示例详解

 更新时间:2023年04月17日 10:40:08   作者:小雄Ya  
这篇文章主要为大家介绍了Go 日志封装实战示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景

日志是框架中至关重要的一部分。在 Golang 只也提供了基本的日志组件,但其没有提供给比较多的功能。当然现在也有很多第三方已经封装好的库使用起来也很方便。作为成熟的开发者也应该学会封装自己的类库,以便后续在自己的个人项目中使用它。

Logger 封装的理解

Logger 库主要是一系列方法或接口,提供给应用程序代码调用然后将相关的数据记录到日志记录库中。就是在代码和底层日志库中间的一层。需要实现的功能是能够记录日志,且支持不同日志记录库的切换或添加新的记录库。

封装包,首先需要先定义一些能够描述日志方法的接口,基本的都是你的应用程序所需要的方法。比如,基本的日志接口基本的方法有 Info、Warn、 Error。然后就可以创建此接口的实现,将数据记录到记录库中。定义了接口和实现,就可以创建一个 logger 封装,并将相关的接口方法公开。

简单包封装

以下定义了五个方法:Info, Warn, Error 和 Fatal. 这些方法接口接收 2个参数,一个字符串和一个字段映射map.

type Logger interface {
	Debug(msg string, field map[string]interface{})
	Info(msg string, field map[string]interface{})
	Warn(msg string, field map[string]interface{})
	Error(msg string, field map[string]interface{})
	Fatal(msg string, field map[string]interface{})
}

接下来就是实现啦 Logger 方法,底层的实现主要是依赖使用 Logrus。首先需要创建一个 LLogger 结构体,该结构体包含 Logrus 实例。当然还需要一个 NewLLogger 方法来实例化一个 LLogger。

type LLogger struct {
	logger *logrus.Logger
	ctx    context.Context
}
func NewLLogger(ctx context.Context) *LLogger {
	logger := logrus.New()
	logger.Out = os.Stdout
	return &LLogger{logger: logger, ctx: ctx}
}
func (l *LLogger) Info(msg string, fields map[string]interface{}) {
	l.logger.WithFields(fields).Info(msg)
}
func (l *LLogger) Warn(msg string, fields map[string]interface{}) {
	l.logger.WithFields(fields).Warn(msg)
}
func (l *LLogger) Error(msg string, fields map[string]interface{}) {
	l.logger.WithFields(fields).Error(msg)
}
func (l *LLogger) Fatal(msg string, fields map[string]interface{}) {
	l.logger.WithFields(fields).Fatal(msg)
}

这样一个简单日志封装就完成了,使用时就可以直接使用。

func main() {
	ctx := ... // context 信息
	lg := NewLLogger(ctx)
	fields := map[string]interface{}{
		"userId":    "xiaoxiong",
		"ipAddress": "127.0.0.1",
	}
	lg.Info("这是测试信息", fields)
}

多日志库切换

当底层需要使用的是不同的日志库进行记录日志时,那就需要封装另外的日志,但是在实例化方法时可以增加一种日志类型参数,然后根据不同的类型实例化不同的日志。

比如使用了zap 包,那童养媳与奥实现接口的四个方法 :Info, Warn, Error and Fatal.

type ZapLog struct {
	logger *zap.Logger
	ctx    context.Context
}
func NewZapLog(ctx context.Context) *ZapLog {
	logger, _ := zap.NewProduction()
	return &ZapLog{logger: logger, ctx: ctx}
}
func (l *ZapLog) Info(msg string, fields map[string]interface{}) {
	l.logger.Info(msg, zap.Any("args", fields))
}
func (l *ZapLog) Warn(msg string, fields map[string]interface{}) {
	l.logger.Warn(msg, zap.Any("args", fields))
}
func (l *ZapLog) Error(msg string, fields map[string]interface{}) {
	l.logger.Error(msg, zap.Any("args", fields))
}
func (l *ZapLog) Fatal(msg string, fields map[string]interface{}) {
	l.logger.Fatal(msg, zap.Any("args", fields))
}

定义其他日志库的方法后就只需对这个两个日志库进行封装,根据不同的类型初始化出不同的日志,然后使用日志时候就使用相应的包进行处理。

type LoggerWrapper struct {
	logger Logger
}
func NewLoggerWrapper(loggerType string, ctx context.Context) *LoggerWrapper {
	var logger Logger
	switch loggerType {
	case "logrus":
		logger = NewLLogger(ctx)
	case "zap":
		logger = NewZapLog(ctx)
	default:
		logger = NewLLogger(ctx)
	}
	return &LoggerWrapper{logger: logger}
}

使用中间件记录公共信息

封装中增加了 Context 上下文的内容,主要是为了记录一些公共属性。就像经常在链路追踪时可需要请求ID ,请求IP 等相关的信息。但是日志实例都是在程序启动时进行初始化的,在每次的请求时可能请求ID或者IP 都是不一样,所以要记录这部分信息,可以使用中间件将上下文的信息添加到日志消息中。

以上就是Go 日志封装实战示例详解的详细内容,更多关于Go 日志封装的资料请关注脚本之家其它相关文章!

相关文章

  • Golang切片删除指定元素的三种方法对比

    Golang切片删除指定元素的三种方法对比

    Go语言并没有提供用于删除元素的语法或接口,而是通过利用切片本身的特性来删除元素—追加元素,这篇文章主要给大家介绍了关于Golang切片删除指定元素的三种方法,需要的朋友可以参考下
    2022-06-06
  • 详解Golang官方中的一致性哈希组件

    详解Golang官方中的一致性哈希组件

    这篇文章主要为大家详细介绍了Golang官方中的一致性哈希组件的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-04-04
  • Go实现用户每日限额的方法(例一天只能领三次福利)

    Go实现用户每日限额的方法(例一天只能领三次福利)

    这篇文章主要介绍了Go实现用户每日限额的方法(例一天只能领三次福利)
    2022-01-01
  • Go语言中常见的坑以及高性能编程技巧分享

    Go语言中常见的坑以及高性能编程技巧分享

    代码的稳健性、高性能、可读性是我们每一位coder必须去追求的目标,本文结合Go语言的特性做了相关总结,感兴趣的小伙伴可以了解一下
    2023-06-06
  • GO使用阿里云,解决go get下载项目慢或无法下载的情况

    GO使用阿里云,解决go get下载项目慢或无法下载的情况

    这篇文章主要介绍了GO使用阿里云,解决go get下载项目慢或无法下载的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • golang使用viper加载配置文件实现自动反序列化到结构

    golang使用viper加载配置文件实现自动反序列化到结构

    这篇文章主要为大家介绍了golang使用viper加载配置文件实现自动反序列化到结构示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Golang实现可重入锁的示例代码

    Golang实现可重入锁的示例代码

    可重入锁指的是同一个线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。本文将用Golang实现可重入锁,需要的可以参考一下
    2022-05-05
  • Go内存分配之结构体优化技巧

    Go内存分配之结构体优化技巧

    这篇文章主要为大家详细介绍了Go语言内存分配之结构体优化技巧的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • Golang配置解析神器go viper使用详解

    Golang配置解析神器go viper使用详解

    viper是一个很完善的Go项目配置解决方案,很多著名的开源项目都在使用,比如Hugo,Docker都使用了该库,使用viper可以让我们专注于自己的项目代码,而不用自己写那些配置解析代码,本文给大家介绍Golang配置解析神器go viper使用,感兴趣的朋友一起看看吧
    2022-05-05
  • Golang判断两个链表是否相交的方法详解

    Golang判断两个链表是否相交的方法详解

    这篇文章主要为大家详细介绍了如何通过Golang判断两个链表是否相交,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03

最新评论