Logging in Golang
Logging is very important. Every production web application uses logs to assist developers and operations. The type of application you're building will determine the data you actually log.
Why do we need logging in Go language?
The most common reasons to use logging in your programs are:
-
Find programming errors in the application.
-
Analyze the causes of failures and security problems.
-
The timestamp for an event or the creation of a log.
-
Layers of logging like debug, error, or info.
-
Identify performance issues.
-
Contextual information to make it easier to understand what happened and to duplicate the circumstance.
-
Environment variables and information.
You should never log sensitive information, which may contain users data, such as Name, API keys, etc.
Package log
Go language has built-in package to make programmers life easy but we can always use or create third party packages for better results. Instead of the standard error (stderr) output stream, which is where it prints by default.You can force the log package to write to local files or any location that accepts the io.Writer interface and append a timestamps to the log message.
Write logs in a file - Go language
1st method
Based on the Go docs, os.Open()
can't work for log.SetOutput
, because it opens the file "for reading:"
# open file in read/write mode
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 log entry")
2nd method
To append to a log file you can use shell redirection. The default logger in Go writes to stderr (2).
./app 2>> logfile
3rd method
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()))
}
What is the difference between log.Println and fmt.Println?
There are two differences:
-
While plain fmt
is not safe from concurrent goroutines, printing via package log is.
-
Log can automatically add time data
So these are two completely different things. log is for logging and fmt
for formatting. (Okay, log uses the same verbs and flags, but that is just convenient).