I\'m trying to write to a log file with Go.
I have tried several approaches, all of which have failed. This is what I have tried:
func TestLogging(t
This works for me
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)
}
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()))
}
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 */
}
I usually print the logs on screen and write into a file as well. Hope this helps someone.
f, err := os.OpenFile("/tmp/orders.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
defer f.Close()
wrt := io.MultiWriter(os.Stdout, f)
log.SetOutput(wrt)
log.Println(" Orders API Called")
To help others, I create a basic log function to handle the logging in both cases, if you want the output to stdout, then turn debug on, its straight forward to do a switch flag so you can choose your output.
func myLog(msg ...interface{}) {
defer func() { r := recover(); if r != nil { fmt.Print("Error detected logging:", r) } }()
if conf.DEBUG {
fmt.Println(msg)
} else {
logfile, err := os.OpenFile(conf.LOGDIR+"/"+conf.AppName+".log", os.O_RDWR | os.O_CREATE | os.O_APPEND,0666)
if !checkErr(err) {
log.SetOutput(logfile)
log.Println(msg)
}
defer logfile.Close()
}
}
maybe this will help you (if the log file exists use it, if it does not exist create it):
package main
import (
"flag"
"log"
"os"
)
//Se declara la variable Log. Esta será usada para registrar los eventos.
var (
Log *log.Logger = Loggerx()
)
func Loggerx() *log.Logger {
LOG_FILE_LOCATION := os.Getenv("LOG_FILE_LOCATION")
//En el caso que la variable de entorno exista, el sistema usa la configuración del docker.
if LOG_FILE_LOCATION == "" {
LOG_FILE_LOCATION = "../logs/" + APP_NAME + ".log"
} else {
LOG_FILE_LOCATION = LOG_FILE_LOCATION + APP_NAME + ".log"
}
flag.Parse()
//Si el archivo existe se rehusa, es decir, no elimina el archivo log y crea uno nuevo.
if _, err := os.Stat(LOG_FILE_LOCATION); os.IsNotExist(err) {
file, err1 := os.Create(LOG_FILE_LOCATION)
if err1 != nil {
panic(err1)
}
//si no existe,se crea uno nuevo.
return log.New(file, "", log.Ldate|log.Ltime|log.Lshortfile)
} else {
//si existe se rehusa.
file, err := os.OpenFile(LOG_FILE_LOCATION, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
panic(err)
}
return log.New(file, "", log.Ldate|log.Ltime|log.Lshortfile)
}
}
For more detail: https://su9.co/9BAE74B
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