How can I print to Stderr in Go without using log
Solution 1
The Go builtin functions print
and println
print to stderr. So if you simply want to output some text to stderr you can do
package main
func main() {
println("Hello stderr!")
}
Documentation: https://golang.org/pkg/builtin/#print
Solution 2
If you don't want timestamps, just create a new log.Logger
with flag
set to 0
:
l := log.New(os.Stderr, "", 0)
l.Println("log msg")
EDIT:
Is the following good Go?
os.Stderr.WriteString("Message")
This is acceptable, and you can also use fmt.Fprintf
and friends to get formatted output:
fmt.Fprintf(os.Stderr, "number of foo: %d", nFoo)
Solution 3
Using the fmt
package, you can choose to write to stderr
this way:
import "fmt"
import "os"
func main() {
fmt.Fprintln(os.Stderr, "hello world")
}
Solution 4
os.Stderr
is an io.Writer
, so you can use it in any function which accepts an io.Writer
. Here are a few examples:
str := "Message"
fmt.Fprintln(os.Stderr, str)
io.WriteString(os.Stderr, str)
io.Copy(os.Stderr, bytes.NewBufferString(str))
os.Stderr.Write([]byte(str))
It all depends on how exactly you have the string you want to print (i.e. if you want to format it first, if you have it as an io.Reader
, if you have it as a byte slice...). And there can be a lot more ways.
Solution 5
By default the logger flags are set to Ldate | Ltime
. You can change the logger format to any of the following (from the golang log documentation):
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
LstdFlags = Ldate | Ltime // initial values for the standard logger
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
You can also set the default logger to not print anything by setting the flag to 0:
log.SetFlags(0)
Max Heiber
Updated on August 18, 2020Comments
-
Max Heiber over 3 years
How can I write a message to Stderr without using
log
?A comment in this SO post shows how to do it with
log
:log.Println("Message")
, but what if I don't want a timestamp?Is the following good Go?
os.Stderr.WriteString("Message")
-
Ainar-G about 9 yearsIf you're going to use stderr to actually log things, use a logger. Otherwise, a simple
os.Stderr.WriteString
will suffice, IMO. -
Andrioid over 5 yearsBest answer. Although, my personal preference is using fmt.Fprintf or fmt.Fprintln. If you're doing this many places in your program, maybe wrap it in a function then you can easily change stderr to stdout or whatever writer you want.
-
Daniel Gray over 3 yearsGood tip! However, it says: "Print is useful for bootstrapping and debugging; it is not guaranteed to stay in the language." so maybe not for long-term projects?
-
weakish over 3 yearsIMO,
print
andprintln
are used for debugging. -
KEINOS almost 3 yearsIndeed the documents say that
println
prints to STDERR. Though, it seems not printing to STDERR by default. Throwing away the STDERR bygo run ./main.go 2>/dev/null 3>/dev/null
, I'm still getting a "Hello stderr!" message. Which means that it's printing to STDOUT. I think @julienc answerfmt.Fprintln(os.Stderr, "Hello stderr!")
should be the accepted answer too. -
Sridhar Sarnobat almost 3 yearsNote to self: be careful about using
| grep 'DEBUG'
in combination with2>
. Somehow I still get the stderr output on my terminal while using2>
. -
Speeddymon almost 3 years@SridharSarnobat each command in a group of piped command can independently output to
stderr
. Consider this instead:somecommand 2>/dev/null |grep 'DEBUG' 2>/dev/null
in order to sendgrep
errors to/dev/null
in addition tosomecommand
errors -
taras over 2 years@KEINOS what OS do you use to get println in stdout? I am trying to reproduce to understand it better, however it still prints into stderr
-
KEINOS over 2 years@TarasMatsyk My bad! I DO GET the STDERR with
println
. I think I was confused. The reason was that I ran the code on the Docker container.docker run --rm -it -v "$(pwd)":/root/src golang:alpine go run /root/src/main.go 2>/dev/null
. This will print the error message since the container prints to STDOUT the "outputs inside the container". -
user5359531 almost 2 yearshow are you supposed to use these flags?