关于 python 写 log 的一个疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
kier
V2EX    Python

关于 python 写 log 的一个疑问

  •  
  •   kier 2016-11-08 10:47:45 +08:00 5680 次点击
    这是一个创建于 3262 天前的主题,其中的信息可能已经有所发展或是发生改变。
    python 自带的 logging 模块虽然有 timerotate ,但是它是把当前 log 文件重命名,然后再开新文件,这样的话,就容易会出现多 process 冲突的问题!
    所以楼主在上家公司时,是用的从 logging 模块扩展的模块,具体实现是每小时一个日志文件(文件名里包含时间信息),各个 process 都 append 方式打开写入,当前小时的 log 写完了,自动用 append 方式打开下一个日志文件,这样就不存在重命名的问题,也不会有多 process 冲突的问题。
    最近做项目,还是想用这种方式,但是换了东家,原来的代码没找到,所以想网上找,结果一点相关的都没找到,难道就没人这么用的吗?那大家是如何处理写 log ,多 process 的问题呢?都用 sockethandler ,让一个单独的服务去同一写日志?
    19 条回复    2016-11-09 20:13:13 +08:00
    iyaozhen
        1
    iyaozhen  
       2016-11-08 11:00:34 +08:00 via Android
    这就是两种打日志的风格了。
    一种是 access.log
    一种是 access.log.2016110810
    看日志框架的类型了,一般都支持自己滚动日志。
    不过一般第一种用的多, op 会自己配置日志切分程序,先 mv 重命名日志,然后再给写日志的进程发一个啥信号,然后程序会自动在原来的位置再起一个新文件打日志。
    knightdf
        2
    knightdf  
       2016-11-08 11:08:58 +08:00
    python 自带的 TimedRotatingFileHandler 本来就在多进程下有 bug,会误删日志.得自己重写 doRollover 函数
    doer233
        3
    doer233  
       2016-11-08 11:10:26 +08:00 via Android
    python 新手请教个问题,生产项目的 log 代码直接写在生产代码里面吗?
    lostarray
        4
    lostarray  
       2016-11-08 12:48:36 +08:00 via iPhone   2
    如果是在 Linux 下,可以考虑用 syslog 和 logrotate
    onlyice
        5
    onlyice  
       2016-11-08 12:50:14 +08:00
    Python 的官方文档有提到这个问题: https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes

    QueueHandler 可以解决这个问题。它是在 Python 3 中加入的; Python 2 中没有,但是也可以搜到类似代码。
    yanchao7511461
        6
    yanchao7511461  
       2016-11-08 13:13:15 +08:00
    借楼问个问题
    一般 python 的 traceback 是出错定位的重要信息。但是一个程序里面 我又不想用 try... 能不能想办法把这个错误信息保存下来。看到具体哪行出错。 是不是除了 2 >&1 没办法了?
    onlyice
        7
    onlyice  
       2016-11-08 15:16:17 +08:00 via Android
    @yanchao7511461 logging 里面的 logger.exception 函数
    yanchao7511461
        8
    yanchao7511461  
       2016-11-08 19:32:10 +08:00
    @onlyice 不太明白怎么用...我用 logger 一般都是 try 。。。。 excetion logger.error(" xxx error !!").都是通过 try 然后输出信息的... 所以一旦我的程序后台运行的,某一个我没想到的位置崩溃了。我就看不到 traceback 了.... 能给个例子 说一下 logger.exception 怎么用么
    onlyice
        9
    onlyice  
       2016-11-08 19:39:54 +08:00   1
    @yanchao7511461 啊,我读题没读仔细。。

    logger.exception 函数可以把 traceback 也打印下来。

    但是对于未捕获的异常,你可以修改 sys.excepthook 来自定义行为: https://docs.python.org/2/library/sys.html#sys.excepthook

    但是我不确定是不是好的实践。。感觉可以看看 Sentry 怎么做
    kier
        10
    kier  
    OP
       2016-11-08 20:47:46 +08:00
    @knightdf 嗯,如果按照我帖子里描述的方法,多进程也是没有问题的,只是我在网上居然没有发现有哪怕一个人是用这种方式的,所以觉得很诧异!因为我的理解,对于中小型项目,这种方法的开发运维成本是最低的!
    kier
        11
    kier  
    OP
       2016-11-08 20:51:10 +08:00   1
    @yanchao7511461 @onlyice 无法预知的 exception 没有必要自己去 try catch ,就让它落到 stderr 就 ok 了,而对于服务端程序这类需要常驻运行的,一般在最外层会捕获异常,并输出的
    onlyice
        12
    onlyice  
       2016-11-08 21:34:18 +08:00
    @kier 嗯是的,只是 @yanchao7511461 的场景是他不想去 try catch ,所以可能 sys.excepthook 有作用
    fengclient
        13
    fengclient  
       2016-11-08 22:35:09 +08:00 via iPhone
    同意上面说的 syslog/rsyslog ,可以很好解决多点写入的问题,这也是大型系统的标准操作吧。
    knightdf
        14
    knightdf  
       2016-11-08 23:40:57 +08:00
    @kier 只要有新文件产生,append 必然也会有问题,因为问题就出在谁来产生这个新文件这.
    ericls
        15
    ericls  
       2016-11-09 01:44:35 +08:00
    用个 queue 来专门写日志
    restran
        16
    restran  
       2016-11-09 08:39:17 +08:00
    kier
        17
    kier  
    OP
       2016-11-09 10:25:20 +08:00
    @knightdf 用 append 的方式 open 文件,应该没问题吧, open 应该是 atomic 操作吧
    zjq426
        18
    zjq426  
       2016-11-09 16:03:25 +08:00
    @kier https://github.com/zhujiaqi/pycrabapi/tree/master/miscs/logger

    我前前东家的项目里面刚好也有这个东西,在前前同事们的授意下我给他开源了
    heqingpan
        19
    heqingpan  
       2016-11-09 20:13:13 +08:00
    @kier
    http://www.cnblogs.com/shizioo/p/python_logging_handler_custom.html
    ---
    import logging
    import os,os.path
    import datetime

    _filefmt=os.path.join("logs","%Y-%m-%d","%H.log")
    class MyLoggerHandler(logging.Handler):
    def __init__(self,filefmt=None):
    self.filefmt=filefmt
    if filefmt is None:
    self.filefmt=_filefmt
    logging.Handler.__init__(self)
    def emit(self,record):
    msg=self.format(record)
    _filePath=datetime.datetime.now().strftime(self.filefmt)
    _dir=os.path.dirname(_filePath)
    try:
    if os.path.exists(_dir) is False:
    os.makedirs(_dir)
    except Exception:
    print "can not make dirs"
    print "filepath is "+_filePath
    pass
    try:
    _fobj=open(_filePath,'a')
    _fobj.write(msg)
    _fobj.write("\n")
    _fobj.flush()
    _fobj.close()
    except Exception:
    print "can not write to file"
    print "filepath is "+_filePath
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3675 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 10:31 PVG 18:31 LAX 03:31 JFK 06:31
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86