[Golang (Go)] Use log package to output log

log

Package log implements a simple logging package. It defines a type, Logger, with methods for formatting output. It also has a predefined ‘standard’ Logger accessible through helper functions Print[f|ln], Fatal[f|ln], and Panic[f|ln], which are easier to use than creating a Logger manually. That logger writes to standard error and prints the date and time of each logged message. Every log message is output on a separate line: if the message being printed does not end in a newline, the logger will add one. The Fatal functions call os.Exit(1) after writing the log message. The Panic functions call panic after writing the log message.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// main.go

package main

import (
"fmt"
"log"
)

func main() {

// log.SetFlags(log.Lshortfile | log.Ldate | log.Lmicroseconds)
// log.SetPrefix("[Info] ")

log.Print("log.Print - Hello, CloudoLife!")
log.Printf("log.Printf - Hello,%s!", "CloudoLife")
log.Println("log.Println - Hello, CloudoLife!")

// log.Panic("log.Panic - Hello, CloudoLife!")
// log.Panicf("log.Panicf - Hello, %s!", "CloudoLife")
// log.Panicln("log.Panicln - Hello, CloudoLife!")

// log.Fatal("log.Fatal - Hello, CloudoLife!")
// log.Fatalf("log.Fatalf - Hello, %s!", "CloudoLife")
// log.Fatalln("log.Fatalln - Hello, CloudoLife!")

fmt.Print("fmt.Print - Hello, CloudoLife!\n")
fmt.Printf("fmt.Printf - Hello, %s!\n", "CloudoLife")
fmt.Println("fmt.Println - Hello, CloudoLife!")

fmt.Println("Finish!")
}

Run it.

1
2
3
4
5
6
7
8
$ go run main.go
2009/11/10 23:00:00 log.Print - Hello, CloudoLife!
2009/11/10 23:00:00 log.Printf - Hello,CloudoLife!
2009/11/10 23:00:00 log.Println - Hello, CloudoLife!
fmt.Print - Hello, CloudoLife!
fmt.Printf - Hello, CloudoLife!
fmt.Println - Hello, CloudoLife!
Finish!

Flags

These flags define which text to prefix to each log entry generated by the Logger. Bits are or’ed together to control what’s printed. With the exception of the Lmsgprefix flag, there is no control over the order they appear (the order listed here) or the format they present (as described in the comments). The prefix is followed by a colon only when Llongfile or Lshortfile is specified. For example, flags Ldate | Ltime (or LstdFlags) produce,

1
2009/01/23 01:23:23 message

while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,

1
2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message

Example

1
2
3
4
5
// main.go

log.SetFlags(log.Lshortfile | log.Ldate | log.Lmicroseconds)

log.Print("log.Print - Hello, CloudoLife!")

Run it.

1
2
$ go run main.go
2009/11/10 23:00:00.000000 prog.go:12: log.Print - Hello, CloudoLife!

See Flags const - https://golang.org/src/log/log.go?s=8098:8126#L233 to learn more.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// These flags define which text to prefix to each log entry generated by the Logger.
// Bits are or'ed together to control what's printed.
// With the exception of the Lmsgprefix flag, there is no
// control over the order they appear (the order listed here)
// or the format they present (as described in the comments).
// The prefix is followed by a colon only when Llongfile or Lshortfile
// is specified.
// For example, flags Ldate | Ltime (or LstdFlags) produce,
// 2009/01/23 01:23:23 message
// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
const (
Ldate = 1 << iota // the date in the local time zone: 2009/01/23
Ltime // the time in the local time zone: 01:23:23
Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
Llongfile // full file name and line number: /a/b/c/d.go:23
Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
Lmsgprefix // move the "prefix" from the beginning of the line to before the message
LstdFlags = Ldate | Ltime // initial values for the standard logger
)

Prefix

SetPrefix sets the output prefix for the logger.

Example

1
2
3
4
5
// main.go

log.SetPrefix("[Info] ")

log.Print("log.Print - Hello, CloudoLife!")

Run it.

1
2
$ go run main.go
[Info] 2009/11/10 23:00:00 log.Print - Hello, CloudoLife!

Custome Log

function New creates a new Logger. The out variable sets the destination to which log data will be written. The prefix appears at the beginning of each generated log line, or after the log header if the Lmsgprefix flag is provided. The flag argument defines the logging properties.

1
func New(out io.Writer, prefix string, flag int) *Logger

New Log

The follow code outputs the log to a bytes.Buffer

1
2
3
4
buf := &bytes.Buffer{}
logger := log.New(buf, "", log.Lshortfile|log.LstdFlags)

log.Print("log.Print - Hello, CloudoLife!")

Multi-destination Output

We can use io.MultiWriter to achieve multi-destination output. Below we will output the log to standard output, bytes.Buffer and file at the same time.

1
2
3
4
5
6
7
8
9
writer1 := &bytes.Buffer{}
writer2 := os.Stdout
writer3, err := os.OpenFile("example.log", os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
log.Fatalf("create file log.txt failed: %v", err)
}

logger := log.New(io.MultiWriter(writer1, writer2, writer3), "", log.Lshortfile|log.LstdFlags)
log.Print("log.Print - Hello, CloudoLife!")

References

[1] log - The Go Programming Language - https://golang.org/pkg/log/

[2] Let’s talk about logging – The acme of foolishness - https://dave.cheney.net/2015/11/05/lets-talk-about-logging

[3] [Go 每日一库之 log - 大俊的博客 - https://darjun.github.io/2020/02/07/godailylib/log/]