chore(logging): 更新日志重定向与捕获功能
- 在 .gitignore 中添加调试日志文件的忽略规则,避免不必要的调试信息被提交 - 修改 application.go 中的 stdout 重定向逻辑,使用 log.CaptureStream 以支持更灵活的日志捕获 - 更新 README 文档,增加对日志重定向功能的说明
This commit is contained in:
+20
-35
@@ -1,7 +1,6 @@
|
||||
package hotime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
@@ -26,6 +25,8 @@ import (
|
||||
. "code.hoteas.com/golang/hotime/db"
|
||||
"code.hoteas.com/golang/hotime/log"
|
||||
mysql "github.com/go-sql-driver/mysql"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Application struct {
|
||||
@@ -189,7 +190,7 @@ func (that *Application) Run(router Router) {
|
||||
return // 停机过程中的 panic 不触发重启
|
||||
}
|
||||
//that.SetError(errors.New(fmt.Sprint(err)), LOG_FMT)
|
||||
that.Log.Warnf("%v", err)
|
||||
that.Log.EmitRecoveredPanic(err)
|
||||
|
||||
that.Run(router)
|
||||
}
|
||||
@@ -346,7 +347,8 @@ func (that *Application) SetConfig(configPath ...string) {
|
||||
}
|
||||
|
||||
// 重定向 os.Stdout 和标准 log 包,捕获 fmt.Println 等绕过 HoTime Logger 的输出
|
||||
redirectStdout(that.Log)
|
||||
stdoutW := redirectStdout(that.Log)
|
||||
bridgeThirdPartyStdout(stdoutW)
|
||||
// 重定向 os.Stderr,捕获 panic 栈、MySQL driver errLog 等写 stderr 的输出
|
||||
// 注意:Logger 在此之前已创建,ConsoleWriter.Out 已绑定到原始 os.Stderr,无循环风险
|
||||
redirectStderr(that.Log)
|
||||
@@ -660,52 +662,35 @@ func getLocalIP() string {
|
||||
}
|
||||
|
||||
// redirectStdout 重定向 os.Stdout 和标准 log 包到 HoTime Logger。
|
||||
// 捕获 fmt.Println/fmt.Printf 等绕过 HoTime 日志系统的输出,
|
||||
// 以 INFO 级别 + source="stdout" 字段写入,后续经 SeqWriter 推送到 Seq。
|
||||
func redirectStdout(l *log.Logger) {
|
||||
// 返回管道写端,供 logrus 等第三方库桥接。
|
||||
func redirectStdout(l *log.Logger) *os.File {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
os.Stdout = w
|
||||
stdlog.SetOutput(w)
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if line != "" {
|
||||
l.Info().Str("source", "stdout").Msg(line)
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
l.Errorf("[stdout redirect] scanner error: %v", err)
|
||||
}
|
||||
}()
|
||||
go log.CaptureStream(l, zerolog.InfoLevel, "stdout", r)
|
||||
return w
|
||||
}
|
||||
|
||||
// bridgeThirdPartyStdout 将 import 时钉死原始 stdout 的第三方日志指到捕获管道。
|
||||
func bridgeThirdPartyStdout(w *os.File) {
|
||||
if w == nil {
|
||||
return
|
||||
}
|
||||
logrus.SetOutput(w)
|
||||
}
|
||||
|
||||
// redirectStderr 重定向 os.Stderr 到 HoTime Logger(level=error, source=stderr)。
|
||||
// 捕获 Go runtime panic 栈、MySQL driver errLog 等直写 stderr 的输出。
|
||||
// 必须在 Logger 创建之后调用:ConsoleWriter.Out 已绑定原始 os.Stderr 文件指针,
|
||||
// 重定向后 ConsoleWriter 仍写真实终端,不会形成循环。
|
||||
func redirectStderr(l *log.Logger) {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
l.Warnf("[redirectStderr] create pipe failed: %v", err)
|
||||
l.EmitCaptured(zerolog.WarnLevel, "stderr-capture", fmt.Sprintf("create pipe failed: %v", err))
|
||||
return
|
||||
}
|
||||
os.Stderr = w
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if line != "" {
|
||||
l.Error().Str("source", "stderr").Msg(line)
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
l.Warnf("[redirectStderr] scanner error: %v", err)
|
||||
}
|
||||
}()
|
||||
go log.CaptureStream(l, zerolog.ErrorLevel, "stderr", r)
|
||||
}
|
||||
|
||||
// Init 初始化application
|
||||
|
||||
Reference in New Issue
Block a user