问题描述

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

代码结构如下:

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. ElasticSearch(十三):Spring Data ElasticSearch 的使用(三)——NativeSearchQuery 高亮查询

    在Elasticsearch的实际应用中,经常需要将匹配到的结果字符进行高亮显示,此处采取NativeSearchQuery原生查询的方法,实现查询结果的高亮显示. /** * 高亮查询 */ @Te ...

  2. 项目Beta冲刺--7/7

    项目Beta冲刺--7/7 作业要求 这个作业属于哪个课程 软件工程1916-W(福州大学) 这个作业要求在哪里 项目Beta冲刺 团队名称 基于云的胜利冲锋队 项目名称 云评:高校学生成绩综合评估及 ...

  3. 13、Python文件处理、os模块、json/pickle序列化模块

    一.字符编码 Python3中字符串默认为Unicode编码. str类型的数据可以编码成其他字符编码的格式,编码的结果为bytes类型. # coding:gbk x = '上' # 当程序执行时, ...

  4. wordpress时间函数the_time() 实例解读

    wordpress the_time()时间函数想必大家多多少少都会用到,但是要自定义一些时间相对没那么熟悉了,随ytkah一起来看看吧.我们知道时间函数基础调用是<?php the_time( ...

  5. stm32中的型号对比——为什么很少用STM32F2,F3?

    源自网络 我觉得有三点: 1. F2属于加强版的F1,内核还是cortex M3,只是主频提高到了120MHz(F1是72MHz),但是这点提升没有实质性意义,性能比不上 2. F3是F4的削弱版,一 ...

  6. IMP本质上是一个通用的函数指针

    IMP:通用的函数指针 /// A pointer to the function of a method implementation. #if !OBJC_OLD_DISPATCH_PROTOTY ...

  7. Codechef August Challenge 2019 Chef and Gordon Ramsay

    [传送门] 题目即求所有的三元组,相对大小关系同 $p_1,p_2,p_3$. 题解说都很清楚,这里写一下过程整理一下思路. 如果我们枚举中间这个元素,那么就是统计子树内外有多少个大于这个数和小于这个 ...

  8. (尚028)Vue_案例_交互删除

    删除一条;1.鼠标移入移除这一条时颜色有变化 2.删除当前的todo ================================================================= ...

  9. 几个java proxy servlet 工具

    HTTP-Proxy-Servlet 这个工具使用比较简单,可以通过配置,或者代码的方式 https://github.com/mitre/HTTP-Proxy-Servlet servlet 配置方 ...

  10. Tomcat8.x的安装与启动

    Tomcat是企业网站的服务器,大多都用于中.小型网站开发和学习开发JSP应用程序中.笔者也是开始学习,下面介绍Tomcat8.x的安装步骤. 进入Tomcat官网,点击左边的download目录下的 ...