|
|
@@ -9,13 +9,15 @@ import (
|
|
|
"github.com/rs/zerolog"
|
|
|
)
|
|
|
|
|
|
+// nanoLogger 实现 nano 框架的日志接口
|
|
|
+// nano 是一个轻量级的游戏服务器框架,支持分布式架构
|
|
|
+// 参考: https://github.com/lonng/nano
|
|
|
type nanoLogger struct{}
|
|
|
|
|
|
-// Println 实现标准日志接口的 Println 方法,用于记录信息级别的微服务日志
|
|
|
+// Println 实现 nano.Logger 接口的 Println 方法
|
|
|
//
|
|
|
-// 该方法提供了智能的日志级别检查和性能优化:
|
|
|
-// 1. 首先检查 Info 级别的日志是否启用,避免不必要的字符串格式化开销
|
|
|
-// 2. 如果 Info 级别已启用,才执行字符串格式化和日志记录操作
|
|
|
+// 该方法为 nano 框架提供信息级别的日志记录功能
|
|
|
+// 在游戏服务器开发中,用于记录服务器运行状态、玩家操作等信息
|
|
|
//
|
|
|
// 参数:
|
|
|
//
|
|
|
@@ -25,23 +27,26 @@ type nanoLogger struct{}
|
|
|
// - 性能优化:先检查日志级别,避免不必要的字符串格式化
|
|
|
// - 调用栈调整:跳过1层调用栈,准确定位日志调用位置
|
|
|
// - 自动格式化:使用 fmt.Sprint 自动格式化各种类型参数
|
|
|
-// - 级别控制:遵循配置的日志级别,支持动态启用/禁用
|
|
|
+// - 游戏服务器优化:专为高频游戏操作日志设计
|
|
|
//
|
|
|
-// 使用示例:
|
|
|
+// 使用示例(在 nano 组件中):
|
|
|
//
|
|
|
-// logger := logx.NanoLogger()
|
|
|
-// logger.Println("微服务启动完成")
|
|
|
-// logger.Println("用户ID:", userID, "操作:", "登录")
|
|
|
-// logger.Println("请求参数:", req, "响应:", resp)
|
|
|
+// type MyComponent struct{}
|
|
|
+//
|
|
|
+// func (c *MyComponent) AfterInit() {
|
|
|
+// logger := logx.NanoLogger()
|
|
|
+// logger.Println("游戏组件初始化完成")
|
|
|
+// logger.Println("玩家ID:", playerID, "操作:", "加入房间")
|
|
|
+// }
|
|
|
//
|
|
|
// 性能优化说明:
|
|
|
// - e.Enabled() 检查可以避免在日志级别禁用时执行昂贵的字符串格式化
|
|
|
-// - 这种设计特别适合高频调用的微服务日志场景
|
|
|
+// - 这种设计特别适合高频的游戏服务器日志场景
|
|
|
// - 在生产环境中,当 Info 级别被禁用时,此方法几乎无性能开销
|
|
|
//
|
|
|
// 调用栈调整:
|
|
|
// - CallerSkipFrame(1) 跳过当前方法本身的调用栈帧
|
|
|
-// - 确保日志显示的是调用 Println 的代码位置,而不是此方法内部
|
|
|
+// - 确保日志显示的是游戏逻辑代码的位置,而不是框架内部
|
|
|
func (nanoLogger) Println(v ...interface{}) {
|
|
|
// 获取 Info 级别的日志事件,并检查该级别是否启用
|
|
|
// 这种设计避免在日志级别禁用时执行不必要的字符串格式化操作
|
|
|
@@ -53,40 +58,40 @@ func (nanoLogger) Println(v ...interface{}) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// Fatal 实现标准日志接口的 Fatal 方法,用于记录致命错误并终止程序
|
|
|
+// Fatal 实现 nano.Logger 接口的 Fatal 方法
|
|
|
//
|
|
|
-// 该方法用于处理无法恢复的严重错误,记录错误信息后会立即终止应用程序。
|
|
|
-// 在微服务架构中,Fatal 日志通常表示服务遇到了不可恢复的致命问题。
|
|
|
+// 该方法用于处理游戏服务器中无法恢复的严重错误
|
|
|
+// 记录错误信息后会立即终止服务器进程,防止数据不一致或安全风险
|
|
|
//
|
|
|
// 参数:
|
|
|
//
|
|
|
// v - 可变参数,支持任意类型的致命错误信息
|
|
|
//
|
|
|
// 功能特性:
|
|
|
-// - 立即终止:记录日志后立即调用 os.Exit(1) 终止程序
|
|
|
+// - 立即终止:记录日志后立即调用 os.Exit(1) 终止服务器
|
|
|
// - 自动格式化:使用 fmt.Sprint 自动格式化各种类型参数
|
|
|
-// - 致命级别:使用 Fatal 级别记录,便于监控系统识别
|
|
|
-// - 微服务适配:专为微服务环境优化的致命错误处理
|
|
|
+// - 致命级别:使用 Fatal 级别记录,便于运维监控
|
|
|
+// - 游戏服务器适配:专为游戏服务器环境优化的致命错误处理
|
|
|
//
|
|
|
-// 使用示例:
|
|
|
+// 使用示例(在游戏服务器组件中):
|
|
|
//
|
|
|
// logger := logx.NanoLogger()
|
|
|
//
|
|
|
-// // 数据库连接失败,无法继续运行
|
|
|
-// if err := connectDatabase(); err != nil {
|
|
|
-// logger.Fatal("数据库连接失败:", err)
|
|
|
+// // 游戏数据库连接失败,服务器无法运行
|
|
|
+// if err := connectGameDB(); err != nil {
|
|
|
+// logger.Fatal("游戏数据库连接失败:", err)
|
|
|
// }
|
|
|
//
|
|
|
-// // 关键配置缺失,服务无法启动
|
|
|
-// if config.APIKey == "" {
|
|
|
-// logger.Fatal("API密钥配置缺失,服务无法启动")
|
|
|
+// // 游戏配置文件缺失,服务器无法启动
|
|
|
+// if config.GameConfigPath == "" {
|
|
|
+// logger.Fatal("游戏配置文件缺失,服务器无法启动")
|
|
|
// }
|
|
|
//
|
|
|
// 注意事项:
|
|
|
-// - Fatal 方法会立即终止程序,请谨慎使用
|
|
|
+// - Fatal 方法会立即终止服务器进程,请谨慎使用
|
|
|
// - 仅在遇到不可恢复的致命错误时使用
|
|
|
// - 确保在调用 Fatal 前已经记录了足够的错误上下文信息
|
|
|
-// - 微服务环境中,监控系统应该对 Fatal 日志进行告警
|
|
|
+// - 游戏服务器环境中,运维系统应该对 Fatal 日志进行告警
|
|
|
//
|
|
|
// 与 Panic 的区别:
|
|
|
// - Fatal: 记录日志后立即终止程序(os.Exit(1))
|
|
|
@@ -98,10 +103,10 @@ func (nanoLogger) Fatal(v ...interface{}) {
|
|
|
nanoWriter.Fatal().Msg(fmt.Sprint(v...))
|
|
|
}
|
|
|
|
|
|
-// Fatalf 实现标准日志接口的 Fatalf 方法,用于格式化记录致命错误并终止程序
|
|
|
+// Fatalf 实现 nano.Logger 接口的 Fatalf 方法
|
|
|
//
|
|
|
-// 该方法与 Fatal 方法类似,但支持格式化字符串,便于记录结构化的致命错误信息。
|
|
|
-// 在微服务架构中,Fatalf 用于记录包含具体错误代码、状态等详细信息的致命错误。
|
|
|
+// 该方法与 Fatal 方法类似,但支持格式化字符串
|
|
|
+// 便于在游戏服务器中记录包含具体错误代码、状态等详细信息的致命错误
|
|
|
//
|
|
|
// 参数:
|
|
|
//
|
|
|
@@ -109,28 +114,28 @@ func (nanoLogger) Fatal(v ...interface{}) {
|
|
|
// v - 可变参数,用于填充格式化字符串的占位符
|
|
|
//
|
|
|
// 功能特性:
|
|
|
-// - 立即终止:记录日志后立即调用 os.Exit(1) 终止程序
|
|
|
+// - 立即终止:记录日志后立即调用 os.Exit(1) 终止服务器
|
|
|
// - 格式化支持:支持使用格式化字符串模板记录结构化错误信息
|
|
|
-// - 致命级别:使用 Fatal 级别记录,便于监控系统识别
|
|
|
-// - 微服务适配:专为微服务环境优化的格式化致命错误处理
|
|
|
+// - 致命级别:使用 Fatal 级别记录,便于运维监控
|
|
|
+// - 游戏服务器适配:专为游戏服务器环境优化的格式化致命错误处理
|
|
|
//
|
|
|
-// 使用示例:
|
|
|
+// 使用示例(在游戏服务器组件中):
|
|
|
//
|
|
|
// logger := logx.NanoLogger()
|
|
|
//
|
|
|
-// // 数据库连接失败,包含具体错误代码
|
|
|
-// if err := connectDatabase(); err != nil {
|
|
|
-// logger.Fatalf("数据库连接失败,错误码: %d, 错误信息: %s", err.Code, err.Message)
|
|
|
+// // 游戏数据库连接失败,包含具体错误代码
|
|
|
+// if err := connectGameDB(); err != nil {
|
|
|
+// logger.Fatalf("游戏数据库连接失败,错误码: %d, 错误信息: %s", err.Code, err.Message)
|
|
|
// }
|
|
|
//
|
|
|
-// // 配置验证失败,包含具体配置项
|
|
|
-// if !validateConfig(config) {
|
|
|
-// logger.Fatalf("配置验证失败,缺失配置项: %s,当前环境: %s", missingKey, env)
|
|
|
+// // 游戏配置验证失败,包含具体配置项
|
|
|
+// if !validateGameConfig(config) {
|
|
|
+// logger.Fatalf("游戏配置验证失败,缺失配置项: %s,当前环境: %s", missingKey, env)
|
|
|
// }
|
|
|
//
|
|
|
-// // 服务端口被占用
|
|
|
-// if err := startServer(port); err != nil {
|
|
|
-// logger.Fatalf("服务启动失败,端口 %d 已被占用,错误: %v", port, err)
|
|
|
+// // 游戏服务器端口被占用
|
|
|
+// if err := startGameServer(port); err != nil {
|
|
|
+// logger.Fatalf("游戏服务器启动失败,端口 %d 已被占用,错误: %v", port, err)
|
|
|
// }
|
|
|
//
|
|
|
// 格式化占位符支持:
|
|
|
@@ -142,10 +147,10 @@ func (nanoLogger) Fatal(v ...interface{}) {
|
|
|
// - 其他标准 fmt 包支持的占位符
|
|
|
//
|
|
|
// 注意事项:
|
|
|
-// - Fatalf 方法会立即终止程序,请谨慎使用
|
|
|
+// - Fatalf 方法会立即终止服务器进程,请谨慎使用
|
|
|
// - 仅在遇到不可恢复的致命错误时使用
|
|
|
// - 格式化字符串可以包含具体的错误代码、状态等详细信息
|
|
|
-// - 微服务环境中,监控系统应该对 Fatalf 日志进行告警和分析
|
|
|
+// - 游戏服务器环境中,运维系统应该对 Fatalf 日志进行告警和分析
|
|
|
func (nanoLogger) Fatalf(format string, v ...interface{}) {
|
|
|
// 使用 Fatal 级别的日志事件记录格式化致命错误信息
|
|
|
// Fatal 级别会自动调用 os.Exit(1) 终止应用程序
|
|
|
@@ -158,38 +163,39 @@ var (
|
|
|
nanoWriter *zerolog.Logger
|
|
|
)
|
|
|
|
|
|
-// InitNanoWriter 初始化微服务专用的日志写入器
|
|
|
+// InitNanoWriter 初始化 nano 游戏服务器框架专用的日志写入器
|
|
|
//
|
|
|
-// 该函数创建一个专门用于微服务架构的日志器实例,配置了适合分布式系统日志的格式。
|
|
|
-// Nano 日志器特别优化了调用栈信息,便于在微服务环境中追踪跨服务调用链。
|
|
|
+// 该函数创建一个专门用于 nano 游戏服务器框架的日志器实例
|
|
|
+// 配置了适合游戏服务器日志的格式,特别优化了调用栈信息
|
|
|
+// 便于在游戏服务器开发中追踪玩家操作和游戏逻辑调用链
|
|
|
//
|
|
|
// 参数:
|
|
|
//
|
|
|
-// writer - 微服务日志输出目标,通常是文件写入器或控制台
|
|
|
+// writer - 游戏服务器日志输出目标,通常是文件写入器或控制台
|
|
|
//
|
|
|
// 功能特性:
|
|
|
-// - 专门为微服务架构优化的日志格式
|
|
|
-// - 使用控制台格式输出,便于阅读分布式系统日志
|
|
|
+// - 专门为游戏服务器架构优化的日志格式
|
|
|
+// - 使用控制台格式输出,便于阅读游戏服务器日志
|
|
|
// - 禁用颜色输出,适合文件持久化存储
|
|
|
// - 包含时间戳和精确的调用者信息
|
|
|
-// - 跳过多层调用栈(CallerWithSkipFrameCount(3)),准确定位业务代码位置
|
|
|
-// - 实现单例模式,全局共享微服务日志器
|
|
|
+// - 跳过多层调用栈(CallerWithSkipFrameCount(3)),准确定位游戏逻辑代码位置
|
|
|
+// - 实现单例模式,全局共享游戏服务器日志器
|
|
|
//
|
|
|
// 使用示例:
|
|
|
//
|
|
|
-// // 创建微服务日志文件写入器(推荐启用异步写入)
|
|
|
+// // 创建游戏服务器日志文件写入器(推荐启用异步写入)
|
|
|
// nanoWriter := logx.DefaultWriter("nano.log", true)
|
|
|
//
|
|
|
-// // 初始化微服务日志器
|
|
|
+// // 初始化游戏服务器日志器
|
|
|
// logx.InitNanoWriter(nanoWriter)
|
|
|
//
|
|
|
-// // 获取微服务日志器接口
|
|
|
+// // 获取游戏服务器日志器接口
|
|
|
// logger := logx.NanoLogger()
|
|
|
//
|
|
|
// 注意事项:
|
|
|
-// - 微服务日志通常需要包含完整的调用链信息,便于分布式追踪
|
|
|
-// - CallerWithSkipFrameCount(3) 确保跳过框架内部调用,准确定位业务代码
|
|
|
-// - 建议在生产环境中启用异步写入以提高微服务性能
|
|
|
+// - 游戏服务器日志通常需要包含完整的调用链信息,便于追踪玩家操作
|
|
|
+// - CallerWithSkipFrameCount(3) 确保跳过框架内部调用,准确定位游戏逻辑代码
|
|
|
+// - 建议在生产环境中启用异步写入以提高游戏服务器性能
|
|
|
// - 需要先调用 logx.InitDefault() 或设置 loggingLocationName 以确保时区正确
|
|
|
func InitNanoWriter(writer io.Writer) {
|
|
|
// 创建配置完善的 zerolog 微服务日志器:
|
|
|
@@ -211,46 +217,42 @@ func InitNanoWriter(writer io.Writer) {
|
|
|
nanoWriter = &l
|
|
|
}
|
|
|
|
|
|
-// NanoLogger
|
|
|
-//
|
|
|
-// e.g.
|
|
|
+// NanoLogger 返回 nano 游戏服务器框架专用的日志器接口
|
|
|
//
|
|
|
-// # NanoLogger 返回微服务专用的日志器接口
|
|
|
-//
|
|
|
-// 该函数实现了智能的微服务日志器初始化机制:
|
|
|
-// 1. 如果已经通过 InitNanoWriter() 初始化了专用微服务日志器,则直接返回 nanoLogger 实例
|
|
|
+// 该函数实现了智能的游戏服务器日志器初始化机制:
|
|
|
+// 1. 如果已经通过 InitNanoWriter() 初始化了专用游戏服务器日志器,则直接返回 nanoLogger 实例
|
|
|
// 2. 如果没有初始化,则自动创建一个临时的控制台输出日志器作为回退方案
|
|
|
//
|
|
|
// 返回值:
|
|
|
//
|
|
|
-// nanoLogger - 实现了标准日志接口的微服务日志器
|
|
|
+// nanoLogger - 实现了 nano.Logger 接口的游戏服务器日志器
|
|
|
//
|
|
|
// 主要用途:
|
|
|
-// 1. 为微服务框架提供兼容的日志器接口
|
|
|
-// 2. 确保即使没有显式初始化,微服务也能正常使用日志功能
|
|
|
-// 3. 支持分布式系统中的日志记录和追踪
|
|
|
+// 1. 为 nano 游戏服务器框架提供兼容的日志器接口
|
|
|
+// 2. 确保即使没有显式初始化,游戏服务器也能正常使用日志功能
|
|
|
+// 3. 支持游戏服务器中的玩家操作和游戏逻辑日志记录
|
|
|
//
|
|
|
-// 使用示例:
|
|
|
+// 使用示例(在 nano 组件中):
|
|
|
//
|
|
|
-// // 配置微服务框架使用自定义日志器
|
|
|
+// // 配置 nano 框架使用自定义日志器
|
|
|
// nano.WithLogger(logx.NanoLogger())
|
|
|
//
|
|
|
// 功能特性:
|
|
|
// - 懒加载初始化:首次调用时自动创建日志器实例
|
|
|
// - 智能回退:无专用配置时使用控制台输出作为回退
|
|
|
// - 颜色支持:启用颜色输出便于控制台调试
|
|
|
-// - 精确调用栈:跳过3层调用栈,准确定位业务代码
|
|
|
+// - 精确调用栈:跳过3层调用栈,准确定位游戏逻辑代码
|
|
|
// - 线程安全:单例模式确保全局一致性
|
|
|
//
|
|
|
// 智能初始化逻辑:
|
|
|
// - 检查 nanoWriter 单例是否已初始化
|
|
|
// - 如果未初始化,创建临时控制台日志器并存储为单例
|
|
|
-// - 返回 nanoLogger 结构体实例,该结构体实现了标准日志接口
|
|
|
+// - 返回 nanoLogger 结构体实例,该结构体实现了 nano.Logger 接口
|
|
|
//
|
|
|
// 最佳实践:
|
|
|
// - 生产环境建议先调用 InitNanoWriter() 初始化专用文件日志器
|
|
|
// - 开发环境可以使用自动回退的控制台日志器进行调试
|
|
|
-// - 微服务环境中确保所有服务使用相同的日志配置
|
|
|
+// - 游戏服务器环境中确保所有组件使用相同的日志配置
|
|
|
func NanoLogger() nanoLogger {
|
|
|
// 检查微服务日志器单例是否已经初始化
|
|
|
// 如果未初始化,执行懒加载初始化流程
|