Go 关闭具有延迟关闭的文件

Go 关闭具有延迟关闭的文件,go,Go,在我的主函数中,我打开一个日志文本文件,以便在应用程序退出后使用延迟关闭方法将其关闭。但是,在新的一天开始时,我希望开始写入第二天的日志文件,我不知道如何关闭前一天的文件并开始写入当前文件 在我的主要职能中: func main() { f, err := os.OpenFile("2019-07-24.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0644) if err != nil { log.Fatalf("Error

在我的主函数中,我打开一个日志文本文件,以便在应用程序退出后使用延迟关闭方法将其关闭。但是,在新的一天开始时,我希望开始写入第二天的日志文件,我不知道如何关闭前一天的文件并开始写入当前文件

在我的主要职能中:

func main() {

f, err := os.OpenFile("2019-07-24.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0644)
    if err != nil {
        log.Fatalf("Error opening log file: %v", err)
    }
    defer f.Close()

    log.SetOutput(f)

}
现在,当我在新的一天收到另一个包裹中的消息时:

func gateway() {

f, err := os.OpenFile("2019-07-25.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0644)
    if err != nil {
        log.Fatalf("Error opening log file: %v", err)
    }
    defer f.Close()

    log.SetOutput(f)

}

如何从另一个包中获取指向前一天日志文件的指针,然后将其关闭(除非应用程序完全关闭,否则不会调用延迟调用?

创建一个管理日志输出的包

package logoutput

package main

import (
    "io"
    "log"
    "sync"
)

var (
    mu            sync.Mutex
    curr io.WriteCloser
)

func Set(w io.WriteCloser) {
    mu.Lock()
    defer mu.Unlock()
    prev := curr
    curr = w
    log.SetOutput(curr)
    if prev != nil {
       prev.Close()
    }
}

func Close() {
    mu.Lock()
    defer mu.Unlock()
    log.SetOutput(os.Stderr) // revert to default
    if curr != nil {
       curr.Close()
    }
    curr = nil
}
从主程序包和网关程序包调用程序包

f, err := os.OpenFile("2019-07-24.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0644)
if err != nil {
    log.Fatalf("Error opening log file: %v", err)
}
logoutput.Set(f)
defer logoutput.Close() // call from main only

创建管理日志输出的包

package logoutput

package main

import (
    "io"
    "log"
    "sync"
)

var (
    mu            sync.Mutex
    curr io.WriteCloser
)

func Set(w io.WriteCloser) {
    mu.Lock()
    defer mu.Unlock()
    prev := curr
    curr = w
    log.SetOutput(curr)
    if prev != nil {
       prev.Close()
    }
}

func Close() {
    mu.Lock()
    defer mu.Unlock()
    log.SetOutput(os.Stderr) // revert to default
    if curr != nil {
       curr.Close()
    }
    curr = nil
}
从主程序包和网关程序包调用程序包

f, err := os.OpenFile("2019-07-24.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0644)
if err != nil {
    log.Fatalf("Error opening log file: %v", err)
}
logoutput.Set(f)
defer logoutput.Close() // call from main only

您可以通过通道来执行此操作。打开新文件时,返回一个通道。如果要打开另一个文件,则向该通道发送信号(然后关闭上一个文件)然后打开新的。这是一个很好的建议,谢谢。这个问题回答得很好,但提供了一个供考虑的替代方案-一般来说,应用程序不应该真正负责管理自己的日志文件;它应该只是盲目地写入标准输出。然后,操作员可以选择将其传输到一个文件,并使用像logrotate这样的专用工具,或者他们可以将其流式传输到集中式日志管理器,或者其他任何必要的工具。我不同意所有这些,但我绝对同意这一点。您可以通过通道进行操作。打开新文件时,返回一个通道。当您想要打开另一个文件时,请向通道发送信号(然后关闭上一个文件)然后打开新的。这是一个很好的建议,谢谢。这个问题回答得很好,但提供了一个供考虑的替代方案-一般来说,应用程序不应该真正负责管理自己的日志文件;它应该只是盲目地写入标准输出。然后,操作员可以选择将其传输到一个文件,并使用一个像logrotate这样的专用工具,或者他们可以将其流式传输到一个集中的日志管理器,或者其他任何必要的工具。我不完全同意这些,但我绝对同意这一点。