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

时间:2015-03-25 19:03:55

标签: 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无法下载软件包等,那么有什么方法可以获得那些运行时日志? 当本地运行时,错误将打印到控制台上。有没有办法在服务器上运行时,我们可以将所有这些日志写入文本文件?

2 个答案:

答案 0 :(得分:2)

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

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

// 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)
   }
}

如果您没有统一使用日志库并且想要捕获所有输出(如恐慌),则接受的答案有效。但是,当您调用程序时,我更喜欢使用像logger这样的工具来简化代码的更简单的方法:

go run MainPackageFile.go 2>&1 | logger

这会将您的所有程序输出发送到syslog,而不必弄乱您的代码。 logger命令有许多选项可用于自定义日志记录行为,包括选择自己的日志文件的功能。有关详细信息,请阅读logger man page

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

答案 1 :(得分:1)

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

// 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)
    }
}

Original code from minux