You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下logrus/lumberjack如何实现日志文件被删除后自动重建

问题原因

lumberjack 库默认仅在当前写入的日志文件大小达到你配置的 MaxSize 阈值时才会执行轮转逻辑、检查文件是否存在并重建。当你手动删除日志文件时,运行中的进程仍然持有已删除文件的文件描述符,后续日志会继续写入这个失效的文件描述符,不会自动触发重建逻辑。

解决方案

你可以通过主动触发 lumberjack 的轮转逻辑来实现文件删除后的自动重建,常见实现方式有两种:

方式1:监听系统信号手动触发(推荐)

给应用注册 SIGHUP 信号监听,当你手动删除日志文件后,给进程发送 SIGHUP 信号就会自动触发重建,不需要重启应用。
代码示例:

package main

import (
	"os"
	"os/signal"
	"path/filepath"
	"syscall"
	"github.com/natefinch/lumberjack"
	"github.com/sirupsen/logrus"
)

func main() {
	logFolder := "./logs"
	logger := &lumberjack.Logger{
		Filename:   filepath.Join(logFolder, "xxx.log"),
		MaxSize:    10,
		MaxBackups: 3,
		Compress:   false,
	}
	logrus.SetOutput(logger)

	// 注册信号监听
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGHUP)
	go func() {
		for range sigChan {
			// 调用 Rotate 方法会直接关闭当前文件,重建新的日志文件
			_ = logger.Rotate()
			logrus.Info("日志文件已重建")
		}
	}()

	// 后续你的应用逻辑
}

使用方式:手动删除日志文件后,执行 kill -HUP <你的应用进程ID> 即可触发重建。

方式2:自动检测文件存在性定时重建

如果不需要人工干预,希望程序自动检测,可以开一个后台 goroutine 定期检查日志文件是否存在,不存在就自动触发 Rotate:

import "time"

// 加入到你的初始化逻辑中
go func() {
	logPath := filepath.Join(logFolder, "xxx.log")
	// 每30秒检查一次,可自行调整间隔
	ticker := time.NewTicker(30 * time.Second)
	defer ticker.Stop()
	for range ticker.C {
		if _, err := os.Stat(logPath); os.IsNotExist(err) {
			_ = logger.Rotate()
			logrus.Info("检测到日志文件被删除,已自动重建")
		}
	}
}()

注意事项

  • 两种方式都依赖 lumberjack 暴露的 Rotate() 方法,该方法会安全关闭当前打开的日志文件,按照配置执行旧文件备份,再创建新的日志文件,不会丢失正在写入的日志。
  • 如果你使用的是封装后的 logrus 实例而不是全局 logrus,只需要对绑定的 lumberjack 实例调用 Rotate 方法即可,逻辑完全一致。

内容的提问来源于stack exchange,提问作者Jerry YY Rain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 10:54:03