Show a Log Throbber in Terminal with Go
Show a Log Throbber in the Terminal with Go
A long-running program made to run in a terminal window should indicate what it is doing. Judicious logging is the first step.
While developing Printd for Toph, we needed a way to indicate the program status without outputting loglines repeatedly.
Printd, a print server daemon, waits for print requests from Toph and prints out the contents of the request to a connected printer. Until these requests arrive, Printd is mostly sitting idle.
Printd uses a throbbing indicator at the end of the log lines to indicate its status. For example, while waiting for new requests, it shows [~] Ready
with the ~
flashing slowly.
Printd uses github.com/FurqanSoftware/pog to implement multiple log throbbers in the terminal.
In this blog post, I only explain how Pog uses control escape sequences to implement these throbbers.
Control Escape Sequence

Terminals support control escape sequences that allow you to move the cursor back to the start of a line and clear out its contents.
^[[2K
: Clear entire line\r
: Move cursor to the beginning of the line
By combining these two, you can implement a throbber:
|
|
It will look something like this:
But this is being output to stdout
. To output this to stderr
, you need to use fmt.Fprint
with os.Stderr
instead:
|
|
However, this now poses a new issue. It is interfering with log lines output to stderr
. To fix that, you can set your logging library to clear the current line before writing the logline:
|
|
At this point, you will notice every time the program outputs a log line, the throbber may not appear for a fraction of a second. It is because the throbber is being output once every second.
We need to make the throbber output more frequent.
Complete Example

Below is a slightly more complete code example:
|
|
The result looks like this:
This post is 70th of my #100DaysToOffload challenge. Want to get involved? Find out more at 100daystooffload.com.
comments powered by Disqus