GoFrame 框架培训大纲 - 第6章:日志与监控
6.1 日志系统
6.1.1 日志配置
- 基本日志配置
# config.yaml
logger:
default:
level: "all" # 日志级别
stdout: true # 是否输出到控制台
file: "logs/app.log" # 日志文件路径
rotate:
max-size: 100 # 单个日志文件最大大小(MB)
max-age: 7 # 日志保留天数
max-backups: 5 # 最大备份文件数
- 日志配置初始化
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/glog"
)
// 自定义日志配置
func initLogger() {
// 设置默认日志配置
g.Log().SetConfigWithMap(g.Map{
"level": "all",
"stdout": true,
"file": "logs/app.log",
})
}
6.1.2 日志级别
// 日志级别定义
const (
FATAL = iota // 致命错误
ERROR // 错误
WARN // 警告
INFO // 信息
DEBUG // 调试
TRACE // 跟踪
)
// 日志级别使用示例
func logLevelDemo() {
// 不同级别日志记录
g.Log().Debug(ctx, "调试信息")
g.Log().Info(ctx, "普通信息")
g.Log().Warning(ctx, "警告信息")
g.Log().Error(ctx, "错误信息")
g.Log().Fatal(ctx, "致命错误")
}
6.1.3 日志格式
- 自定义日志格式
func customLogFormat() {
// 自定义日志格式
g.Log().SetConfigWithMap(g.Map{
"format": "[{level}] {datetime} {file}:{line} - {message}",
})
// 示例日志输出
g.Log().Info(ctx, "用户登录", g.Map{
"username": "john_doe",
"ip": "192.168.1.100",
})
}
- 结构化日志
func structuredLogging() {
// 结构化日志记录
g.Log().Info(ctx, "用户操作", g.Map{
"action": "login",
"user": g.Map{
"id": 1001,
"username": "john_doe",
},
"timestamp": time.Now(),
})
}
6.1.4 日志输出
- 多输出目标
func multiOutputLogger() {
// 配置多输出目标
g.Log().SetConfigWithMap(g.Map{
"stdout": true, // 控制台输出
"file": "app.log", // 文件输出
"redis": true, // Redis输出(可选)
})
}
- 日志分割与归档
func logRotation() {
// 日志轮转配置
g.Log().SetConfigWithMap(g.Map{
"file": "logs/app.log",
"rotate": g.Map{
"max-size": 100, // 100MB触发轮转
"max-age": 7, // 保留7天日志
"max-backups": 5, // 最多5个备份文件
"compress": true, // 压缩历史日志文件
},
})
}
6.2 链路追踪
6.2.1 链路追踪配置
- 基本配置
# config.yaml
tracer:
default:
enabled: true
type: jaeger
endpoint: "http://localhost:14268/api/traces"
sampling-rate: 1.0
- 链路追踪初始化
import (
"github.com/gogf/gf/v2/net/gotel"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/trace"
)
func initTracer() {
// 创建Jaeger导出器
exporter, err := jaeger.New(jaeger.WithCollectorEndpoint(
jaeger.WithEndpoint("http://localhost:14268/api/traces")
))
if err != nil {
g.Log().Fatal(ctx, "初始化追踪器失败", err)
}
// 创建追踪提供程序
tp := trace.NewTracerProvider(
trace.WithBatcher(exporter),
)
otel.SetTracerProvider(tp)
}
6.2.2 性能监控
- 函数性能追踪
func performanceTracing() {
// 使用内置性能追踪
defer gotel.Start().End()
// 需要监控的业务逻辑
time.Sleep(100 * time.Millisecond)
}
- 自定义追踪
func customTracing() {
// 创建追踪上下文
tracer := otel.Tracer("myapp")
// 开始一个新的追踪span
ctx, span := tracer.Start(ctx, "database-query")
defer span.End()
// 添加额外的追踪信息
span.SetAttributes(
attribute.String("db.system", "mysql"),
attribute.String("db.statement", "SELECT * FROM users"),
)
// 执行数据库查询
result := g.Model("users").Ctx(ctx).All()
}
6.2.3 异常捕获
- 全局异常处理
func globalExceptionHandler() {
// 设置全局错误处理
g.Log().SetConfigWithMap(g.Map{
"exception-handler": func(err error) {
// 记录详细错误信息
g.Log().Error(ctx, "未捕获的异常", err)
// 可选:发送告警通知
sendAlertNotification(err)
},
})
}
- 异常追踪
func exceptionTracing() {
defer func() {
if r := recover(); r != nil {
// 记录panic信息
err := fmt.Errorf("panic: %v", r)
g.Log().Error(ctx, "系统异常", err)
// 打印堆栈信息
debug.PrintStack()
}
}()
// 可能出现异常的代码
riskyOperation()
}
总结
本章详细介绍了GoFrame框架的日志与监控技术。通过学习,你将掌握:
- 日志系统配置与使用
- 日志级别与格式控制
- 链路追踪实现
- 性能监控技术
- 异常捕获与处理
这些技能将帮助你构建可观测、高可靠的应用系统。