golang快速高效12-factor应用日志记录插件logxi的使用

Golang快速高效12-factor应用日志记录插件logxi的使用

logxi是一个为速度和开发体验优化的结构化12-factor应用日志记录器。

demo

主要特点

  • 更简单:开箱即用的合理默认配置
  • 更快速:比logrus和log15更快
  • 结构化:强制使用键值对,生产环境输出JSON
  • 可配置:通过环境变量启用/禁用日志记录器和级别
  • 友好:终端中显示彩色、开发者友好的日志
  • 有帮助:强调跟踪、警告和错误,显示文件、行号和调用栈
  • 高效:有级别保护,避免构建复杂参数的成本

安装

go get -u github.com/mgutz/logxi/v1

快速开始

import "github.com/mgutz/logxi/v1"

// 创建包变量用于Logger接口
var logger log.Logger

func main() {
    // 使用默认日志记录器
    who := "mario"
    log.Info("Hello", "who", who)

    // 创建一个带有唯一标识符的日志记录器
    // 可以通过环境变量启用
    logger = log.New("pkg")

    // 指定写入器,如果非并发安全则使用NewConcurrentWriter
    modelLogger = log.NewLogger(log.NewConcurrentWriter(os.Stdout), "models")

    db, err := sql.Open("postgres", "dbname=testdb")
    if err != nil {
        modelLogger.Error("Could not open database", "err", err)
    }

    fruit := "apple"
    languages := []string{"go", "javascript"}
    if log.IsDebug() {
        // 在消息后使用键值对
        logger.Debug("OK", "fruit", fruit, "languages", languages)
    }
}

默认情况下,logxi只显示警告及以上级别的日志。要查看所有日志:

LOGXI=* go run main.go

完整示例

package main

import (
    "github.com/mgutz/logxi/v1"
    "os"
)

var logger log.Logger

func main() {
    // 初始化日志记录器
    logger = log.New("app")
    
    // 设置日志级别为Debug
    logger.SetLevel(log.LevelDebug)
    
    // 记录不同级别的日志
    logger.Trace("This is a trace message", "key1", "value1")
    logger.Debug("This is a debug message", "key2", 123)
    logger.Info("This is an info message", "key3", true)
    
    // 错误处理示例
    err := someFunction()
    if err != nil {
        // 错误日志会自动包含堆栈跟踪
        logger.Error("Failed to execute someFunction", "err", err)
    }
    
    // 性能敏感区域使用级别保护
    if logger.IsDebug() {
        // 只有在Debug级别启用时才会执行
        data := expensiveDataCollection()
        logger.Debug("Expensive data collected", "data", data)
    }
    
    // 创建文件日志记录器
    file, _ := os.Create("app.log")
    fileLogger := log.NewLogger(log.NewConcurrentWriter(file), "file")
    fileLogger.Info("This goes to file")
}

func someFunction() error {
    return log.Error("Something went wrong")
}

func expensiveDataCollection() string {
    // 模拟耗时操作
    return "collected data"
}

配置

启用/禁用日志记录器

默认情况下,logxi在使用终端时记录LevelWarn及以上级别的条目。对于非终端,记录LevelError及以上级别的条目。

快速查看所有条目:

# 启用所有,禁用名为foo的日志记录器
LOGXI=*,-foo yourapp

更精细的控制:

# 上述语句等价于
LOGXI=*=DBG,foo=OFF yourapp

在生产环境中调试数据访问层问题:

# 将所有设置为Error,将数据相关包设置为Debug
LOGXI=*=ERR,models=DBG,dat*=DBG,api=DBG yourapp

格式

可以通过LOGXI_FORMAT环境变量设置格式。有效值为"happy", "text", "JSON", "LTSV"

# 在生产环境中使用JSON和自定义时间格式
LOGXI_FORMAT=JSON,t=2006-01-02T15:04:05.000000-0700 yourapp

颜色方案

使用LOGXI_COLORS环境变量设置颜色方案:

# 强调错误为红色背景上的白色文字
LOGXI_COLORS="ERR=white:red" yourapp

# 使用256色表中的粉色(200)强调错误
LOGXI_COLORS="ERR=200" yourapp

性能

logxi在生产环境中非常高效:

# 原始类型
BenchmarkLogxi          100000    20021 ns/op   2477 B/op    66 allocs/op
BenchmarkLogrus          30000    46372 ns/op   8991 B/op   196 allocs/op
BenchmarkLog15           20000    62974 ns/op   9244 B/op   236 allocs/op

# 嵌套对象
BenchmarkLogxiComplex    30000    44448 ns/op   6416 B/op   190 allocs/op
BenchmarkLogrusComplex   20000    65006 ns/op  12231 B/op   278 allocs/op
BenchmarkLog15Complex    20000    92880 ns/op  13172 B/op   311 allocs/op

日志接口

logxi实现了标准的日志接口:

type Logger interface {
    Trace(msg string, args ...interface{})
    Debug(msg string, args ...interface{})
    Info(msg string, args ...interface{})
    Warn(msg string, args ...interface{}) error
    Error(msg string, args ...interface{}) error
    Fatal(msg string, args ...interface{})
    Log(level int, msg string, args []interface{})

    SetLevel(int)
    IsTrace() bool
    IsDebug() bool
    IsInfo() bool
    IsWarn() bool
    // Error, Fatal not needed, those SHOULD always be logged
}

测试

在单元测试中抑制日志输出:

func TestErrNotFound() {
    log.Suppress(true)
    defer log.Suppress(false)
    ...
}

更多关于golang快速高效12-factor应用日志记录插件logxi的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang快速高效12-factor应用日志记录插件logxi的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用logxi构建高效12-Factor应用日志记录

logxi是一个高性能、结构化、可扩展的Go日志库,非常适合构建符合12-Factor原则的应用程序。以下是logxi的核心特性和使用方法:

logxi核心特性

  1. 高性能:比标准库log包快5-10倍
  2. 结构化日志:支持键值对格式的日志
  3. 彩色输出:终端中可读性更好
  4. 多种输出格式:JSON、文本等
  5. 灵活的日志级别:支持标准日志级别

安装

go get github.com/mgutz/logxi/v1

基本使用示例

package main

import (
    "github.com/mgutz/logxi/v1"
)

func main() {
    // 创建一个默认logger
    logger := log.New("myapp")
    
    // 不同级别日志
    logger.Info("Starting application")
    logger.Debug("Debug information", "key1", "value1", "key2", 42)
    logger.Warn("Warning message", "error", "something might be wrong")
    logger.Error("Error occurred", "err", "file not found")
    
    // 性能关键路径可以使用Fataln避免格式化开销
    logger.Fatal("Critical failure", "reason", "disk full")
}

高级配置

func configureLogger() {
    // 自定义logger配置
    log.NewLogger(log.NewConcurrentWriter(os.Stdout), "myapp", log.Config{
        Level:      log.LevelDebug,  // 设置日志级别
        Color:      "auto",         // 自动检测终端支持
        TimeFormat: "2006-01-02T15:04:05.000", // 时间格式
        Pretty:     true,           // 美化输出
    })
    
    // 创建带固定字段的logger
    reqLogger := log.New("request").With(
        "method", "GET",
        "path", "/api/users",
        "request_id", "abc123",
    )
    
    reqLogger.Info("Request started")
    reqLogger.Debug("Processing data", "user_id", 123)
}

12-Factor应用最佳实践

  1. 日志作为事件流
// 使用JSON格式输出到stdout
log.NewLogger(log.NewJSONWriter(os.Stdout), "app", log.Config{
    Level: log.LevelInfo,
})
  1. 环境变量配置
func initLogger() {
    level := os.Getenv("LOG_LEVEL")
    logLevel := log.LevelInfo
    switch level {
    case "debug":
        logLevel = log.LevelDebug
    case "warn":
        logLevel = log.LevelWarn
    case "error":
        logLevel = log.LevelError
    }
    
    log.DefaultLogger.SetLevel(logLevel)
}
  1. 生产环境配置
func productionLogger() log.Logger {
    return log.NewLogger(log.NewConcurrentWriter(os.Stdout), "prod", log.Config{
        Level:      log.LevelInfo,
        Color:      "none",
        Pretty:     false,
        TimeFormat: time.RFC3339Nano,
    })
}
  1. 性能关键代码
// 使用Fataln/Fatalln避免格式化开销
if err != nil {
    logger.Fatal("DB connection failed", "err", err)
}

// 预先创建字段减少分配
var errorFields = []interface{}{"err", nil}
func logError(err error) {
    errorFields[1] = err
    logger.Error("Operation failed", errorFields...)
}

与标准库集成

// 将logxi作为标准库logger
func init() {
    stdlog.SetFlags(0)
    stdlog.SetOutput(log.NewStdWriter(log.New("stdlog")))
}

logxi提供了高性能、结构化且符合12-Factor原则的日志解决方案,特别适合云原生和微服务架构应用。通过合理配置,可以在开发和生产环境中获得良好的日志体验。

回到顶部