log writes timestamped lines to standard error and, through Fatal and Panic, ends the program on the way out. For structured key-value output, reach for log/slog instead.
Examples
Print writes one event to standard error and returns. Fatal writes the same way, then exits with status 1, so nothing after it runs.
func main() {
log.Print("starting up")
log.Printf("listening on port %d", 8080)
_, err := os.Open("config.yaml")
if err != nil {
log.Fatal(err)
}
log.Print("never reached")
}Output
2009/11/10 23:00:00 starting up
2009/11/10 23:00:00 listening on port 8080
2009/11/10 23:00:00 open config.yaml: no such file or directory
exit status 1Flags pick which fields precede the message. Lshortfile adds the file and line of the call site, which is what makes a log line traceable back to code.
func main() {
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetPrefix("api: ")
log.Print("request handled")
// Lmsgprefix moves the prefix past the date and file fields.
log.SetFlags(log.Ltime | log.Lshortfile | log.Lmsgprefix)
log.Print("request handled")
}Output
api: 2009/11/10 23:00:00 main.go:8: request handled
23:00:00 main.go:12: api: request handledNew builds a Logger with its own destination, prefix, and flags. Passing one around keeps each component's output labelled without a global setting.
func main() {
db := log.New(os.Stdout, "db: ", log.Ltime)
http := log.New(os.Stdout, "http: ", log.Ltime)
db.Print("connected to postgres")
http.Printf("GET /health -> %d", 200)
db.Print("closing pool")
}Output
db: 23:00:00 connected to postgres
http: 23:00:00 GET /health -> 200
db: 23:00:00 closing poolA Logger takes any io.Writer. An os.File sends the log to disk, and an io.MultiWriter sends every line to two places at once.
func main() {
f, err := os.OpenFile("app.log",
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Every line goes to the terminal and to app.log.
log.SetOutput(io.MultiWriter(os.Stdout, f))
log.Print("job finished")
}Output
2009/11/10 23:00:00 job finished
$ cat app.log
2009/11/10 23:00:00 job finished| Function | Description |
|---|---|
Print(v ...any) log.Print("starting") | Writes v to the standard logger, formatting like fmt.Print. |
Printf(format string, v ...any) log.Printf("port %d", 8080) | Writes to the standard logger, formatting like fmt.Printf. |
Println(v ...any) | Writes to the standard logger, formatting like fmt.Println. |
Fatal(v ...any) log.Fatal(err) | Writes to the standard logger, then calls os.Exit(1). Deferred functions do not run. |
Fatalf(format string, v ...any) | Printf, then os.Exit(1). |
Fatalln(v ...any) | Println, then os.Exit(1). |
Panic(v ...any) log.Panic("unreachable") | Writes to the standard logger, then panics with the same message. |
Panicf(format string, v ...any) | Printf, then panics with the formatted message. |
Panicln(v ...any) | Println, then panics with the message. |
Output(calldepth int, s string) error | Writes the string s as one log event, with calldepth controlling which caller the file:line prefix reports. |
SetOutput(w io.Writer) log.SetOutput(os.Stdout) | Redirects the standard logger to w. Default is os.Stderr. |
Writer() io.Writer | Returns the standard logger's current output destination. |
SetPrefix(prefix string) log.SetPrefix("api: ") | Sets the string written at the start of every line from the standard logger. |
Prefix() string | Returns the standard logger's current prefix. |
SetFlags(flag int) log.SetFlags(log.LstdFlags | log.Lshortfile) | Sets which fields the standard logger writes before the message. |
Flags() int | Returns the standard logger's current flag set. |
Default() *Logger | Returns the standard logger itself, for passing to code that takes a *Logger. |
New(out io.Writer, prefix string, flag int) *Logger log.New(os.Stdout, "db: ", log.LstdFlags) | Creates a Logger writing to out, with the given prefix and flags. |
type Logger struct | A logger writing to an io.Writer. Safe for concurrent use from multiple goroutines. |
(*Logger) Print(v ...any) | Writes v to this logger, formatting like fmt.Print. |
(*Logger) Printf(format string, v ...any) | Writes to this logger, formatting like fmt.Printf. |
(*Logger) Println(v ...any) | Writes to this logger, formatting like fmt.Println. |
(*Logger) Fatal(v ...any) | Writes to this logger, then calls os.Exit(1). |
(*Logger) Fatalf(format string, v ...any) | Printf on this logger, then os.Exit(1). |
(*Logger) Fatalln(v ...any) | Println on this logger, then os.Exit(1). |
(*Logger) Panic(v ...any) | Writes to this logger, then panics with the same message. |
(*Logger) Panicf(format string, v ...any) | Printf on this logger, then panics with the formatted message. |
(*Logger) Panicln(v ...any) | Println on this logger, then panics with the message. |
(*Logger) Output(calldepth int, s string) error | Writes s as one log event on this logger. |
(*Logger) SetOutput(w io.Writer) | Redirects this logger to w. |
(*Logger) Writer() io.Writer | Returns this logger's output destination. |
(*Logger) SetPrefix(prefix string) | Sets this logger's line prefix. |
(*Logger) Prefix() string | Returns this logger's prefix. |
(*Logger) SetFlags(flag int) | Sets this logger's flags. |
(*Logger) Flags() int | Returns this logger's flags. |
Ldate log.SetFlags(log.Ldate) | Flag: the date in the local time zone, 2009/01/23. |
Ltime | Flag: the time in the local time zone, 01:23:23. |
Lmicroseconds | Flag: microsecond resolution on the time, 01:23:23.123123. Implies Ltime. |
Llongfile | Flag: full file path and line number, /a/b/c/d.go:23. |
Lshortfile | Flag: final file name element and line number, d.go:23. Overrides Llongfile. |
LUTC | Flag: report the date and time in UTC rather than local time. |
Lmsgprefix | Flag: move the prefix from the start of the line to just before the message. |
LstdFlags log.New(w, "", log.LstdFlags) | Flag: Ldate | Ltime, the standard logger's default. |
Related: os errors io