为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 macOS 上的 logrus/lumberjack 中自动重新创建日志文件

如何在 macOS 上的 logrus/lumberjack 中自动重新创建日志文件

Go
紫衣仙女 2022-10-10 18:05:00
我在 macOS 上使用logrus和lumberjack作为日志文件。logger := &lumberjack.Logger{    // Log path    Filename: filepath.Join(logFolder, "xxx.log"),    // Log size MB    MaxSize: 10,    // Backup count    MaxBackups: 3,    // expire days    // MaxAge: 28,    // gzip compress    Compress: false,}logrus.SetOutput(logger)当我启动我的应用程序时,它将按预期创建日志文件。但是,当我的应用程序运行时,我手动删除了日志文件,因为我的应用程序继续运行,我希望它会重新创建日志文件,但是,日志文件没有创建。但是如果我重新启动我的应用程序,将再次创建日志文件。那么我应该怎么做才能让我的应用程序(继续运行)在删除日志文件时重新创建和写入日志文件。提前致谢。
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

这是使用fsnotifylib 监视日志文件的另一种方法。fsnotify监控xxx.log所在的目录,告诉lumberjackRotate()什么时候删除xxx.log。


import (

    "fmt"

    "log"

    "path/filepath"

    "time"


    "github.com/fsnotify/fsnotify"

    "gopkg.in/natefinch/lumberjack.v2"

)


func main() {

    logPath := "./xxx.log"

    logName := filepath.Base(logPath)


    logger := &lumberjack.Logger{

        // Log path

        Filename: logPath,

        // Log size MB

        MaxSize: 10,

        // Backup count

        MaxBackups: 3,

        // expire days

        // MaxAge: 28,

        // gzip compress

        Compress: false,

    }


    watcher, err := fsnotify.NewWatcher()

    if err != nil {

        log.Fatal(err)

    }

    defer watcher.Close()


    go func() {

        for event := range watcher.Events {

            if event.Op&fsnotify.Remove == fsnotify.Remove &&

                event.Name == logName {

                log.Println("rotate log", event.Name)

                logger.Rotate()

            }

        }

    }()


    err = watcher.Add(filepath.Dir(logPath))

    if err != nil {

        log.Fatal(err)

    }


    for {

        logger.Write([]byte(fmt.Sprintf("current time:%v\n", time.Now())))

        time.Sleep(3 * time.Second)

    }

}


查看完整回答
反对 回复 2022-10-10
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

问题”

基于所述行为,我假设这发生在为文件实现 POSIX 兼容行为的操作系统上(因此它运行在具有 Unix 遗产的某些内核上 - 例如 *BSD 或 Linux,或者它是 Mac OS 系统)。在这些系统上,从文件系统中删除文件对该文件系统上的文件存储没有任何影响——只要它至少在一个正在运行的进程中打开。
具体来说,要引用POSIX 文档open(2)

如果文件的链接计数为0,则当与该文件关联的所有文件描述符都关闭时,该文件占用的空间将被释放,该文件将不再可访问。

打开文件被认为将其链接计数增加 1,从其文件系统中删除文件与将链接计数减 1 相同。您可以在此处
阅读有关链接计数的更多信息。

假设您正在使用的日志记录包保持日志文件处于打开状态,因此您只需从文件系统的目录中删除文件名,但这绝不会影响日志记录过程。
此外,当任何文件名消失时,不会通知打开文件的进程(在类 Unix 系统上,一个文件可能同时有多个名称——请阅读硬链接)。

解决方案

通常,对于类 Unix 操作系统,有一种方法可以明确要求进程重新打开其日志文件。
偶然地,SIGUSR1为此使用了一个信号,因此您可以设置一个处理程序(通过signal.Notify)为此类信号设置一个处理程序,然后将您的日志轮换代码设置kill -USR1为正在运行的进程,以告诉它重新打开日志文件,这将是重新创建。

当然,可以实施更多涉及的方案,因为您可以使用任何形式的IPC将该命令传达给正在运行的进程。


查看完整回答
反对 回复 2022-10-10
?
MMTTMM

TA贡献1869条经验 获得超4个赞

删除 xxx.log 后,您可以向正在运行的进程发送一个信号,然后下面的代码将处理该信号并告诉伐木工人创建新的日志文件。


sigs := make(chan os.Signal, 1)

signal.Notify(sigs, syscall.SIGUSR1)


go func() {

    for _ = range sigs {

        // call Rotate() method of lumberjack to create new log file

        logger.Rotate()

    }

}()

用于删除和轮换日志的命令


# delete log file

rm path/to/xxx.log

# this command would not kill your process, just send a signal to it.

kill -USR1 <your process id>


查看完整回答
反对 回复 2022-10-10
  • 3 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信