Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

display only one logging line, removing the previous ones

I have a program using the logging module and the print statement. The logging is to inform the user what the program is doing, for example

logging.info("downloading HTML")
time.sleep(1)
logging.info("parsing HTML")
time.sleep(1)
print "the result"

at the end the output on the screen (mixing stdout and stderr) will be:

INFO:downloading HTML
INFO:parsing HTML
the result

I want to hide the last logging output when the next logging output is displayed or when the print is called. For example, start the program, you will see:

INFO:download HTML

wait one seconds, the next info "parsing HTML" will replace the previous "downloading HTML", so on the screen you will see only:

INFO:parsing HTML

and nothing else before, then wait one second, I want to see on the screen only:

"the result"

I want this feauture only when logging on the stderr, and not when logging to a file for example, there I want to see all the logging outputs.

Is it possible?

like image 954
Ruggero Turra Avatar asked Aug 16 '12 09:08

Ruggero Turra


1 Answers

On unix-like terminals, you can try prepending ANSI escape sequences to the text;

import time
import sys

print 'this is a text',
sys.stdout.flush()

time.sleep(1)
print '\x1b[80D'+'\x1b[K'+'Second text',
sys.stdout.flush()

The character '\x1b' is the escape character. The first sequence moves the cursor up to 80 positions to the left. The second clears the line.

You need the comma at the end of the print statement to prevent it from going to the second line. Then you need to flush the stdout stream otherwise the text won't appear.

Edit: For combinging this with logging, wrap it in a simple function:

def mylog(text):
    logging.info(text)
    print '\x1b[80D' + '\x1b[K'+ text,
    sys.stdout.flush()

EDIT 2: Integrating this into the standard logging;

import logging
# create console handler
ch = logging.StreamHandler()
# create formatter
formatter = logging.Formatter('\x1b[80D\x1b[1A\x1b[K%(message)s')
# add formatter to console handler
ch.setFormatter(formatter)
# add console handler to logger
logger.addHandler(ch)

Since the logging module seems to add newlines by itself, I've added an ANSI sequense (\x1b[1A) to go up one line.

Also see the logging howto for more information.

like image 162
Roland Smith Avatar answered Sep 22 '22 01:09

Roland Smith