flask日志和gunicorn日志合并

logging

logging框架中主要有四个部分组成:

  • Loggers:可供程序直接调用的接口
  • Handlers:决定将日志记录分配至正确的目的地
  • Filters:提供更细粒度的日志是否输出的判断
  • Formatters:制定最终记录打印的格式布局

logging是作为一个模块被引入的。logging.debug用的是logging模块的方法。logger是用logging.getLogger()生成的,是一个日志对象,logger.debug调用的是logger这个日志对象的方法。在下面的例子中logging.debug和logger.debug的效果是完全一样的。

import logging
 
logging.debug('调试信息')
 
logger = logging.getLogger()
 
logger.debug('调试信息')

为了开发者方便使用,logging模块提供了一系列模块方法,在引入模块后,就可以直接使用。这样开发者就不用关系日志模块的细节,像用print一样输出日志。

在使用模块方法,logging其实创建了一个日志对象—root logger。即logging.debug这个调用,实质上是调用root logger的日志方法。相当于默认情况下root logger会作为日志处理对象。root logger对象可以通过不带参数的logging.getLogger()方法获得。

  • 基本使用
import logging
logging.basicConfig(level = logging.INFO,filename="path",filemode="a",format = '%(asctime)s %(message)s') #全局配置
logging.info("")
logging.debuge("")
logging.warning("")
  • 高级使用
import logging
logger = logging.getLogger()  # 记录器
logger.setLevel(logging.INFO)

consoleHandler = logging.StreamHandler() # 处理器
consoleHandler.setLevel(logging.DEBUG)

fileHandler = logging.FileHandler("path") # 处理器

formatter = logging.Formatter('%(asctime)s %(message)s') # 输出格式

# 将Handler与Formatter关联
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)

#将Handler与logger关联
logger.addHandler(consoleHandler)
logger.addHandler(fileHandler)

# 使用logger写入日志信息
logger.info("")
logger.debug("")

flask日志

flask具有自带的logger,在程序中只需要使用app.logger调用即可。

  • flask日志显示到文件中。

    if __name__ == '__main__':
        fh = logging.FileHandler(filename='./log/flask_matting_head.log', encoding='utf-8')
        logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                            datefmt='%a, %d, %b %Y %H:%M:%S',
                            handlers=[fh])
        app.debug = True
        app.run(host='0.0.0.0', port=7788, debug=True)
    
  • flask日志显示在控制台

	if __name__ == '__main__':
        logger = logging.getLogger()
		logger.setLevel('DEBUG')
		BASIC_FORMAT = '%(asctimie)s:%(levelname)s:%(message)s'
		DATE_FORMAT = '%y-%m-%d %H:%M:%S'
		formatter = logging.Formatter(BASIC_FORMAT, DATE_FORMAT)
		chlr = logging.StreamHandler()
		chlr.setFormatter(formatter)
		logger.addHandler(chlr)
		logger.setLevel('DEBUG')
	    app.run(host='0.0.0.0', port=7788, debug=True)

gunicorn日志

gunicorn可以用logging.config来进行完整的配置。
gunicorn中日志的配置。

```python
# !/usr/bin/env python
# -*- coding: utf-8 -*-
#
# @Author: xxx
# @Date  : 1/17/22 9:09 AM
# @File  : config.py

# config.py
import os
import gevent.monkey
gevent.monkey.patch_all()
import multiprocessing

#debug = True
bind = '0.0.0.0:7788'
pidfile = 'log/gunicorn.pid'

logconfig_dict = {
    'version':1,
    'disable_existing_loggers': False,
    'loggers':{
        "gunicorn.error": {
            "level": "WARNING",# 打日志的等级可以换的,下面的同理
            "handlers": ["error_file"], # 对应下面的键
            "propagate": 1,
            "qualname": "gunicorn.error"
        },

        "gunicorn.access": {
            "level": "DEBUG",
            "handlers": ["access_file"],
            "propagate": 0,
            "qualname": "gunicorn.access"
        }
    },
    'handlers':{
        "error_file": {
            "class": "logging.handlers.RotatingFileHandler",
            "maxBytes": 1024*1024*1024,# 打日志的大小,我这种写法是1个G
            "backupCount": 1,# 备份多少份,经过测试,最少也要写1,不然控制不住大小
            "formatter": "generic",# 对应下面的键
            # 'mode': 'w+',
            "filename": "./log/gunicorn.error.log"# 打日志的路径
        },
        "access_file": {
            "class": "logging.handlers.RotatingFileHandler",
            "maxBytes": 1024*1024*1024,
            "backupCount": 1,
            "formatter": "generic",
            "filename": "./log/gunicorn.access.log",
        }
    },
    'formatters':{
        "generic": {
            "format": "'[%(process)d] [%(asctime)s] %(levelname)s [%(filename)s:%(lineno)s] %(message)s'", # 打日志的格式
            "datefmt": "[%Y-%m-%d %H:%M:%S %z]",# 时间显示方法
            "class": "logging.Formatter"
        },
        "access": {
            "format": "'[%(process)d] [%(asctime)s] %(levelname)s [%(filename)s:%(lineno)s] %(message)s'",
            "class": "logging.Formatter"
        }
    }
}

capture_output = True
#loglevel = 'warning'
loglevel = 'debug'


daemon = True #后台启动
reload = True

#workers = multiprocessing.cpu_count()
workers = 1
worker_class = 'gevent'
x_forwarded_for_header = 'X-FORWARDED-FOR'

```

如果需要将Flask的logger和Gunicorn的日志合并,那么需要在Flask中加入这样一段代码。即当Flask不是自启动的时候,是被Gunicorn启动,那么则获取到gunicorn.error的logger,将app.logger的handler赋值成gunicorn.error.handler。将app.logger的logger.level设置成和Gunicorn配置相同的level。

if __name__ != '__main__':
    gunicorn_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)

参考资料
logging的理解和使用一
Flask 和 Gunicorn 的logger
gunicorn部署flask的log处理
gunicorn日志的问题
神器 logging,你真的了解吗?
logging的基本使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值