将错误记录到两个不同的文件中

时间:2015-03-24 19:35:59

标签: python logging

我是python上logging模块的新手,我决定在我的一个程序中使用它。这是我的功能

def _get_local_err_logger():

    try:
        # logs_dir = "logs"
        parent_dir = exec_dir
        logs_dir = os.path.join(parent_dir, "logs")
        if not os.path.exists(logs_dir):
            os.makedirs(logs_dir)
    except Exception as e:
        print str(e)
        exit(1)

    logging.basicConfig(
        filename=os.path.join(logs_dir, 'cli.log'),
        level='ERROR',
        format='%(asctime)s %(levelname)s: %(message)s'
    )
    return logging.getLogger('cli.log')

在main()..

exec_file = os.path.abspath( argv[0] )
exec_dir = os.path.dirname( exec_file )

try:
        log_filename = args.logfile if args.logfile else config.get('Logging', 'filename') 
    except (NoOptionError, NoSectionError) as e:
        logger = _get_local_err_logger()
        logger.error( str( e ) )
        exit(1)

    if not os.path.isabs( log_filename ):
        log_filename = os.path.join(exec_dir, log_filename)

    try:                                            
        logging.basicConfig(
            filename=log_filename,
            level=config.get( 'Logging', 'log_level' ),
            format=config.get( 'Logging', 'format' )
        )
        logger = logging.getLogger('cli.log')
    except Exception as e:
        logger = _get_local_err_logger()
        logger.exception( "Logging configuration error({0})".format( str( e ) ) )
        exit(1)

但是我刚刚注意到一个奇怪的问题(主要是因为我可能不完全理解logging模块)。 我从配置文件中读取了一些凭据(密钥)以及以下内容:

[Logging]
filename = cli.log 
log_level = INFO
format = %(asctime)s %(levelname)s: %(message)s

当我使用我的程序(CLI)时,所有日志都会写入与程序位于同一目录中的cli.log文件中。但是,当我在配置文件中注释掉[Logging]部分时,错误(NoSectionError)会写入名为' cli.log'的文件中。在名为' logs'的文件夹中在我的程序所在的目录中创建。我希望我的所有日​​志都放在logs目录中的文件中,但我不确定为什么要写入2个不同的文件。

如果我将logs中的代码更改为:

,我可以将所有日志记录到main()目录中的文件中
try:
        log_filename = args.logfile if args.logfile else config.get('Logging', 'filename') 
    except (NoOptionError, NoSectionError) as e:
        logger = _get_local_err_logger()
        logger.error( repr( e ) )
        exit(1)

    if not os.path.isabs( log_filename ):           
        logs_directory = os.path.join( exec_dir, "logs" )       
        if not os.path.exists( logs_directory ):
            os.makedirs( logs_directory )
        log_filename = os.path.join( logs_directory, log_filename )

    try:                            
        logging.basicConfig(
            filename=log_filename,
            level=config.get( 'Logging', 'log_level' ),
            format=config.get( 'Logging', 'format' )
        )
        logger = logging.getLogger('cli.log')
    except Exception as e:
        logger = _get_local_err_logger()
        logger.exception( "Logging configuration error({0})".format( str( e ) ) )
        exit(1) 

然而,这几乎是重复该函数的代码,并且违反了DRY。有人能指出错误是什么吗?

1 个答案:

答案 0 :(得分:1)

def _get_logger(pdir,ldir,lname,level,fmt):
    try:
        logs_dir = os.path.join(pdir, ldir)
        if not os.path.exists(logs_dir):
            os.makedirs(logs_dir)
    except Exception as e:
        print e
        exit(1)

    logging.basicConfig(
        filename=os.path.join(logs_dir, lname),
        level=level,
        format=fmt
    )
    return logging.getLogger('cli.log')


exec_file = os.path.abspath(argv[0])
exec_dir = os.path.dirname(exec_file)
#build a dict with default configuration values for the logger
default_logger = dict(pdir=exec_dir,ldir='logs',lname='cli.log',level='ERROR',
                fmt='%(asctime)s %(levelname)s: %(message)s')

try:
    log_filename = args.logfile if args.logfile else config.get('Logging', 'filename')
    level = config.get('Logging', 'log_level')
    format = config.get('Logging', 'format')
except (NoOptionError, NoSectionError) as e:
    #unpack the configuration dict and call _get_logger
    logger = _get_logger(**default_logger)
    logger.error(repr(e))
    exit(1)
else:
    # we have successfully read configuration from file, so update
    # configuration dict to reflect new settings
    default_logger.update(fmt=format,level=level,lname=log_filename)
if os.path.isabs(log_filename):
    # log_filename is an absolute one. split it to get filename and dirname
    # and update configuration dict
    bdir, log_filename = os.path.split(log_filename)
    default_logger.update(pdir='',ldir=bdir,lname=log_filename)
logger = _get_logger(**default_logger)