Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Go log/syslog 包详解

概述

log/syslog 包提供了与系统日志(syslog)服务的简单接口。它可以使用 UNIX domain sockets、UDP 或 TCP 将消息发送到 syslog 守护进程。该包支持标准的 syslog 优先级(severity)和设施(facility),允许应用程序将日志消息发送到系统日志服务进行集中管理和存储。

重要说明

  • ⚠️ 该包已冻结(frozen),不再接受新功能
  • ⚠️ 不支持 Windows 和 Plan 9 系统
  • ✓ 建议:Windows 用户使用第三方 syslog 包

包导入

import "log/syslog"

基本使用

1. 连接到本地 syslog

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 连接到本地 syslog
    syslogWriter, err := syslog.New(syslog.LOG_INFO, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer syslogWriter.Close()
    
    // 发送日志消息
    syslogWriter.Info("应用启动")
    syslogWriter.Warning("资源不足")
    syslogWriter.Err("发生错误")
}

2. 连接到远程 syslog 服务器

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 通过 TCP 连接到远程 syslog 服务器
    syslogWriter, err := syslog.Dial("tcp", "192.168.1.100:514", 
        syslog.LOG_WARNING|syslog.LOG_DAEMON, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer syslogWriter.Close()
    
    // 发送日志
    syslogWriter.Warning("警告消息")
    syslogWriter.Emerg("紧急消息")
}

3. 使用标准 log.Logger

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 创建 syslog Writer
    syslogWriter, err := syslog.New(syslog.LOG_INFO, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer syslogWriter.Close()
    
    // 创建 log.Logger
    logger, err := syslog.NewLogger(syslog.LOG_INFO, 0)
    if err != nil {
        log.Fatal(err)
    }
    
    // 使用标准 log 包输出到 syslog
    logger.Println("这是一条日志")
    logger.Printf("格式化日志:%s", "test")
}

一、核心类型

Priority

定义:

type Priority int

说明:

  • 功能:表示 syslog 优先级
  • 组成:设施(facility)+ 严重性(severity)的组合
  • 计算公式Priority = (facility << 3) | severity
  • 用途:指定日志的来源和重要程度

常量 - 严重性(Severity):

常量说明使用场景
LOG_EMERG0系统不可用系统崩溃、硬件故障
LOG_ALERT1需要立即行动数据库损坏、数据丢失
LOG_CRIT2严重错误关键服务失败
LOG_ERR3一般错误操作失败、连接错误
LOG_WARNING4警告资源不足、配置问题
LOG_NOTICE5正常但重要服务启动、配置变更
LOG_INFO6信息一般操作日志
LOG_DEBUG7调试开发调试信息

常量 - 设施(Facility):

常量说明
LOG_KERN0内核消息
LOG_USER1用户级消息(默认)
LOG_MAIL2邮件系统
LOG_DAEMON3系统守护进程
LOG_AUTH4认证系统
LOG_SYSLOG5syslog 本身
LOG_LPR6行式打印机
LOG_NEWS7网络新闻
LOG_UUCP8UUCP 子系统
LOG_CRON9时钟守护进程
LOG_AUTHPRIV10认证系统(私有)
LOG_FTP11FTP 守护进程
LOG_LOCAL0 - LOG_LOCAL716-23本地使用

示例 - 组合优先级:

package main

import (
    "log/syslog"
)

func main() {
    // 示例 1:默认设施 + INFO 严重性
    p1 := syslog.LOG_INFO
    syslog.New(p1, "app1")
    
    // 示例 2:DAEMON 设施 + WARNING 严重性
    p2 := syslog.LOG_DAEMON | syslog.LOG_WARNING
    syslog.New(p2, "app2")
    
    // 示例 3:LOCAL0 设施 + DEBUG 严重性
    p3 := syslog.LOG_LOCAL0 | syslog.LOG_DEBUG
    syslog.New(p3, "app3")
    
    // 示例 4:AUTH 设施 + CRIT 严重性
    p4 := syslog.LOG_AUTH | syslog.LOG_CRIT
    syslog.New(p4, "auth-app")
}

Writer

定义:

type Writer struct {
    // 包含未导出的字段
}

说明:

  • 功能:syslog 服务器连接
  • 用途:发送日志消息到 syslog 守护进程
  • 特点
    • 线程安全
    • 自动重连
    • 支持多种传输协议

方法总览:

方法参数返回值描述
Alertm stringerrorLOG_ALERT 级别日志
Closeerror关闭连接
Critm stringerrorLOG_CRIT 级别日志
Debugm stringerrorLOG_DEBUG 级别日志
Emergm stringerrorLOG_EMERG 级别日志
Errm stringerrorLOG_ERR 级别日志
Infom stringerrorLOG_INFO 级别日志
Noticem stringerrorLOG_NOTICE 级别日志
Warningm stringerrorLOG_WARNING 级别日志
Writeb []byte(int, error)写入原始字节

示例 - Writer 完整使用:

package main

import (
    "fmt"
    "log"
    "log/syslog"
)

func main() {
    // 创建 Writer
    w, err := syslog.New(syslog.LOG_INFO, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer w.Close()
    
    // 使用不同级别的方法
    w.Emerg("系统不可用!")
    w.Alert("需要立即行动!")
    w.Crit("严重错误!")
    w.Err("一般错误")
    w.Warning("警告信息")
    w.Notice("正常但重要的消息")
    w.Info("普通信息")
    w.Debug("调试信息")
    
    // 使用 Write 方法
    n, err := w.Write([]byte("原始字节消息\n"))
    fmt.Printf("写入 %d 字节\n", n)
}

二、核心函数

Dial

定义:

func Dial(network, raddr string, priority Priority, tag string) (*Writer, error)

说明:

  • 功能:建立到 syslog 守护程序的连接
  • 参数
    • network - 网络类型(tcp、udp、unixgram、unix)
    • raddr - 服务器地址(如 “localhost:514”)
    • priority - 优先级(设施 + 严重性)
    • tag - 标签(用于标识消息来源,空则使用 os.Args[0])
  • 返回值
    • *Writer - syslog Writer
    • error - 错误信息

示例:

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 示例 1:本地 syslog(自动选择)
    w1, err := syslog.Dial("", "", syslog.LOG_INFO, "app1")
    if err != nil {
        log.Fatal(err)
    }
    defer w1.Close()
    
    // 示例 2:TCP 连接
    w2, err := syslog.Dial("tcp", "localhost:514", 
        syslog.LOG_DAEMON|syslog.LOG_INFO, "app2")
    if err != nil {
        log.Fatal(err)
    }
    defer w2.Close()
    
    // 示例 3:UDP 连接
    w3, err := syslog.Dial("udp", "192.168.1.100:514", 
        syslog.LOG_USER|syslog.LOG_WARNING, "app3")
    if err != nil {
        log.Fatal(err)
    }
    defer w3.Close()
    
    // 示例 4:UNIX domain socket
    w4, err := syslog.Dial("unixgram", "/dev/log", 
        syslog.LOG_USER|syslog.LOG_INFO, "app4")
    if err != nil {
        log.Fatal(err)
    }
    defer w4.Close()
    
    // 发送测试消息
    w1.Info("本地 syslog 消息")
    w2.Info("TCP syslog 消息")
    w3.Warning("UDP syslog 消息")
    w4.Notice("UNIX socket 消息")
}

New

定义:

func New(priority Priority, tag string) (*Writer, error)

说明:

  • 功能:建立到系统日志守护进程的新连接
  • 参数
    • priority - 优先级(设施 + 严重性)
    • tag - 标签(空则使用 os.Args[0])
  • 返回值
    • *Writer - syslog Writer
    • error - 错误信息
  • 等价于Dial("", "", priority, tag)

示例:

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 示例 1:INFO 级别
    w1, err := syslog.New(syslog.LOG_INFO, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer w1.Close()
    w1.Info("INFO 消息")
    
    // 示例 2:WARNING 级别
    w2, err := syslog.New(syslog.LOG_WARNING, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer w2.Close()
    w2.Warning("WARNING 消息")
    
    // 示例 3:使用 LOCAL0 设施
    w3, err := syslog.New(syslog.LOG_LOCAL0|syslog.LOG_INFO, "custom")
    if err != nil {
        log.Fatal(err)
    }
    defer w3.Close()
    w3.Info("LOCAL0 消息")
}

NewLogger

定义:

func NewLogger(p Priority, logFlag int) (*log.Logger, error)

说明:

  • 功能:创建输出到 syslog 的 log.Logger
  • 参数
    • p - syslog 优先级
    • logFlag - log 包的标志(如 log.Ldate|log.Ltime)
  • 返回值
    • *log.Logger - 标准库 Logger
    • error - 错误信息
  • 用途:将现有使用 log 包的代码迁移到 syslog

示例:

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 创建 syslog Logger
    logger, err := syslog.NewLogger(
        syslog.LOG_INFO|syslog.LOG_DAEMON,
        log.Ldate|log.Ltime,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    // 使用标准 log API
    logger.Println("这是一条日志")
    logger.Printf("格式化日志:%s", "test")
    logger.Printf("带变量的日志:%d", 123)
}

三、Writer 方法详解

Alert

定义:

func (w *Writer) Alert(m string) error

说明:

  • 功能:记录 LOG_ALERT 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 严重性:需要立即采取行动

示例:

w.Alert("数据库连接丢失!")
w.Alert("安全漏洞检测到!")

Close

定义:

func (w *Writer) Close() error

说明:

  • 功能:关闭与 syslog 守护进程的连接
  • 返回值error - 错误信息
  • 用途:资源清理

示例:

w, _ := syslog.New(syslog.LOG_INFO, "app")
defer w.Close() // ✓ 推荐做法

Crit

定义:

func (w *Writer) Crit(m string) error

说明:

  • 功能:记录 LOG_CRIT 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 严重性:严重错误

示例:

w.Crit("主服务崩溃")
w.Crit("磁盘空间耗尽")

Debug

定义:

func (w *Writer) Debug(m string) error

说明:

  • 功能:记录 LOG_DEBUG 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 用途:开发调试信息

示例:

w.Debug("函数调用参数:x=1, y=2")
w.Debug("SQL 查询:SELECT * FROM users")

Emerg

定义:

func (w *Writer) Emerg(m string) error

说明:

  • 功能:记录 LOG_EMERG 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 严重性:系统不可用(最高级别)

示例:

w.Emerg("系统崩溃!")
w.Emerg("硬件故障!")

Err

定义:

func (w *Writer) Err(m string) error

说明:

  • 功能:记录 LOG_ERR 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 严重性:一般错误

示例:

w.Err("文件打开失败:%v", err)
w.Err("API 调用返回 500")

Info

定义:

func (w *Writer) Info(m string) error

说明:

  • 功能:记录 LOG_INFO 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 用途:普通信息(最常用)

示例:

w.Info("服务启动成功")
w.Info("用户登录:user123")
w.Info("请求处理完成")

Notice

定义:

func (w *Writer) Notice(m string) error

说明:

  • 功能:记录 LOG_NOTICE 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 严重性:正常但重要的消息

示例:

w.Notice("配置已更新")
w.Notice("备份完成")

Warning

定义:

func (w *Writer) Warning(m string) error

说明:

  • 功能:记录 LOG_WARNING 级别消息
  • 参数m - 日志消息
  • 返回值error - 错误信息
  • 严重性:警告

示例:

w.Warning("内存使用率超过 80%")
w.Warning("SSL 证书即将过期")

Write

定义:

func (w *Writer) Write(b []byte) (int, error)

说明:

  • 功能:写入原始字节到 syslog
  • 参数b - 字节切片
  • 返回值
    • int - 写入的字节数
    • error - 错误信息
  • 实现io.Writer 接口

示例:

package main

import (
    "fmt"
    "log"
    "log/syslog"
)

func main() {
    w, err := syslog.New(syslog.LOG_INFO, "app")
    if err != nil {
        log.Fatal(err)
    }
    defer w.Close()
    
    // 直接写入字节
    n, err := w.Write([]byte("原始消息\n"))
    if err != nil {
        log.Printf("写入失败:%v", err)
    }
    fmt.Printf("写入 %d 字节\n", n)
    
    // 使用 fmt.Fprintf
    fmt.Fprintf(w, "格式化消息:%s\n", "test")
}

四、典型示例

示例 1:Web 应用日志

package main

import (
    "fmt"
    "log"
    "log/syslog"
    "net/http"
)

var syslogWriter *syslog.Writer

func initSyslog() {
    var err error
    syslogWriter, err = syslog.Dial("tcp", "localhost:514", 
        syslog.LOG_DAEMON|syslog.LOG_INFO, "webapp")
    if err != nil {
        log.Fatal("无法连接 syslog:", err)
    }
}

func requestHandler(w http.ResponseWriter, r *http.Request) {
    // 记录请求
    syslogWriter.Info(fmt.Sprintf("请求:%s %s", r.Method, r.URL.Path))
    
    // 处理请求
    fmt.Fprintf(w, "Hello World")
    
    // 记录响应
    syslogWriter.Info(fmt.Sprintf("响应完成:%s", r.URL.Path))
}

func errorHandler(w http.ResponseWriter, r *http.Request) {
    syslogWriter.Err("404 错误:" + r.URL.Path)
    http.NotFound(w, r)
}

func main() {
    initSyslog()
    defer syslogWriter.Close()
    
    http.HandleFunc("/", requestHandler)
    http.Handle("/static/", http.NotFoundHandler())
    
    syslogWriter.Info("Web 服务器启动")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

示例 2:多级别日志记录

package main

import (
    "fmt"
    "log"
    "log/syslog"
)

type Application struct {
    syslog *syslog.Writer
}

func NewApplication() (*Application, error) {
    w, err := syslog.New(syslog.LOG_DAEMON|syslog.LOG_INFO, "myapp")
    if err != nil {
        return nil, err
    }
    
    return &Application{
        syslog: w,
    }, nil
}

func (a *Application) Start() {
    a.syslog.Notice("应用启动中...")
    a.syslog.Info("加载配置文件")
    a.syslog.Debug("配置内容:port=8080")
    
    // 模拟启动过程
    if err := a.loadConfig(); err != nil {
        a.syslog.Err(fmt.Sprintf("配置加载失败:%v", err))
        return
    }
    
    a.syslog.Info("应用启动完成")
}

func (a *Application) loadConfig() error {
    // 模拟配置加载
    a.syslog.Debug("检查配置文件")
    a.syslog.Debug("验证配置参数")
    return nil
}

func (a *Application) ProcessRequest(data string) error {
    a.syslog.Debug(fmt.Sprintf("处理请求:%s", data))
    
    // 模拟处理
    if data == "error" {
        err := fmt.Errorf("处理失败")
        a.syslog.Err(err.Error())
        return err
    }
    
    if data == "warning" {
        a.syslog.Warning("潜在问题")
    }
    
    a.syslog.Info("请求处理成功")
    return nil
}

func (a *Application) Stop() {
    a.syslog.Notice("应用关闭中...")
    a.syslog.Info("清理资源")
    a.syslog.Notice("应用已关闭")
    a.syslog.Close()
}

func main() {
    app, err := NewApplication()
    if err != nil {
        log.Fatal(err)
    }
    defer app.Stop()
    
    app.Start()
    app.ProcessRequest("test")
    app.ProcessRequest("warning")
    app.ProcessRequest("error")
}

示例 3:远程日志聚合

package main

import (
    "fmt"
    "log"
    "log/syslog"
    "os"
    "time"
)

type RemoteLogger struct {
    writers []*syslog.Writer
}

func NewRemoteLogger(servers []string, tag string) (*RemoteLogger, error) {
    rl := &RemoteLogger{
        writers: make([]*syslog.Writer, 0),
    }
    
    for _, server := range servers {
        w, err := syslog.Dial("tcp", server, 
            syslog.LOG_USER|syslog.LOG_INFO, tag)
        if err != nil {
            log.Printf("连接 %s 失败:%v", server, err)
            continue
        }
        rl.writers = append(rl.writers, w)
    }
    
    if len(rl.writers) == 0 {
        return nil, fmt.Errorf("无法连接任何 syslog 服务器")
    }
    
    return rl, nil
}

func (rl *RemoteLogger) Info(message string) {
    for _, w := range rl.writers {
        w.Info(message)
    }
}

func (rl *RemoteLogger) Error(message string) {
    for _, w := range rl.writers {
        w.Err(message)
    }
}

func (rl *RemoteLogger) Close() {
    for _, w := range rl.writers {
        w.Close()
    }
}

func main() {
    // 配置多个 syslog 服务器
    servers := []string{
        "192.168.1.100:514",
        "192.168.1.101:514",
    }
    
    logger, err := NewRemoteLogger(servers, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer logger.Close()
    
    // 模拟日志发送
    for i := 0; i < 10; i++ {
        logger.Info(fmt.Sprintf("日志消息 %d - %s", i, time.Now().Format(time.RFC3339)))
        time.Sleep(time.Second)
    }
    
    logger.Error("测试错误消息")
}

示例 4:与标准 log 包集成

package main

import (
    "log"
    "log/syslog"
)

func main() {
    // 创建 syslog Writer
    syslogWriter, err := syslog.New(syslog.LOG_DAEMON|syslog.LOG_INFO, "myapp")
    if err != nil {
        log.Fatal(err)
    }
    defer syslogWriter.Close()
    
    // 创建标准 log.Logger 输出到 syslog
    logger, err := syslog.NewLogger(
        syslog.LOG_INFO,
        log.Ldate|log.Ltime|log.Lshortfile,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    // 使用标准 log API
    logger.Println("标准日志输出")
    logger.Printf("格式化输出:%s", "test")
    
    // 同时使用 syslog 原生 API
    syslogWriter.Info("syslog 原生输出")
    syslogWriter.Warning("警告消息")
}

五、最佳实践

1. 选择合适的严重性

// EMERG: 系统不可用
syslog.Emerg("系统崩溃")

// ALERT: 需要立即行动
syslog.Alert("安全入侵检测")

// CRIT: 严重错误
syslog.Crit("数据库连接失败")

// ERR: 一般错误
syslog.Err("文件打开失败")

// WARNING: 警告
syslog.Warning("内存使用率 85%")

// NOTICE: 正常但重要
syslog.Notice("配置已更新")

// INFO: 普通信息(最常用)
syslog.Info("服务启动")

// DEBUG: 调试信息
syslog.Debug("函数参数:x=1")

2. 使用合适的设施

// 用户应用
syslog.New(syslog.LOG_USER|syslog.LOG_INFO, "myapp")

// 守护进程
syslog.New(syslog.LOG_DAEMON|syslog.LOG_INFO, "mydaemon")

// 认证相关
syslog.New(syslog.LOG_AUTH|syslog.LOG_INFO, "auth")

// 本地应用
syslog.New(syslog.LOG_LOCAL0|syslog.LOG_INFO, "local-app")

3. 错误处理

w, err := syslog.New(syslog.LOG_INFO, "app")
if err != nil {
    // 回退到标准错误输出
    log.Printf("syslog 不可用:%v", err)
    return
}
defer w.Close()

4. 资源管理

// 使用 defer 确保连接关闭
func process() {
    w, err := syslog.New(syslog.LOG_INFO, "app")
    if err != nil {
        log.Fatal(err)
    }
    defer w.Close() // ✓ 确保关闭
    
    w.Info("处理中...")
    // ... 处理逻辑
}

5. 标签命名

// ✓ 好的做法:清晰、一致的标签
syslog.New(syslog.LOG_INFO, "webapp")
syslog.New(syslog.LOG_INFO, "webapp-api")
syslog.New(syslog.LOG_INFO, "webapp-worker")

// ✗ 不好的做法:模糊的标签
syslog.New(syslog.LOG_INFO, "app")
syslog.New(syslog.LOG_INFO, "test")

六、与其他包配合

1. 与 log 包配合

// 见示例:与标准 log 包集成

2. 与 fmt 包配合

import "fmt"

fmt.Fprintf(syslogWriter, "格式化:%s %d\n", "test", 123)

3. 与 net 包配合

// 自定义网络连接
import "net"

conn, err := net.Dial("tcp", "syslog-server:514")
// 然后使用自定义连接...

七、快速参考

函数总览

函数名参数返回值描述
Dialnetwork, raddr string, priority Priority, tag string(*Writer, error)建立连接
Newpriority Priority, tag string(*Writer, error)建立本地连接
NewLoggerp Priority, logFlag int(*log.Logger, error)创建 log.Logger

类型总览

类型名描述
Prioritysyslog 优先级类型
Writersyslog 连接类型

严重性常量

常量说明
LOG_EMERG0系统不可用
LOG_ALERT1需要立即行动
LOG_CRIT2严重错误
LOG_ERR3一般错误
LOG_WARNING4警告
LOG_NOTICE5正常但重要
LOG_INFO6信息
LOG_DEBUG7调试

设施常量

常量说明
LOG_KERN内核
LOG_USER用户级(默认)
LOG_MAIL邮件系统
LOG_DAEMON守护进程
LOG_AUTH认证系统
LOG_LOCAL0-7本地使用

Writer 方法

方法严重性描述
EmergLOG_EMERG系统不可用
AlertLOG_ALERT需要立即行动
CritLOG_CRIT严重错误
ErrLOG_ERR一般错误
WarningLOG_WARNING警告
NoticeLOG_NOTICE正常但重要
InfoLOG_INFO信息
DebugLOG_DEBUG调试
Write-原始写入
Close-关闭连接

八、注意事项

1. 平台限制

// ✗ Windows 不支持
// ✗ Plan 9 不支持
// ✓ Linux、BSD、macOS 支持

2. 包已冻结

// 该包不再接受新功能
// 需要更多功能请使用第三方包
// 如:github.com/influxdata/go-syslog

3. 连接管理

// ✓ 总是关闭连接
w, _ := syslog.New(syslog.LOG_INFO, "app")
defer w.Close()

// ✓ 检查错误
if err != nil {
    log.Printf("syslog 不可用:%v", err)
}

4. 性能考虑

// syslog 是同步的
// 高并发场景考虑:
// 1. 使用缓冲通道
// 2. 批量发送
// 3. 异步处理

5. 网络故障处理

// syslog 包会尝试自动重连
// 但仍需处理连接失败情况
w, err := syslog.Dial("tcp", "server:514", syslog.LOG_INFO, "app")
if err != nil {
    // 使用本地日志作为后备
    log.Println("syslog 不可用,使用本地日志")
}

九、完整示例:企业级日志系统

package main

import (
    "fmt"
    "log"
    "log/syslog"
    "os"
    "time"
)

// EnterpriseLogger 企业级日志记录器
type EnterpriseLogger struct {
    syslog   *syslog.Writer
    fallback *log.Logger
    appName  string
}

// NewEnterpriseLogger 创建日志记录器
func NewEnterpriseLogger(appName, syslogServer string) (*EnterpriseLogger, error) {
    var (
        w   *syslog.Writer
        err error
    )
    
    // 尝试连接 syslog
    if syslogServer != "" {
        w, err = syslog.Dial("tcp", syslogServer, 
            syslog.LOG_DAEMON|syslog.LOG_INFO, appName)
        if err != nil {
            log.Printf("syslog 连接失败,使用本地日志:%v", err)
        }
    }
    
    // 创建后备 logger
    fallback := log.New(os.Stderr, fmt.Sprintf("[%s] ", appName), 
        log.Ldate|log.Ltime|log.Lshortfile)
    
    return &EnterpriseLogger{
        syslog:   w,
        fallback: fallback,
        appName:  appName,
    }, nil
}

// Debug 记录调试日志
func (el *EnterpriseLogger) Debug(format string, v ...interface{}) {
    msg := fmt.Sprintf(format, v...)
    if el.syslog != nil {
        el.syslog.Debug(msg)
    }
    el.fallback.Printf("DEBUG: "+format+"\n", v...)
}

// Info 记录信息日志
func (el *EnterpriseLogger) Info(format string, v ...interface{}) {
    msg := fmt.Sprintf(format, v...)
    if el.syslog != nil {
        el.syslog.Info(msg)
    }
    el.fallback.Printf("INFO: "+format+"\n", v...)
}

// Warning 记录警告日志
func (el *EnterpriseLogger) Warning(format string, v ...interface{}) {
    msg := fmt.Sprintf(format, v...)
    if el.syslog != nil {
        el.syslog.Warning(msg)
    }
    el.fallback.Printf("WARNING: "+format+"\n", v...)
}

// Error 记录错误日志
func (el *EnterpriseLogger) Error(format string, v ...interface{}) {
    msg := fmt.Sprintf(format, v...)
    if el.syslog != nil {
        el.syslog.Err(msg)
    }
    el.fallback.Printf("ERROR: "+format+"\n", v...)
}

// Close 关闭日志记录器
func (el *EnterpriseLogger) Close() {
    if el.syslog != nil {
        el.syslog.Close()
    }
}

func main() {
    // 从环境变量读取配置
    appName := os.Getenv("APP_NAME")
    if appName == "" {
        appName = "myapp"
    }
    
    syslogServer := os.Getenv("SYSLOG_SERVER")
    
    // 创建日志记录器
    logger, err := NewEnterpriseLogger(appName, syslogServer)
    if err != nil {
        log.Fatal(err)
    }
    defer logger.Close()
    
    // 使用示例
    logger.Info("应用启动")
    logger.Debug("配置:%+v", map[string]string{
        "app": appName,
        "syslog": syslogServer,
    })
    
    // 模拟业务逻辑
    for i := 0; i < 5; i++ {
        logger.Info("处理任务 %d", i)
        time.Sleep(time.Second)
    }
    
    logger.Warning("任务处理完成,但有警告")
    logger.Info("应用关闭")
}

最后更新: 2026-04-04
Go 版本: 1.21+
包文档: https://pkg.go.dev/log/syslog
重要提示: 该包已冻结,Windows 不支持