45

I know that we can print variable or error using log and fmt. for example if I want to print variable I can do this :

h := "world"
fmt.Printf("hello = %v\n", h)
log.Printf("halo = %v\n", h)

the output would be :

hello = world
2016/12/30 09:13:12 halo = world

and usually in the error handling I found log like this

if err != nil {
    log.Println("Error : something terrible happen -> ", err)
    return err
}

but from above case I could also use fmt to print the error like this

fmt.Printf("Error : something terrible happen -> %v\n",err.Error())

Is it a good practice to use fmt instead of log for printing the error? And then I always use fmt instead of log for printing the variable when debugging.

Gujarat Santana
  • 9,854
  • 17
  • 53
  • 75
  • 2
    Possible duplicate of [Why should I use log.Println instead of fmt.Println?](https://stackoverflow.com/questions/19646889/why-should-i-use-log-println-instead-of-fmt-println) – mayo Oct 09 '17 at 17:23

4 Answers4

58

Select between log and fmt using these facts:

The answer to the three sub questions are "it depends".

Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • Could show me an example about `The log functions can print timestamp, source code location and other info.` ? – BlackMamba Dec 30 '16 at 04:34
  • 1
    @BlackMamba It looks like this but is happens automatically when you use log: `Dec 16 16:13:20 My-MacBook someDescription[80590]: 2019/12/16 16:13:20 Error 1054: Unknown column 'xxx' in 'field list'` – Serkan Sipahi Dec 17 '19 at 07:52
13

I would like to add one more point:

  • Log is thread safe where as fmt is not.

    A Logger can be used simultaneously from multiple goroutines; it guarantees to serialize access to the Writer.

Link

James Sapam
  • 16,036
  • 12
  • 50
  • 73
  • how do you know if `log` is thread safe? any reference for this ? thanks – Gujarat Santana Dec 30 '16 at 11:18
  • 4
    @GujaratSantana The [logger documentation](https://godoc.org/log#Logger) states that a logger can be used simultaneously from multiple goroutines. There is no documentation on the thread safety of `fmt.Printf`. The `fmt.Printf` implementation is thread safe it is very unlikely that it will be changed to not be thread safe. – Charlie Tumahai Dec 30 '16 at 12:56
  • 4
    Actually, though `fmt.Printf` is thread safe in the sense that it doesn't have any data races, a `Logger` uses a mutex to serialize the output, while fmt writes it out directly. With enough concurrency you can get interleaved writes to stdout. – JimB Dec 30 '16 at 14:14
7

You generally don't get into trouble if you stick to use fmt.Print* for program output and log.* for program logging.

Of course if your program doesn't have "local" output (as most network server programs) you could use both for logging, but for logging log.* is more flexible and apt.

Pablo Lalloni
  • 2,615
  • 19
  • 20
4

From "Essential Go" book

Standard package log offers more functionality:

log.Printf("Logging")
log.Printf("Second line\n")

2019/03/26 10:07:11 Logging
2019/03/26 10:07:11 Second line

Compared to fmt.Printf, log.Printf:

  • By default logs to stderr (os.Stderr)
  • Adds current time to each log line
  • Ensures that echo log is on it’s own line by adding \n if not explicitly provided

To log fatal issues:

f, err := os.Open("file.txt")
if err != nil {
    log.Fatalf("os.Open('file.txt') failed with '%s'\n", err)
}

log.Fatalf logs the message and calls os.Exit(1) to end the process.

Vlad Bezden
  • 83,883
  • 25
  • 248
  • 179