插件窝 干货文章 Linux系统中Golang如何进行日志记录

Linux系统中Golang如何进行日志记录

日志 log logrus 使用 904    来源:    2025-05-10

Golang 日志记录在 Linux 系统中的实现方案

在 Linux 系统上使用 Golang 进行日志记录有多种方法,以下是一些常用且高效的方案:

1. 标准库 log 包

Golang 内置的 log 包提供了基本的日志功能:

package main

import (
    "log"
    "os"
)

func main() {
    // 基本日志
    log.Println("这是一条普通日志")

    // 设置日志前缀
    log.SetPrefix("MyApp: ")

    // 设置日志输出到文件
    file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatal("无法打开日志文件:", err)
    }
    defer file.Close()

    log.SetOutput(file)
    log.Println("这条日志会被写入文件")

    // 致命错误日志(会调用os.Exit(1))
    // log.Fatal("致命错误")
}

2. 第三方日志库

2.1 logrus (推荐)

package main

import (
    "os"
    "github.com/sirupsen/logrus"
)

func main() {
    // 创建logrus实例
    log := logrus.New()

    // 设置日志级别
    log.SetLevel(logrus.InfoLevel)

    // 设置JSON格式
    log.SetFormatter(&logrus.JSONFormatter{})

    // 设置输出到文件
    file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err == nil {
        log.SetOutput(file)
    } else {
        log.Info("无法打开日志文件,使用默认的stderr")
    }

    // 记录不同级别的日志
    log.WithFields(logrus.Fields{
        "event": "startup",
        "status": "running",
    }).Info("应用程序启动")

    log.Warn("这是一条警告日志")
    log.Error("这是一条错误日志")
}

2.2 zap (高性能)

package main

import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
)

func main() {
    // 配置zap
    config := zap.NewProductionConfig()
    config.OutputPaths = []string{"app.log", "stdout"}

    logger, err := config.Build()
    if err != nil {
        panic(err)
    }
    defer logger.Sync() // 刷新缓冲区

    // 记录日志
    logger.Info("这是一条信息日志",
        zap.String("key", "value"),
        zap.Int("count", 42),
    )

    logger.Error("这是一条错误日志",
        zap.String("module", "auth"),
        zap.Error(err),
    )
}

3. 系统日志集成 (syslog)

对于 Linux 系统服务,可以集成系统日志:

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 连接到系统日志服务
    sysLog, err := syslog.New(syslog.LOG_INFO|syslog.LOG_LOCAL7, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    log.SetOutput(sysLog)

    log.Println("这条日志会发送到系统日志")
}

4. 日志轮转 (log rotation)

在生产环境中,日志轮转是必须的:

4.1 使用 lumberjack

package main

import (
    "gopkg.in/natefinch/lumberjack.v2"
    "log"
)

func main() {
    log.SetOutput(&lumberjack.Logger{
        Filename:   "/var/log/myapp/app.log",
        MaxSize:    100, // MB
        MaxBackups: 3,
        MaxAge:     28, // days
        Compress:   true,
    })

    log.Println("这条日志会被自动轮转")
}

4.2 结合 logrus 和 lumberjack

package main

import (
    "github.com/sirupsen/logrus"
    "gopkg.in/natefinch/lumberjack.v2"
)

func main() {
    logger := logrus.New()
    logger.SetOutput(&lumberjack.Logger{
        Filename:   "/var/log/myapp/app.log",
        MaxSize:    100,
        MaxBackups: 3,
        MaxAge:     28,
        Compress:   true,
    })

    logger.Info("结合logrus和lumberjack的日志轮转")
}

5. 最佳实践建议

  1. 日志级别:合理使用不同日志级别(DEBUG, INFO, WARN, ERROR, FATAL)
  2. 结构化日志:使用JSON格式便于后续分析处理
  3. 上下文信息:在日志中包含足够的上下文信息(如请求ID、用户ID等)
  4. 性能考虑:高频日志应考虑异步写入
  5. 敏感信息:避免记录敏感数据(密码、密钥等)
  6. 日志清理:设置合理的日志保留策略

6. 高级方案

对于大规模分布式系统,可以考虑:

  • 使用ELK(Elasticsearch, Logstash, Kibana)栈
  • 使用Fluentd/Fluent Bit收集日志
  • 使用Prometheus + Grafana监控日志指标

以上方案可以根据您的具体需求选择或组合使用。对于大多数应用场景,logrus + lumberjack 的组合已经足够强大且易于使用。