kit

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

kit - 结构化日志库

基于 Go 标准库 log/slog 的日志封装,支持上下文提取、webhook 通知和堆栈跟踪。

特性

  • 标准库兼容: 基于 log/slog,与 Go 生态无缝集成
  • 上下文感知: 自动从 context 提取 trace_id, request_id, user_id
  • Webhook 通知: 支持 Error 级别自动触发 webhook(企业微信、飞书等)
  • 堆栈跟踪: 可配置的调用者信息和堆栈跟踪
  • 灵活配置: 全局默认 + 实例级覆盖的 context key 配置

快速开始

package main

import (
    "context"
    "github.com/tsopia/go-kit/kit"
)

func main() {
    // 初始化
    kit.Init(kit.Options{
        Level:  "info",
        Format: kit.FormatJSON,
    })

    // 使用
    ctx := context.WithValue(context.Background(), "trace_id", "abc-123")
    kit.Info(ctx, "服务启动", "port", 8080)
    // 输出: {"time":"...","level":"INFO","msg":"服务启动","trace_id":"abc-123","port":8080}
}

API 概览

日志级别
kit.Debug(ctx, "调试信息", "key", "value")
kit.Info(ctx, "普通信息")
kit.Warn(ctx, "警告信息")
kit.Error(ctx, "错误信息")
kit.Fatal(ctx, "致命错误")  // 输出后 os.Exit(1)
kit.Panic(ctx, "严重错误")  // 输出后 panic()
格式化日志
kit.Infof(ctx, "用户 %d 登录", userID)
kit.Errorf(ctx, "操作失败: %v", err)
链式调用
logger := kit.WithCtx(ctx)
logger.Info("步骤1")
logger.Info("步骤2")

配置选项

基本配置
kit.Init(kit.Options{
    Level:      "info",             // 日志级别: debug, info, warn, error, fatal, panic
    Format:     kit.FormatJSON,     // 格式: JSON 或 Text
    Output:     os.Stdout,          // 输出目标
    AddCaller:  true,               // 是否添加调用者信息
    TimeFormat: time.RFC3339,       // 时间格式
})
Context Key 配置
// 方式1: 全局设置(推荐)
kit.SetDefaultContextKeys(kit.ContextKeys{
    Trace:   []string{"trace_id", "x-trace-id", "X-Trace-Id"},
    Request: []string{"request_id", "x-request-id"},
    User:    []string{"user_id", "userId"},
})

// 方式2: 实例级设置
logger := kit.New(kit.Options{
    ContextKeys: &kit.ContextKeys{
        Trace: []string{"uber-trace-id"},
        Custom: map[string][]string{
            "tenant_id": {"tenant_id", "x-tenant-id"},
        },
    },
})
Webhook 配置
// 添加 webhook 通知
kit.AddWebhook(&kit.WebhookConfig{
    Name: "feishu-alert",
    URL:  "https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
    BuildPayload: func(ctx context.Context, r kit.LogRecord) map[string]interface{} {
        return map[string]interface{}{
            "msg_type": "text",
            "content": map[string]string{
                "text": fmt.Sprintf("@oncall %s: %s", r.Caller, r.Message),
            },
        }
    },
    // 可选:自定义过滤
    Filter: func(ctx context.Context, r kit.LogRecord) bool {
        return r.Level >= kit.ErrorLevel  // ErrorLevel, FatalLevel, PanicLevel
    },
})
堆栈跟踪配置
kit.Init(kit.Options{
    StackTrace: kit.StackTraceConfig{
        Enabled:     true,              // 启用堆栈跟踪
        Level:       kit.ErrorLevel,    // Level 类型: ErrorLevel, FatalLevel, PanicLevel
        Depth:       32,                // 堆栈深度
        SkipRuntime: true,              // 跳过 runtime 帧
    },
})

完整示例

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/tsopia/go-kit/kit"
)

func main() {
    // 1. 初始化
    kit.Init(kit.Options{
        Level:      "info",              // 字符串级别: debug, info, warn, error, fatal, panic
        Format:     kit.FormatJSON,
        AddCaller:  true,
        StackTrace: kit.StackTraceConfig{
            Enabled: true,
            Level:   kit.ErrorLevel,      // StackTraceConfig.Level 仍是 Level 类型
        },
        ContextKeys: &kit.ContextKeys{
            Trace:   []string{"trace_id", "x-trace-id"},
            Request: []string{"request_id"},
        },
    })

    // 2. 添加告警 webhook
    kit.AddWebhook(&kit.WebhookConfig{
        Name: "alerts",
        URL:  os.Getenv("WEBHOOK_URL"),
        BuildPayload: func(ctx context.Context, r kit.LogRecord) map[string]interface{} {
            return map[string]interface{}{
                "text": fmt.Sprintf("@oncall [%s] %s", r.Caller, r.Message),
            }
        },
    })

    // 3. 使用
    ctx := context.Background()
    ctx = context.WithValue(ctx, "trace_id", "abc-123")
    ctx = context.WithValue(ctx, "request_id", "req-456")

    kit.Info(ctx, "服务启动", "port", 8080)

    // Error 会自动触发 webhook
    kit.Error(ctx, "数据库连接失败", "error", "timeout")
}

日志格式示例

JSON 格式
{
  "time": "2024-01-15T10:30:00+08:00",
  "level": "ERROR",
  "msg": "数据库连接失败",
  "trace_id": "abc-123",
  "request_id": "req-456",
  "error": "timeout",
  "caller": "db/conn.go:45",
  "stack_trace": "db/conn.go:45\nservice/user.go:88"
}
Text 格式
time=2024-01-15T10:30:00+08:00 level=ERROR msg="数据库连接失败" trace_id=abc-123 request_id=req-456 caller=db/conn.go:45

与标准库 slog 的关系

本包基于 log/slog 实现,你可以获取底层的 slog.Logger

logger := kit.New(kit.Options{})
slogLogger := logger.GetSlog()

也可以与标准库 slog 混合使用:

// 使用本包记录业务日志
kit.Info(ctx, "业务日志")

// 使用标准库记录系统日志
slog.Info("系统日志")

最佳实践

  1. 始终传递 context: kit.Info(ctx, msg, fields...)
  2. 结构化优于格式化: 优先使用 kit.Info(ctx, msg, "key", value) 而非 kit.Infof
  3. 配置全局默认值: 在 main 函数中配置一次 kit.SetDefaultContextKeys
  4. Error 级别用于可恢复错误: 使用 kit.Error 记录错误但继续执行
  5. Fatal 仅用于不可恢复错误: 如配置加载失败、数据库连接失败等

Documentation

Overview

Package kit 提供基于标准库 slog 的日志封装,支持上下文提取、webhook 通知和堆栈跟踪。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddWebhook

func AddWebhook(config *WebhookConfig)

AddWebhook 添加 webhook 到全局日志记录器

func Debug

func Debug(ctx context.Context, msg string, fields ...any)

Debug 输出调试日志到全局记录器

func Debugf

func Debugf(ctx context.Context, format string, args ...any)

Debugf 输出格式化调试日志到全局记录器

func Error

func Error(ctx context.Context, msg string, fields ...any)

Error 输出错误日志到全局记录器

func Errorf

func Errorf(ctx context.Context, format string, args ...any)

Errorf 输出格式化错误日志到全局记录器

func Fatal

func Fatal(ctx context.Context, msg string, fields ...any)

Fatal 输出致命错误日志到全局记录器并退出程序

func Fatalf

func Fatalf(ctx context.Context, format string, args ...any)

Fatalf 输出格式化致命错误日志到全局记录器并退出程序

func Info

func Info(ctx context.Context, msg string, fields ...any)

Info 输出信息日志到全局记录器

func Infof

func Infof(ctx context.Context, format string, args ...any)

Infof 输出格式化信息日志到全局记录器

func Init

func Init(opts Options)

Init 使用指定选项初始化全局日志记录器

func Panic

func Panic(ctx context.Context, msg string, fields ...any)

Panic 输出 panic 日志到全局记录器并触发 panic

func Panicf

func Panicf(ctx context.Context, format string, args ...any)

Panicf 输出格式化 panic 日志到全局记录器并触发 panic

func SetDefaultContextKeys

func SetDefaultContextKeys(keys ContextKeys)

SetDefaultContextKeys 设置全局默认 context keys

func SetLevel

func SetLevel(level string)

SetLevel 设置全局日志级别 level 可以是: "debug", "info", "warn", "error", "fatal", "panic"

func Warn

func Warn(ctx context.Context, msg string, fields ...any)

Warn 输出警告日志到全局记录器

func Warnf

func Warnf(ctx context.Context, format string, args ...any)

Warnf 输出格式化警告日志到全局记录器

func WithCtx

func WithCtx(ctx context.Context) *contextLogger

WithCtx 返回绑定到指定上下文的全局日志记录器

Types

type ContextKeys

type ContextKeys struct {
	// Trace trace ID 可能的 key 列表,按优先级查找
	Trace []string
	// Request request ID 可能的 key 列表,按优先级查找
	Request []string
	// User user ID 可能的 key 列表,按优先级查找
	User []string
	// Custom 自定义字段映射,key 为日志字段名,value 为可能的 context key 列表
	// 例如:{"session_id": ["session_id", "sid", "x-session-id"]}
	Custom map[string][]string
}

ContextKeys 定义要从 context 中提取的 keys

type Format

type Format string

Format 日志格式类型

const (
	// FormatJSON JSON 格式输出
	FormatJSON Format = "json"
	// FormatText 文本格式输出
	FormatText Format = "text"
)

func (Format) String

func (f Format) String() string

String 返回格式字符串

type Level

type Level int

Level 日志级别

const (
	// DebugLevel 调试级别
	DebugLevel Level = iota - 1
	// InfoLevel 信息级别
	InfoLevel
	// WarnLevel 警告级别
	WarnLevel
	// ErrorLevel 错误级别
	ErrorLevel
	// FatalLevel 致命错误级别(会调用 os.Exit(1))
	FatalLevel
	// PanicLevel Panic 级别(会调用 panic)
	PanicLevel
)

func ParseLevel

func ParseLevel(s string) Level

ParseLevel 从字符串解析日志级别 输入字符串会转成大写后匹配,如 "info", "INFO", "Info" 都能正确解析

func (Level) String

func (l Level) String() string

String 返回日志级别字符串

type LogRecord

type LogRecord struct {
	Level      Level
	Message    string
	Time       time.Time
	TraceID    string
	RequestID  string
	UserID     string
	Caller     string
	StackTrace string
	Fields     map[string]interface{}
}

LogRecord 日志记录信息,用于 webhook

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger 日志记录器

func New

func New(opts Options) *Logger

New 创建新的日志记录器

func (*Logger) Debug

func (l *Logger) Debug(ctx context.Context, msg string, fields ...any)

Debug 输出调试日志

func (*Logger) Debugf

func (l *Logger) Debugf(ctx context.Context, format string, args ...any)

Debugf 输出格式化调试日志

func (*Logger) Error

func (l *Logger) Error(ctx context.Context, msg string, fields ...any)

Error 输出错误日志

func (*Logger) Errorf

func (l *Logger) Errorf(ctx context.Context, format string, args ...any)

Errorf 输出格式化错误日志

func (*Logger) Fatal

func (l *Logger) Fatal(ctx context.Context, msg string, fields ...any)

Fatal 输出致命错误日志并退出程序

func (*Logger) Fatalf

func (l *Logger) Fatalf(ctx context.Context, format string, args ...any)

Fatalf 输出格式化致命错误日志并退出程序

func (*Logger) Info

func (l *Logger) Info(ctx context.Context, msg string, fields ...any)

Info 输出信息日志

func (*Logger) Infof

func (l *Logger) Infof(ctx context.Context, format string, args ...any)

Infof 输出格式化信息日志

func (*Logger) Panic

func (l *Logger) Panic(ctx context.Context, msg string, fields ...any)

Panic 输出 panic 日志并触发 panic

func (*Logger) Panicf

func (l *Logger) Panicf(ctx context.Context, format string, args ...any)

Panicf 输出格式化 panic 日志并触发 panic

func (*Logger) SetLevel

func (l *Logger) SetLevel(level string)

SetLevel 设置日志级别 level 可以是: "debug", "info", "warn", "error", "fatal", "panic"

func (*Logger) Sync

func (l *Logger) Sync() error

Sync 同步日志缓冲区

func (*Logger) Warn

func (l *Logger) Warn(ctx context.Context, msg string, fields ...any)

Warn 输出警告日志

func (*Logger) Warnf

func (l *Logger) Warnf(ctx context.Context, format string, args ...any)

Warnf 输出格式化警告日志

func (*Logger) WithCtx

func (l *Logger) WithCtx(ctx context.Context) *contextLogger

WithCtx 返回绑定到指定上下文的 Logger 用于链式调用场景

func (*Logger) Write

func (l *Logger) Write(p []byte) (n int, err error)

Write implements io.Writer for compatibility

type Options

type Options struct {
	// Level 日志级别,默认 "info"
	// 支持: "debug", "info", "warn", "error", "fatal", "panic"
	Level string

	// Format 输出格式,默认 FormatJSON
	Format Format

	// Output 输出目标,默认 os.Stdout
	// 可以通过 io.MultiWriter(os.Stdout, file) 同时输出到多个目标
	Output io.Writer

	// AddCaller 是否添加调用者信息(文件:行号),默认 true
	AddCaller bool

	// StackTrace 堆栈跟踪配置
	StackTrace StackTraceConfig

	// ContextKeys 上下文提取配置,如果不设置使用全局默认值
	ContextKeys *ContextKeys

	// Webhooks webhook 配置列表,错误级别自动触发
	Webhooks []*WebhookConfig

	// TimeFormat 时间格式,默认 time.RFC3339
	TimeFormat string

	// Color 是否启用颜色输出(仅文本格式),默认 false
	Color bool
}

Options 日志配置选项

type StackTraceConfig

type StackTraceConfig struct {
	// Enabled 是否启用堆栈跟踪
	Enabled bool
	// Level 触发堆栈的最小级别,默认 Error
	Level Level
	// Depth 堆栈深度,默认 32
	Depth int
	// SkipRuntime 是否跳过 runtime 帧,默认 true
	SkipRuntime bool
}

StackTraceConfig 堆栈跟踪配置

type WebhookBuildPayload

type WebhookBuildPayload func(ctx context.Context, record LogRecord) map[string]interface{}

WebhookBuildPayload 自定义 payload 构建函数类型

type WebhookConfig

type WebhookConfig struct {
	// Name webhook 名称,用于标识
	Name string

	// URL 接收地址(必填)
	URL string

	// Method 请求方法,默认 POST
	Method string

	// Headers 额外请求头
	Headers map[string]string

	// BuildPayload 自定义 payload 构建函数
	// 如果为空,使用默认 payload 格式
	BuildPayload WebhookBuildPayload

	// Filter 过滤函数,只有返回 true 才发送
	// 如果为空,默认只发送 Error 及以上级别
	Filter WebhookFilter

	// Timeout 请求超时,默认 5 秒
	Timeout time.Duration
}

WebhookConfig Webhook 配置

type WebhookFilter

type WebhookFilter func(ctx context.Context, record LogRecord) bool

WebhookFilter 日志过滤函数类型

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL