Go/Golang write log to file

匿名 (未验证) 提交于 2019-12-03 02:44:02

问题:

I'm trying to write to a log file with Golang.

I have tried several approaches, all of which have failed. This is what I have tried:

func TestLogging(t *testing.T) {     if !FileExists("logfile") {         CreateFile("logfile")     }     f, err := os.Open("logfile")     if err != nil {         t.Fatalf("error: %v", err)     }      // attempt #1     log.SetOutput(io.MultiWriter(os.Stderr, f))     log.Println("hello, logfile")      // attempt #2     log.SetOutput(io.Writer(f))     log.Println("hello, logfile")      // attempt #3     log.SetOutput(f)     log.Println("hello, logfile") }  func FileExists(name string) bool {     if _, err := os.Stat(name); err != nil {        if os.IsNotExist(err) {             return false         }     }     return true }  func CreateFile(name string) error {     fo, err := os.Create(name)     if err != nil {         return err     }     defer func() {         fo.Close()     }()     return nil } 

The log file gets created, but nothing ever gets printed or appended to it. Why?

回答1:

os.Open() must have worked differently in the past, but this works for me:

f, err := os.OpenFile("testlogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) if err != nil {     log.Fatalf("error opening file: %v", err) } defer f.Close()  log.SetOutput(f) log.Println("This is a test log entry") 

Based on the Go docs, os.Open() can't work for log.SetOutput, because it opens the file "for reading:"

func Open

func Open(name string) (file *File, err error) Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY. If there is an error, it will be of type *PathError.

EDIT

Moved defer f.Close() to after if err != nil check



回答2:

I prefer the simplicity and flexibility of the 12 factor app recommendation for logging. To append to a log file you can use shell redirection. The default logger in Go writes to stderr (2).

./app 2>> logfile 

See also: http://12factor.net/logs



回答3:

The default logger in Go writes to stderr (2). redirect to file

import (      "syscall"     "os"   ) func main(){   fErr, err = os.OpenFile("Errfile", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)   syscall.Dup2(int(fErr.Fd()), 1) /* -- stdout */   syscall.Dup2(int(fErr.Fd()), 2) /* -- stderr */  } 


回答4:

This works for me

  1. created a package called logger.go

    package logger  import (   "flag"   "os"   "log"   "go/build" )  var (   Log      *log.Logger )   func init() {     // set location of log file     var logpath = build.Default.GOPATH + "/src/chat/logger/info.log"     flag.Parse()    var file, err1 = os.Create(logpath)     if err1 != nil {       panic(err1)    }       Log = log.New(file, "", log.LstdFlags|log.Lshortfile)       Log.Println("LogFile : " + logpath) } 
    1. import the package wherever you want to log e.g main.go

      package main  import (    "logger" )  const (    VERSION = "0.13"  )  func main() {      // time to use our logger, print version, processID and number of running process     logger.Log.Printf("Server v%s pid=%d started with processes: %d", VERSION, os.Getpid(),runtime.GOMAXPROCS(runtime.NumCPU()))  } 


回答5:

Declare up top in your global var so all your processes can access if needed.

package main  import (     "log"     "os" ) var (     outfile, _ = os.Create("./logs/my.log")     l      = log.New(outfile, "", 0) )  func main() {     l.Println("hello, log!!!") } 


回答6:

import (     "os/exec" )  func main() {     // check error here...     exec.Command("/bin/sh", "-c", "echo "+err.Error()+" >> log.log").Run() } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!