如何获取日志消息

时间:2015-08-06 00:47:19

标签: python logging

import serial
import string
from time import sleep
from subprocess import call, check_call, CalledProcessError
import logging

import random
import signal
import os

LOG_FILENAME = "/tmp/dfu.log"
LOG_FD = open(LOG_FILENAME, "w")

logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)

dfu_image_list = ['/tmp/sample.dfu']

while True:
    try:
        for test_file in dfu_image_list:
            logging.info("\n==================\nbegin dfu download test")
            check_call('sudo dfu-util -vD /tmp/sample.dfu', shell=True,  
                        stdout=LOG_FD, stderr=LOG_FD)
            logging.info("Download completed successfully!")
            sleep(5)   

    except CalledProcessError as e:
        msg = "dfu-util failed with return code :%s \n\nMessage:%s" % 
               (e.returncode, e.message)
        logging.warning(msg)
        logging.warning("USB device likely needs time to re-enumerate, 
                         waiting 10 seconds before restarting")
        sleep(10)

    except OSError:
        logging.error("dfu-util executable not found!")
        exit(1)

执行上面的python脚本会在/tmp/dfu.log中提供日志。 但是,日志文件中的日志来自函数check_call。 预期的行为是主线程日志,如

logging.info("\n==================\nbegin dfu download test")
logs of function check_call
logging.info("Download completed successfully!").

然而,只有函数check_call的日志被反映,主线程记录如

begin dfu download test
Download completed successfully!

没有反映到日志文件中。

1 个答案:

答案 0 :(得分:0)

请记住,日志记录模块会执行一些缓冲,这意味着使用log.something()编写日志并不一定意味着此日志将写入文件。

此外,您正在打开文件两次,并从不同的位置写入文件。通常这是一个坏主意,即使Linux是先发制人的,你刷新日志并且可能工作仍然是个坏主意。

communicate()使用该流程而不是check_call(),然后根据需要记录stdoutstderr。例如:

for image in dfu_image_list:
    logging.info('=' * 10)
    logging.info('Begin dfu download using {}'.format(image))

    process = Popen(['sudo', 'dfu-util', '-vD', image], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()

    logging.info(stdout)
    if stderr:
        logging.warning(stderr)

    logging.info('Download completed successfully!')

顺便说一句,你的循环逻辑是有缺陷的。因为任何错误都会重新启动dfu_image_list图像的循环。

我认为这更像是你想做的事情:

from sys import exit
from time import sleep
from subprocess import Popen, PIPE, CalledProcessError
import logging


LOG_FILENAME = "/tmp/dfu.log"
ATTEMPTS = 3

logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)


def download(where):

    logging.info('=' * 10)
    logging.info('Begin dfu download to {}'.format(where))

    for attempt in range(ATTEMPTS):
        logging.info('Attempt #{}...'.format(attempt + 1))

        try:
            process = Popen(
                ['sudo', 'dfu-util', '-vD', where],
                stdout=PIPE, stderr=PIPE
            )
            stdout, stderr = process.communicate()

            logging.info(stdout)
            if stderr:
                logging.warning(stderr)

            logging.info('Download completed successfully!')
            return True

        except CalledProcessError as e:
            logging.warning(
                'dfu-util failed with return code {}'.format(e.returncode)
            )
            logging.warning(
                'Message:\n{}'.format(e.message)
            )
            logging.warning(
                'USB device likely needs time to re-enumerate, '
                'waiting 10 seconds before restarting...'
            )
            sleep(10)
            continue

        except OSError:
            logging.critical('dfu-util executable not found!')

    return False


if __name__ == '__main__':
    if not download('/tmp/sample.dfu'):
        exit(1)
相关问题