2

In my python script, I am using the logging module with INFO going to a file and the screen:

fh_info = logging.FileHandler(info)
fh_info.setLevel(logging.INFO)
fh_info.setFormatter(formatter)

std_out_info = logging.StreamHandler()
std_out_info.setLevel(logging.INFO)

logger.addHandler(fh_info)
logger.addHandler(std_out_info)

But the issue I am having is that the messages got to the screen after the function is completed. For instance, in:

def getToken(self):
    msg = ("Initializing token....")
    logger.info(msg)
    sys.stdout.flush()
    try:
        jsonreq = ( {"auth": {"KEY:apiKeyCredentials": {
            "username": self.username,
            "apiKey": self.apikey}}})
        auth_headers = {'content-type': 'application/json'}
        r = requests.post(self.url, data=json.dumps(jsonreq), headers=auth_headers)
        self.jsonresp = json.loads(r.text)
        self.token = str(self.jsonresp['access']['token']['id'])
        msg = ("done!")
        logger.info(msg)
    except:
        msg = ("Bad name or apikey!")
        logger.error(msg)
        sys.exit()

The message "Initializing token...." will go to the screen after the operations in the function are completed. The makes for a long pause while authentication is going on with no output...then after authentication completes I see "Initializing token....done".

How can I make the logger.info(msg) stay in sync with the flow of the script and output to the screen in it's timely manner?

dman
  • 10,406
  • 18
  • 102
  • 201
  • Most likely your output on STDOUT gets line buffered (which usually is a good thing). Try 1) Doing an explicit `sys.stdout.flush()` whenever you want to flush STDOUT and 2) running python in unbuffered mode using `python -u yourscript.py` – Lukas Graf Nov 25 '13 at 18:06
  • 2
    Just noticed you're already doing `sys.stdout.flush()` - so disregard that please, and try unbuffered mode (`-u`). – Lukas Graf Nov 25 '13 at 18:07
  • Try to use sleep to see any different: logger.info('start ...'); time.sleep(2); logger.info('done'); if it still not sync, then I guess the problem is from other part. Because I tried you init logger code with sleep part, it works in sync way. BTW, logging go to sys.stderr in linux. – PasteBT Nov 25 '13 at 18:45
  • @PasteBT brought up a good point: If you register your own [`StreamHandler`](http://docs.python.org/2/library/logging.handlers.html#logging.StreamHandler) without specifying `StreamHandler(stream=sys.stdout)`, it will log to STDERR by default - which means you're currently flushing the wrong stream in your code. – Lukas Graf Nov 25 '13 at 18:55

1 Answers1

4

You are not initialising the StreamHandler with sys.stdout, so it will use the documented default - sys.stderr. That's why your flushing of sys.stdout isn't having any effect - there's nothing the the code you posted which is causing writes to sys.stdout!

Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191