问题描述

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

代码结构如下:

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. Docker 0x13: Docker 构建集群/服务/Compose/分布式服务栈

    目录 Docker 构建集群/服务/Compose/分布式服务栈 集群 初始化集群服务 安装docker-machine 管理节点和工作节点 docker集群构建完成 集群中部署应用 集群服务访问特性 ...

  2. 大数据:Hadoop(HDFS 读写数据流程及优缺点)

    一.HDFS 写数据流程 写的过程: CLIENT(客户端):用来发起读写请求,并拆分文件成多个 Block: NAMENODE:全局的协调和把控所有的请求,提供 Block 存放在 DataNode ...

  3. Httpd服务入门知识-正向代理和反向代理

    Httpd服务入门知识-正向代理和反向代理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.正向代理和反向代理 启用反向代理 ProxyPass "/" &q ...

  4. Httpd服务入门知识-Httpd服务常见配置案例之日志设定

    Httpd服务入门知识-Httpd服务常见配置案例之日志设定 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.日志类型 [root@node101.yinzhengjie.org ...

  5. ECHO命令输出空行的11种方法和效率

    标题: 批处理技术内幕:ECHO命令作者: Demon链接: http://demon.tw/reverse/cmd-internal-echo.html版权: 本博客的所有文章,都遵守“署名-非商业 ...

  6. Win10系统如何关闭自动更新?

    现在很多电脑的系统都升级到了win10了,win10已经渐渐普及到每个人的电脑中,但是,win10系统有一个功能特别讨人厌,我自认为挺讨厌这个功能的,它就是“自动更新”功能,你可能会说,自动更新不是挺 ...

  7. vue element-ui 饿了么布局,gutter间距碰上bordr 会失效

    //如下情况,gutter间距会失效 <el-row :gutter="20"> <el-col :span="12" style=" ...

  8. autoRoll_UpDown()|上下滚动函数|无缝|自动(自带demo)

    autoRoll_UpDown函数 function autoRoll_UpDown($domObj,speed){ //$domObj 外围容器的jQuery式元素对象 speed 滚动速度,单位毫 ...

  9. iOS开源库分类

    语言库 rx aop kvo 功能库 UI network data-model-map cache 跨平台库 wkjscorebridge jspatch 性能监控库:友盟 部署库:jspathc ...

  10. java 泛型 类型作为参量 Class<T> transform

    Class<T> transform T:作为类型,用于定义变量: transform:作为具体类的类:用于创建实例. 类型信息是脱敏的具体类: 可以使用class的具体功能: 不能使用具 ...