问题描述

项目过程中写了一个小模块,设计到了日志存储的问题,结果发现了个小问题。

代码结构如下:

db.py
run.py

其中db.py是操作数据库抽象出来的一个类,run.py是业务逻辑代码。两个文件中都有使用Python自带的logging模块,来记录日志。其中前者将日志存入到db_xxx.log下,后者存入run_xxx.log下。

两者logging相关代码为:

# db.py
import logging
import time dt = time.time()
logging.basicConfig(filename='db_' + str(dt) + '.log', level=logging.INFO) # run.py
import logging
import time dt = time.time()
logging.basicConfig(filename='run_' + str(dt) + '.log', level=logging.INFO)

同时,在run.py中会调用db.py的函数,例如:

# db.py

class DB():
def __init__(self):
xxxx def select(self):
logging.info('log from db.py') # run.py from db import DB if __name__ == '__main__':
db = DB()
db.select() logging.info('log from run.py')

实际运行起来,发现所有的日志都只会存在 db_xxx.log 中,同时并不会产生 run_xxx.log 文件。

排错

猜测

依照上面的结果,猜测run.py文件中,引入的db.py中也有logging的设置,但只会有一个生效。

验证 1

写两个py文件first.py和second.py,在second中引用first的函数,看最终日志的输出文件名及顺序。

内容分别为:

# first.py

import logging

class TEST():
def __init__(self, log_type, dt):
dt = str(dt)
logging.basicConfig(filename='./log/' + log_type + '_' + dt + '.txt', level=logging.INFO) def test_log(self):
logging.info('log from first.py') # second.py from first import TEST
import time dt = time.time() import logging
logging.basicConfig(filename='./log/' + 'second.txt', level=logging.INFO)
logging.info('log from second') test = TEST('db', dt)
test.test_log() # 结果 ➜ log_dir_test python second.py
➜ log_dir_test ls log
second.txt
➜ log_dir_test cat log/second.txt
INFO:root:log from second
INFO:root:log from first.py

可以看到,文件名为 second.txt,即采用了 second.py 的logging设置。同时,日志输出的顺序也是先输出 second 再是 first。

验证 2

此时尝试将second.py的语句顺序做一个调整,调整为下面:

# second.py

from first import TEST
import time dt = time.time()
test = TEST('db', dt)
test.test_log() import logging
logging.basicConfig(filename='./log/' + 'second.txt', level=logging.INFO)
logging.info('log from second') # result ➜ log_dir_test cat log/db_1561088221.83.txt
INFO:root:log from first.py
INFO:root:log from second

可以看到结果存储到了 db_xxx.txt 中,即采用了 first.py 的logging设置。

验证 3

再对second.py做调整:

# second.py

from first import TEST
import time dt = time.time()
test = TEST('db', dt) import logging
logging.basicConfig(filename='./log/' + 'second.txt', level=logging.INFO)
logging.info('log from second') test.test_log() # result ➜ log_dir_test cat log/db_1561088393.36.txt
INFO:root:log from second
INFO:root:log from first.py

采用了first.py的设置

验证 4

继续调整second.py:

# second.py

from first import TEST
import time
import logging
logging.basicConfig(filename='./log/' + 'second.txt', level=logging.INFO) dt = time.time()
test = TEST('db', dt) logging.info('log from second') test.test_log() # result ➜ log_dir_test cat log/second.txt
INFO:root:log from second
INFO:root:log from first.py

采用了 second.py 的设置

共性

可以发现,两个文件的logging设置,在second.py的顺序,影响了second.py的logging设置。即:

  • first.py 的logging设置在前的时候,采用first.py的设置
  • 反正,采用second.py的设置
  • 只采用其中一个设置

解释

起初觉得奇怪,现在想想还是比较容易理解的。

假如 second.py 中已经设置了logging,后面引用了first.py的函数,first.py中又设置了logging。若此时又采用 first.py的设置,那后续如果second.py中又使用了logging.xxx怎么办?也就是说,Python会觉得混乱,不知所措……

解决办法

如果还是想达到 db.py 操作都存储到 db 相关目录下,run日志存储到run目录下怎么办?似乎没太好的解决办法;不优雅的处理方式,可以采用文件操作……比方说使用with open(xx) as f去操作,这样的话,比较繁琐。

更好的办法是什么?就是现在Python的这种机制。即 run.py 相关日志都存储到 run 目录下,即使调用了 db.py 的函数,日志也存储到 run 目录下。这样可以保证 run.py 的日志是全的,且时间顺序是正确的,减少了排错的成本。

Python logging模块日志存储位置踩坑的更多相关文章

  1. python logging模块日志回滚TimedRotatingFileHandler

    # coding=utf-8 import logging import time import os import logging.handlers import re def logger(app ...

  2. python logging模块日志回滚RotatingFileHandler

    # coding=utf-8 import logging import time import os import logging.handlers def logger(appname,roots ...

  3. python logging模块日志输出

    import logging logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) handler = ...

  4. Python logging模块无法正常输出日志

    废话少说,先上代码 File:logger.conf [formatters] keys=default [formatter_default] format=%(asctime)s - %(name ...

  5. (转)python logging模块

    python logging模块 原文:http://www.cnblogs.com/dahu-daqing/p/7040764.html 1 logging模块简介 logging模块是Python ...

  6. python logging模块使用总结

    目录 logging模块 日志级别 logging.basicConfig()函数中的具体参数含义 format参数用到的格式化信息 使用logging打印日志到标准输出 使用logging.base ...

  7. 0x01 Python logging模块

    目录 Python logging 模块 前言 logging模块提供的特性 logging模块的设计过程 logger的继承 logger在逻辑上的继承结构 logging.basicConfig( ...

  8. python logging模块可能会令人困惑的地方

    python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调 ...

  9. python logging模块使用

    近来再弄一个小项目,已经到收尾阶段了.希望加入写log机制来增加程序出错后的判断分析.尝试使用了python logging模块. #-*- coding:utf-8 -*- import loggi ...

随机推荐

  1. MySQL倒序索引测试1

    测试环境 MySQL Community Server 准备测试数据 DROP TABLE TB001; CREATE TABLE TB001(ID INT PRIMARY KEY AUTO_INCR ...

  2. Mybatis如何插入空字段

    出现异常:SQLException : 无效的类型: 1111 使用Mybatis插入一条记录,某字段设为null,出错 尝试将空的mgr属性插入到数据库,解决办法: 添加setting属性jdbcT ...

  3. MAC安装配置maven环境变量

    1.下载maven包: 下载链接:

  4. Httpd服务入门知识-Httpd服务常见配置案例之基于客户端来源地址实现访问控制

    Httpd服务入门知识-Httpd服务常见配置案例之基于客户端来源地址实现访问控制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Options  1>.OPTIONS指 ...

  5. php命令模式(command pattern)

    ... <?php /* The command pattern decouples the object that executes certain operations from objec ...

  6. 2019年牛客多校第四场 B题xor(线段树+线性基交)

    题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...

  7. 【转】Linux 网络工具详解之 ip tuntap 和 tunctl 创建 tap/tun 设备

    原文:https://www.cnblogs.com/bakari/p/10449664.html -------------------------------------------------- ...

  8. underscore 工具

    =============== 通知: 博主已迁至<掘金>码字,博客园可能以后不再更新,掘金地址:https://juejin.im/post/5a1a6a6551882534af25a8 ...

  9. Properties 取值和设置函数 Hashtable的静态内部类Entry的结构和克隆方法

  10. Vue——核心思想--mvvm

    Vue的核心思想为数据驱动和组件化. 一.数据驱动——双向绑定 Vue是一种MVVM框架.而DOM是数据的一个种自然映射.传统的模式是通过Ajax请求从model请求数据,然后手动的触发DOM传入数据 ...