Skip to content

Conversation

@Bronya0
Copy link
Contributor

@Bronya0 Bronya0 commented Jul 25, 2025

  • 新增 FORMAT_JSON 格式化标志- 实现 formatJSON 函数用于生成 JSON 格式的日志- 在 logger 中集成 JSON 格式化功能
  • 添加 LogEntry 类型和相关方法支持结构化日志

1、使用:

// 方法一:通过 SetFormat
// logger.SetFormat(logger.FORMAT_JSON)

// 方法二:通过 SetOption (推荐)
logger.SetOption(&logger.Option{
    Level:      logger.LEVEL_INFO,
    Console:    true,
    Format:     logger.FORMAT_JSON, // 关键:设置格式为 JSON
    FileOption: &logger.FileTimeMode{
        // ... 文件配置
    },
})

2、自定义附加字段

// 简单的 JSON 日志
logger.Info("User logged in successfully")

// 输出:
// {"level":"info","message":"User logged in successfully","time":"2025-07-25T09:30:00.123456Z"}

// 带有结构化字段的日志
req_id := "a7b3c9-12f4-8dd1"
user_id := 10086

logger.WithField("user_id", user_id).WithField("request_id", req_id).Warn("Payment processing failed")

// 输出:
// {"level":"warn","message":"Payment processing failed","request_id":"a7b3c9-12f4-8dd1","time":"2025-07-25T09:30:01.234567Z","user_id":10086}

// 使用 WithFields
logger.WithFields(logger.Fields{
    "ip_address": "192.168.1.100",
    "latency_ms": 25.5,
}).Info("API request received")

// 输出:
// {"ip_address":"192.168.1.100","latency_ms":25.5,"level":"info","message":"API request received","time":"2025-07-25T09:30:02.345678Z"}

3、压测见下面第一个,当前仅实现功能,后期进一步改进性能,例如提供json接口让用户支持使用更高性能的json库。

cpu: Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz
BenchmarkSerialJSONLogger-16              176008              6682 ns/op             982 B/op         24 allocs/op
BenchmarkSerialLogger-16                  277548              4362 ns/op             104 B/op          4 allocs/op
BenchmarkParallelLogger-16               1698648               692.3 ns/op           155 B/op          5 allocs/op
BenchmarkSerialSlog-16                    228252              5120 ns/op             336 B/op          6 allocs/op
BenchmarkParallelSLog-16                  228825              4820 ns/op             337 B/op          6 allocs/op
BenchmarkMixedMode-16                    2790825               493.9 ns/op           112 B/op          5 allocs/op

tangwuhong added 2 commits July 25, 2025 18:16
- 新增 FORMAT_JSON 格式化标志- 实现 formatJSON 函数用于生成 JSON 格式的日志- 在 logger 中集成 JSON 格式化功能
- 添加 LogEntry 类型和相关方法支持结构化日志
- 将 MaxBuckup 方法名更正为 MaxBackup,避免潜在的错误
@Bronya0
Copy link
Contributor Author

Bronya0 commented Jul 25, 2025

@donnie4w  ̄へ ̄

@donnie4w
Copy link
Owner

hi @Bronya0
实际上 logger 本身可以构造json输出格式,无需特别增加函数来支持,由于之前我没有给出示例,这部分没有人使用,这部分有一些小bug我已经修正,可以更新一下测试,测试用例 0_29_0_test

示例:

// 通过 Formatter 构造json格式输出
// 说明:
// {level} 日志级别数据
// {time}  日志时间
// {file}  日志文件
// {message}  日志内容
func Test_formater(t *testing.T) {
	logger.SetOption(&logger.Option{Console: true, Formatter: `{"level":"{level}","time":"{time}","file":"{file}","message":"{message}"}` + "\n"})
	logger.Debug("this is a debug message")
	logger.Info("this is a info message")
	logger.Warn("this is a warn message")
	logger.Error("this is a error message")
}

输出

{"level":"[DEBUG]","time":"2025/07/27 15:40:26","file":"0_29_0_test.go:16","message":"this is a debug message"}
{"level":"[INFO]","time":"2025/07/27 15:40:26","file":"0_29_0_test.go:17","message":"this is a info message"}
{"level":"[WARN]","time":"2025/07/27 15:40:26","file":"0_29_0_test.go:18","message":"this is a warn message"}
{"level":"[ERROR]","time":"2025/07/27 15:40:26","file":"0_29_0_test.go:19","message":"this is a error message"}

示例2

// 自定义json格式的参数
// 比如修改LEVEL的格式,同理,可以修改时间的格式
func Test_formater2(t *testing.T) {
	levelFmt := func(level logger.LEVELTYPE) string {
		switch level {
		case logger.LEVEL_DEBUG:
			return "debug"
		case logger.LEVEL_INFO:
			return "info"
		case logger.LEVEL_FATAL:
			return "fatal"
		case logger.LEVEL_WARN:
			return "warn"
		case logger.LEVEL_ERROR:
			return "error"
		default:
			return "unknown"
		}
	}
	logger.SetOption(&logger.Option{Console: true, Format: logger.FORMAT_LEVELFLAG | logger.FORMAT_DATE | logger.FORMAT_TIME, Formatter: `{"level":"{level}","time":"{time}","message":"{message}"}` + "\n", AttrFormat: &logger.AttrFormat{SetLevelFmt: levelFmt}})
	logger.Debug("this is a debug message")
	logger.Info("this is a info message")
	logger.Warn("this is a warn message")
	logger.Error("this is a error message")
}

输出

{"level":"debug","time":"2025/07/27 15:43:09","message":"this is a debug message"}
{"level":"info","time":"2025/07/27 15:43:09","message":"this is a info message"}
{"level":"warn","time":"2025/07/27 15:43:09","message":"this is a warn message"}
{"level":"error","time":"2025/07/27 15:43:09","message":"this is a error message"}

@Bronya0
Copy link
Contributor Author

Bronya0 commented Jul 27, 2025

好吧,我感觉封装成api更好点,更重要的是支持自定义字段

@donnie4w
Copy link
Owner

@Bronya0
是的,能支持自定义键值对对于JSON格式很关键,使用logger.WithField("user_id", user_id).WithField("request_id", req_id)的链式方式可能不太直观,比较理想的方式是类似这种调用方式

logger.Warn("Payment failed", 
    logger.Any("user", user),
    logger.String("request_id", req_id),
    logger.Int("status", status),
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants