Skip to content

About

一个支持 异步、批量、重试、多通道分发 的 Go logging 扩展库,适用于高吞吐日志处理与消息通知场景。

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

gologging-ext

Go Version License Go Report Card Release

一个支持 异步、批量、重试、多通道分发 的 Go logging 扩展库,适用于高吞吐日志处理与消息通知场景。


✨特性

  • 🚀 异步处理:解耦业务线程,提高性能
  • 📦 批量写入:减少 IO / 网络开销
  • 🔁 失败重试:提升日志可靠性
  • 🔀 多通道分发:支持同时写入多个 sink
  • 🔌 插件化 adapters:支持 zap、zerolog 等扩展

📦安装

go get github.com/cnmax/gologging-ext

🔌可选依赖(Adapters)

  • zap
    go get github.com/cnmax/gologging-ext/adapters/zap
  • zerolog
    go get github.com/cnmax/gologging-ext/adapters/zerolog

🚀快速开始

slog(标准库)

package tests

import (
    "context"
    "log/slog"
    "os"
    "testing"
    "time"

    slogAdapter "github.com/cnmax/gologging-ext/adapters/slog"
    "github.com/cnmax/gologging-ext/pipeline"
    "github.com/cnmax/gologging-ext/sinks/cls"
    "github.com/cnmax/gologging-ext/sinks/telegram"
    "github.com/cnmax/gologging-ext/sinks/wechat"
)

func TestSlogAdapter(t *testing.T) {

    ctx := context.Background()

    clsSink := cls.New(
        ctx,
        "ap-shanghai.cls.tencentcs.com",
        "your-secret-id",
        "your-secret-key",
        "your-topic-id",
    )

    wechatSink := wechat.New(
        ctx,
        "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx",
    )

    telegramSink := telegram.New(
        ctx,
        "your-bot-token",
        your-chat-id,
    )

    dispatcher := pipeline.NewDispatcher(
        pipeline.Build(clsSink),
        //pipeline.Build(telegramSink),
        pipeline.NewAsync(
            pipeline.NewRetry(telegramSink, 3, time.Second),
        ),
    )

    //logger := slog.New(slogAdapter.NewHandler(dispatcher, slog.LevelInfo))

    multi := slog.NewMultiHandler(
        slog.NewTextHandler(os.Stdout, nil),
        slogAdapter.NewHandler(dispatcher, slog.LevelInfo),
        slogAdapter.NewHandler(pipeline.NewAsync(wechatSink), slog.LevelError),
    )

    logger := slog.New(multi)
    slog.SetDefault(logger)

    slog.Error("发生错误了", "user", "xxx", "age", 18)

    time.Sleep(10 * time.Second)
}

zap

package tests

import (
    "context"
    "os"
    "testing"
    "time"

    zapAdapter "github.com/cnmax/gologging-ext/adapters/zap"
    "github.com/cnmax/gologging-ext/pipeline"
    "github.com/cnmax/gologging-ext/sinks/cls"
    "github.com/cnmax/gologging-ext/sinks/telegram"
    "github.com/cnmax/gologging-ext/sinks/wechat"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
)

func TestZapAdapter(t *testing.T) {

    ctx := context.Background()

    clsSink := cls.New(
        ctx,
        "ap-shanghai.cls.tencentcs.com",
        "your-secret-id",
        "your-secret-key",
        "your-topic-id",
    )

    wechatSink := wechat.New(
        ctx,
        "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx",
    )

    telegramSink := telegram.New(
        ctx,
        "your-bot-token",
        your-chat-id,
    )

    dispatcher := pipeline.NewDispatcher(
        pipeline.Build(clsSink),
        //pipeline.Build(telegramSink),
        pipeline.NewAsync(
            pipeline.NewRetry(telegramSink, 3, time.Second),
        ),
    )

    multi := zapcore.NewTee(
        zapcore.NewCore(
            zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
            zapcore.AddSync(os.Stdout),
            zapcore.InfoLevel,
        ),
        zapAdapter.NewCore(dispatcher, zapcore.InfoLevel),
        zapAdapter.NewCore(pipeline.NewAsync(wechatSink), zapcore.ErrorLevel),
    )
    logger := zap.New(
        multi,
        zap.AddCaller(),
        //zap.AddStacktrace(zapcore.ErrorLevel),
    )
    zap.ReplaceGlobals(logger)

    zap.L().Error(
        "发生错误了",
        zap.String("user", "xxx"),
        zap.Int("age", 18),
    )

    time.Sleep(10 * time.Second)
}

zerolog

package tests

import (
    "context"
    "os"
    "testing"
    "time"

    zerologAdapter "github.com/cnmax/gologging-ext/adapters/zerolog"
    "github.com/cnmax/gologging-ext/pipeline"
    "github.com/cnmax/gologging-ext/sinks/cls"
    "github.com/cnmax/gologging-ext/sinks/telegram"
    "github.com/cnmax/gologging-ext/sinks/wechat"
    "github.com/rs/zerolog"
    "github.com/rs/zerolog/log"
)

func TestZerologAdapter(t *testing.T) {

    ctx := context.Background()

    clsSink := cls.New(
        ctx,
        "ap-shanghai.cls.tencentcs.com",
        "your-secret-id",
        "your-secret-key",
        "your-topic-id",
    )

    wechatSink := wechat.New(
        ctx,
        "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx",
    )

    telegramSink := telegram.New(
        ctx,
        "your-bot-token",
        your-chat-id,
    )

    dispatcher := pipeline.NewDispatcher(
        pipeline.Build(clsSink),
        //pipeline.Build(telegramSink),
        pipeline.NewAsync(
            pipeline.NewRetry(telegramSink, 3, time.Second),
        ),
    )

    multi := zerolog.MultiLevelWriter(
        zerolog.ConsoleWriter{Out: os.Stdout},
        zerologAdapter.NewWriter(dispatcher, zerolog.InfoLevel),
        zerologAdapter.NewWriter(pipeline.NewAsync(wechatSink), zerolog.ErrorLevel),
    )

    logger := zerolog.
        New(multi).
        With().Timestamp().Logger().
        With().Caller().Logger()
    log.Logger = logger

    log.Error().
        Str("user", "xxx").
        Int("v", 18).
        Msg("发生错误了")

    time.Sleep(10 * time.Second)
}

🧩Sink

支持扩展多种输出目标(可结合 async / batch / retry 使用):

腾讯云 CLS

用于日志上报至 CLS(Cloud Log Service)

func New(ctx context.Context, endpoint, secretID, secretKey, topicID string, opts ...Option) core.Writer

参数

  • endpoint CLS接入地址
  • secretID 腾讯云密钥
  • secretKey 腾讯云密钥
  • topicID 日志主题 ID

微信机器人

用于企业微信群告警通知

func New(ctx context.Context, webhook string, opts ...Option) core.Writer

参数

  • webhook 企业微信机器人地址

Telegram

用于机器人消息推送

func New(ctx context.Context, token string, chatID int, opts ...Option) core.Writer

参数

  • token Telegram Bot Token
  • chatID 聊天 ID

钉钉机器人

用于企业告警通知

func New(ctx context.Context, accessToken, secret string, opts ...Option) core.Writer

参数

  • accessToken Webhook URL 中的 access_token
  • secret 签名密钥(开启加签时必填)

飞书机器人

用于团队消息推送

func New(ctx context.Context, webhook, secret string, opts ...Option) core.Writer

参数

  • webhook 飞书机器人地址
  • secret 签名密钥(开启加签时必填)

🔧自定义 Sink

实现 core.Writer 接口即可:

type Writer interface {
    Write(entry *Entry) error
}

示例:

type MySink struct{}

func (s *MySink) Write(entry *core.Entry) error {
    // 自定义处理逻辑
    return nil
}

🏗️Pipeline Builder

Pipeline Builder 提供了一种灵活的方式来配置日志处理管道,支持异步、批量、重试等特性的组合。

使用方法

import (
    "time"

    "github.com/cnmax/gologging-ext/pipeline"
    "github.com/cnmax/gologging-ext/sinks/cls"
)

// 默认配置
sink := cls.New(ctx, endpoint, secretID, secretKey, topicID)
writer := pipeline.Build(sink)

// 自定义配置
writer := pipeline.Build(sink, &pipeline.BuildOptions{
    EnableAsync:    true,
    EnableBatch:    true,
    EnableRetry:    true,
    BatchSize:      200,
    FlushInterval:  5 * time.Second,
    MaxRetries:     5,
    BaseDelay:      200 * time.Millisecond,
})

// 仅启用异步
writer := pipeline.Build(sink, &pipeline.BuildOptions{
    EnableAsync:    true,
    EnableBatch:    false,
    EnableRetry:    false,
})

// 与其他管道组合使用
dispatcher := pipeline.NewDispatcher(
    pipeline.Build(clsSink),  // CLS sink 使用默认配置
    pipeline.Build(telegramSink, &pipeline.BuildOptions{  // Telegram 自定义配置
        EnableAsync:    true,
        EnableRetry:    true,
        EnableBatch:    false,  // 消息通知不需要批量
        MaxRetries:     3,
    }),
    pipeline.Build(wechatSink, &pipeline.BuildOptions{  // 微信告警
        EnableAsync:    true,
        EnableBatch:    false,
        EnableRetry:    true,
        MaxRetries:     5,
        BaseDelay:      1 * time.Second,
    }),
)

BuildOptions 配置项

type BuildOptions struct {
    // 功能开关
    EnableAsync bool
    EnableBatch bool
    EnableRetry bool

    // 批量配置
    BatchSize     int
    FlushInterval time.Duration

    // 重试配置
    MaxRetries int
    BaseDelay  time.Duration
}

默认配置

DefaultBuildOptions() = &BuildOptions{
    EnableAsync:    true,
    EnableBatch:    true,
    EnableRetry:    true,
    BatchSize:      100,
    FlushInterval:  2 * time.Second,
    MaxRetries:     3,
    BaseDelay:      100 * time.Millisecond,
}

📌适用场景

  • 日志聚合 / 转发
  • 告警 / 通知系统(飞书、钉钉、Webhook 等)
  • 多目标日志输出(文件 + 云服务)

About

一个支持 异步、批量、重试、多通道分发 的 Go logging 扩展库,适用于高吞吐日志处理与消息通知场景。

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages