Logging 我们可以将所有控制台日志定向到文件吗?

Logging 我们可以将所有控制台日志定向到文件吗?,logging,web-applications,go,Logging,Web Applications,Go,使用命令在本地运行web应用程序时 go run MainPackageFile.go 我们还可以用马提尼酒 m := martini.Classic() m.Get("/m", func() string { return "Hello world!" }) m.Map(log.New(f, "[martini]", log.LstdFlags)) 但是,如果代码之外有错误,例如Go无法下载软件包等,该怎么办。。。有没有办法让这些运行日志? 在本地运行时,错误将打印到控制台上。在服务器

使用命令在本地运行web应用程序时

go run MainPackageFile.go
我们还可以用马提尼酒

m := martini.Classic()
m.Get("/m", func() string {
  return "Hello world!"
})
m.Map(log.New(f, "[martini]", log.LstdFlags))
但是,如果代码之外有错误,例如Go无法下载软件包等,该怎么办。。。有没有办法让这些运行日志?
在本地运行时,错误将打印到控制台上。在服务器中运行时,是否有办法将所有日志写入文本文件?

您可以使用此功能将标准错误重定向到文件。这将接收回溯

// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
    if err != nil {
        log.Fatalf("Failed to redirect stderr to file: %v", err)
    }
}
它只在linux/mac/unix上工作

下面是如何对windows执行同样的操作

var (
    kernel32 = syscall.MustLoadDLL("kernel32.dll")
    procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
)

func setStdHandle(stdhandle int32, handle syscall.Handle) error {
    r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
    if r0 == 0 {
        if e1 != 0 {
            return error(e1)
        }
        return syscall.EINVAL
    }
    return nil
}

// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
    err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
    if err != nil {
        log.Fatalf("Failed to redirect stderr to file: %v", err)
    }
}

假设您的代码使用日志库到处报告错误,您可以更改默认记录器写入的文件,而不是定义自己的日志对象并传递它。这是通过日志库的函数完成的

这样,以下代码将只写入日志文件,而不是标准错误:

// Call this when your program starts and pass it the file handle for your
// log file.
func SetupErrorLog(logFile io.Writer) {
    log.SetOutput(logFile)
}

...

func DoSomething() {
    ...
    if err != nil {
       // prints to your log file and exits
       log.Fatalln("A fatal error has occurred:", err)
   }
}
如果您没有统一使用日志库,并且希望捕获所有输出(比如恐慌),那么接受的答案是有效的。但是,我更喜欢一种更简单的方法,在调用程序时使用类似于记录器的工具,而不会使代码复杂化:

go run MainPackageFile.go 2>&1 | logger
这将把程序的所有输出发送到syslog,而不必弄乱代码。logger命令有许多选项可用于自定义日志记录行为,包括选择自己的日志文件的功能。有关更多信息,请阅读

logger命令在Unix系统(包括Mac)上可用。Windows解决方案可能有点不同