golang实现带日志级别处理的简单日志记录插件库go-logger的使用

go-logger - 带日志级别处理的简单日志记录插件库

安装

go get github.com/apsdehal/go-logger

使用 go get -u 更新包。

示例

以下是一个完整的示例程序,演示如何使用 go-logger:

package main

import (
	"github.com/apsdehal/go-logger"
	"os"
)

func main() {
	// 获取logger实例,"test"是模块名,1表示启用颜色
	// 第三个参数是可选的,是io.Writer类型实例,默认为os.Stderr
	log, err := logger.New("test", 1, os.Stdout)
	if err != nil {
		panic(err) // 检查错误
	}

	// 记录Critical级别日志
	log.Critical("This is Critical!")
	log.CriticalF("%+v", err)
	// 也可以使用类似fmt的命名方式,如log.Criticalf, log.Panicf等,使用小写'f'
	
	// Debug级别日志
	// 由于默认日志级别是Info,这不会打印任何内容
	log.Debug("This is Debug!")
	log.DebugF("Here are some numbers: %d %d %f", 10, -3, 3.14)
	// Warning级别日志
	log.Warning("This is Warning!")
	log.WarningF("This is Warning!")
	// Error级别日志
	log.Error("This is Error!")
	log.ErrorF("This is Error!")
	// Notice级别日志
	log.Notice("This is Notice!")
	log.NoticeF("%s %s", "This", "is Notice!")
	// Info级别日志
	log.Info("This is Info!")
	log.InfoF("This is %s!", "Info")

	// 打印堆栈信息
	log.StackAsError("Message before printing stack")

	// 设置自定义日志格式
	log.SetFormat("[%{module}] [%{level}] %{message}")
	log.Warning("This is Warning!") // 输出: "[test] [WARNING] This is Warning!"
	
	// 也可以为所有新logger设置默认格式
	logger.SetDefaultFormat("%{message}")
	log2, _ := logger.New("pkg", 1, os.Stdout)
	log2.Error("This is Error!") // 输出: "This is Error!"

	// 使用日志级别设置日志优先级
	log2.SetLogLevel(logger.DebugLevel)
	// 这会打印
	log2.Debug("This is debug!")
	log2.SetLogLevel(logger.WarningLevel)
	// 这不会打印
	log2.Info("This is an error!")
}

日志格式化

默认情况下,所有日志消息都有固定的格式,但你可以覆盖默认格式并设置你想要的格式。

为Logger实例设置格式

log, _ := logger.New("pkgname", 1)
log.SetFormat(format)

为包设置默认格式

logger.SetDefaultFormat(format)

如果你为包设置了格式,所有现有的logger将继续使用它们当前的格式。但所有新创建的logger将使用你指定的格式。

格式动词

你可以在格式字符串中使用以下动词:

%{id}           - 当前日志消息的编号
%{module}       - 模块名称(传递给New()函数的名称)
%{time}         - 当前时间,格式为"2006-01-02 15:04:05"
%{time:format}  - 当前时间,使用你指定的格式(支持time包支持的所有格式)
%{level}        - 日志级别名称(大写),如"ERROR", "DEBUG"等
%{lvl}          - 日志级别名称的前3个字母(大写),如"ERR", "DEB"等
%{file}         - 要写入日志的文件名
%{filename}     - 同%{file}
%{line}         - 要写入日志的文件行号
%{message}      - 你的日志消息

不存在的动词(如%{nonex-verb}%{})将被替换为空字符串。无效的动词(如%{inv-verb)将被视为纯文本。

测试

运行以下命令进行测试:

  • go test logger 运行logger测试
  • go test -bench=. 运行基准测试

贡献者

感谢以下主要贡献者:

许可证

使用与Go语言相同的BSD 3-Clause许可证


更多关于golang实现带日志级别处理的简单日志记录插件库go-logger的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现带日志级别处理的简单日志记录插件库go-logger的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go-Logger: 一个简单的带日志级别处理的日志库

下面我将介绍一个简单的Go日志库实现,支持不同日志级别、日志输出格式化和基本日志记录功能。

核心功能

  1. 支持多种日志级别:DEBUG, INFO, WARN, ERROR, FATAL
  2. 可自定义日志输出格式
  3. 支持输出到控制台和文件
  4. 线程安全

实现代码

package logger

import (
	"fmt"
	"io"
	"log"
	"os"
	"sync"
	"time"
)

// 日志级别类型
type LogLevel int

const (
	DEBUG LogLevel = iota
	INFO
	WARN
	ERROR
	FATAL
)

var levelNames = []string{
	"DEBUG",
	"INFO",
	"WARN",
	"ERROR",
	"FATAL",
}

// Logger 结构体
type Logger struct {
	level      LogLevel
	logger     *log.Logger
	mu         sync.Mutex
	output     io.Writer
	timeFormat string
}

// NewLogger 创建一个新的Logger实例
func NewLogger(level LogLevel, output io.Writer) *Logger {
	return &Logger{
		level:      level,
		logger:     log.New(output, "", 0),
		output:     output,
		timeFormat: "2006-01-02 15:04:05",
	}
}

// SetLevel 设置日志级别
func (l *Logger) SetLevel(level LogLevel) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.level = level
}

// SetTimeFormat 设置时间格式
func (l *Logger) SetTimeFormat(format string) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.timeFormat = format
}

// 通用日志记录方法
func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
	if level < l.level {
		return
	}

	l.mu.Lock()
	defer l.mu.Unlock()

	msg := fmt.Sprintf(format, args...)
	timestamp := time.Now().Format(l.timeFormat)
	levelName := levelNames[level]

	logMsg := fmt.Sprintf("[%s] [%s] %s", timestamp, levelName, msg)
	l.logger.Println(logMsg)

	if level == FATAL {
		os.Exit(1)
	}
}

// Debug 记录DEBUG级别日志
func (l *Logger) Debug(format string, args ...interface{}) {
	l.log(DEBUG, format, args...)
}

// Info 记录INFO级别日志
func (l *Logger) Info(format string, args ...interface{}) {
	l.log(INFO, format, args...)
}

// Warn 记录WARN级别日志
func (l *Logger) Warn(format string, args ...interface{}) {
	l.log(WARN, format, args...)
}

// Error 记录ERROR级别日志
func (l *Logger) Error(format string, args ...interface{}) {
	l.log(ERROR, format, args...)
}

// Fatal 记录FATAL级别日志并退出程序
func (l *Logger) Fatal(format string, args ...interface{}) {
	l.log(FATAL, format, args...)
}

使用示例

package main

import (
	"os"
	"./logger" // 替换为你的logger包路径
)

func main() {
	// 创建输出到控制台的logger
	consoleLogger := logger.NewLogger(logger.DEBUG, os.Stdout)
	
	// 创建输出到文件的logger
	file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		consoleLogger.Error("Failed to open log file: %v", err)
		return
	}
	defer file.Close()
	
	fileLogger := logger.NewLogger(logger.INFO, file)
	
	// 设置不同的日志级别
	consoleLogger.SetLevel(logger.DEBUG)  // 控制台输出所有级别
	fileLogger.SetLevel(logger.INFO)     // 文件只记录INFO及以上级别
	
	// 记录日志
	consoleLogger.Debug("This is a debug message")
	consoleLogger.Info("This is an info message")
	consoleLogger.Warn("This is a warning message")
	consoleLogger.Error("This is an error message")
	
	fileLogger.Info("This will be written to file")
	fileLogger.Debug("This debug message won't appear in file")
	
	// 修改时间格式
	consoleLogger.SetTimeFormat("2006/01/02 15:04:05.000")
	consoleLogger.Info("Log with custom time format")
	
	// Fatal日志会退出程序
	// consoleLogger.Fatal("This is a fatal error, program will exit")
}

扩展功能建议

  1. 日志轮转:可以添加日志文件大小检查,实现日志轮转功能
  2. JSON格式:支持JSON格式的日志输出
  3. 多输出:支持同时输出到多个目标(控制台+文件+网络等)
  4. 上下文信息:支持添加请求ID等上下文信息
  5. 性能优化:使用缓冲写入提高性能

总结

这个简单的go-logger实现提供了基本的日志功能,包括:

  • 多级别日志记录
  • 线程安全
  • 可自定义输出格式
  • 支持多种输出目标

你可以根据需要进一步扩展功能,比如添加日志轮转、支持JSON格式输出等高级特性。

回到顶部