Golang日志库使用体验与评测

Golang日志库使用体验与评测 大家好,我是Go语言的新手。

我为自己创建了超级简单的日志记录库和彩色日志查看器。

非常感谢您宝贵的意见!

GitHub

ermanimer/logger

Avatar

Go Logger。在GitHub上创建账户以参与ermanimer/logger的开发。

GitHub

ermanimer/log-viewer

Avatar

Go Log Viewer。在GitHub上创建账户以参与ermanimer/log-viewer的开发。


更多关于Golang日志库使用体验与评测的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

可以将消息格式化器和其他部分合并为一个格式,并传递所有值。但我倾向于将它们分开,一个实际上是消息,其他部分(时间、前缀)用于追踪。

ermanimer: 感谢您抽出宝贵时间。

:tr: 不客气。

更多关于Golang日志库使用体验与评测的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


  • 我会使用 io.Writer 来处理输出。
  • 缺少测试。
  • 我不会在所有日志函数中都进行级别比较,我会在实例的日志函数中进行检查。
  • 将格式化和级别检查集中到一个地方。
func Debugf(messageFormat string, values ...interface{}) {
    instance.log(DebugTraceLevel, message, values)
}

谢谢!

我更新了公共日志记录函数:

func Debug(message string) {
	log(DebugTraceLevel, debugPrefix, message)
}

func Debugf(messageFormat string, values ...interface{}) {
	log(DebugTraceLevel, debugPrefix, messageFormat, values...)
}

以及私有日志函数:

func log(traceLevel int, prefix string, messageFormat string, values ...interface{}) {
	//check initialization
	checkInitialization()

	//check trace level
	if instance.traceLevel > traceLevel {
		return
	}

	//synchronization
	instance.mutex.Lock()
	defer instance.mutex.Unlock()

	//create formatted message
	message := fmt.Sprintf(messageFormat, values...)
	formattedMessage := fmt.Sprintf("[%s][%s]: %s%s", time.Now().Format(timeFormat), prefix, message, newLine)

    ...
}

有没有可能只使用一个 Sprintf 函数?

在理解了写入方法之间的区别后,我将编写测试并更新写入方法。

感谢您宝贵的时间。

此致

看了你的GitHub项目,这是一个很不错的实践。对于新手来说,自己动手实现核心工具是深入理解语言特性的好方法。我来对你的logger库做个简单的技术评测,并和标准库log以及流行的zaplogrus做个对比。

1. 你的logger库核心分析

你的库提供了结构化的日志级别(Debug, Info, Warn, Error, Fatal)和颜色输出,这比标准库log的基础功能更实用。关键实现类似于:

// 类似你的Level类型定义
type Level int

const (
    LevelDebug Level = iota
    LevelInfo
    LevelWarn
    LevelError
    LevelFatal
)

// 核心的日志记录方法
func (l *Logger) log(level Level, format string, args ...interface{}) {
    if level < l.level {
        return
    }
    // 添加时间、级别前缀和颜色
    msg := fmt.Sprintf(format, args...)
    coloredMsg := addColor(level, msg)
    fmt.Fprintf(l.writer, "%s %s\n", time.Now().Format(time.RFC3339), coloredMsg)
}

这种实现方式简单直接,适合学习和小型项目。但生产环境还需要考虑性能(如避免频繁的字符串分配)、并发安全(比如对writer的并发写入)和更灵活的输出控制。

2. 与主流库的对比示例

标准库log

import "log"
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Println("标准日志") // 输出: 2023/10/01 14:30:00 main.go:10: 标准日志

优点是无依赖、简单;缺点是缺乏级别、结构化字段和性能优化。

zap(高性能场景首选)

import "go.uber.org/zap"
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("用户登录", zap.String("username", "john"), zap.Int("attempt", 2))
// 输出JSON: {"level":"info","ts":...,"msg":"用户登录","username":"john","attempt":2}

优点是极高性能(避免反射、内存分配);缺点是API稍复杂,需要手动Sync。

logrus(功能丰富)

import "github.com/sirupsen/logrus"
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.WithFields(logrus.Fields{"user": "john"}).Info("操作完成")

优点是功能全面(hooks、多格式);缺点是性能不如zap。

3. 给你的库的改进建议

如果你想继续完善这个库,可以考虑:

  • 添加结构化字段支持(如logger.WithField("key", "value").Info("msg")
  • 实现不同的Formatter(文本、JSON)
  • 提供全局默认logger实例
  • 增加单元测试和性能基准测试

4. log-viewer的补充

日志查看器配合彩色输出很实用。可以进一步考虑:

  • 支持动态过滤日志级别
  • 添加关键字高亮
  • 实现简单的tail -f实时查看功能

总的来说,作为新手项目已经具备了核心功能。通过这个实践,你不仅学会了日志库的基本原理,还掌握了接口设计、包组织等Go语言核心概念。继续迭代的话,可以考虑加入上面提到的生产级特性。

回到顶部