flask的自带logger和celery的自带logger的使用
前言
python有默认的日志配置,但是对于业务开发来说一般需要配置自己的日志输出方式,同时各种框架也继承了日志相关的内容。下面记录一下celery和flask框架中自带的logger使用方法。
flask使用logger
flask中的app对象自带了logger方法,其本质上是在python内置的logging模块上进行封装使用,其调用的方式为:
from flask import current_app
current_app.logger.error('this is a error')
current_app.logger.info('this is a info')
current_app.logger.warning('this is a wraning')
current_app.logger.debug('this is a debug')
配置方法
日志的配置方法有多种,和python配置日志的方式是一样的。
可参考:python日志配置logger
- 通过字典配置
#logging.py
logger_dict = {
'version': 1, # 该配置写法固定
'formatters': { # 设置输出格式
'default': {'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',}
},
# 设置处理器
'handlers': {
'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
'formatter': 'default',
'level': 'DEBUG'
}},
# 设置root日志对象配置
'root': {
'level': 'INFO',
'handlers': ['wsgi']
},
# 设置其他日志对象配置
'loggers': {
'test':
{'level': 'DEBUG',
'handlers':['wsgi'],
'propagate':0}
}
}
- 源码分析
flask的logger其实也是通过python的logging模块创建logger对象得到的,源码为:
# logging.py
from logging import getLogger, getLoggerClass
def create_logger(app):
...
# 创建一个调试模式下的日志处理器,级别为debug
debug_handler = DebugHandler()
debug_handler.setLevel(DEBUG)
debug_handler.setFormatter(Formatter(DEBUG_LOG_FORMAT))
# 创建一个运行过程的日志处理器,级别为error
prod_handler = ProductionHandler(_proxy_stream)
prod_handler.setLevel(ERROR)
prod_handler.setFormatter(Formatter(PROD_LOG_FORMAT))
# 获取应用的名字,即app = Flask(app.name)传入的参数名,然后创建一个logger对象
logger = getLogger(app.logger_name)
# 先清空以前所有的处理器
del logger.handlers[:]
logger.__class__ = DebugLogger
# 加入新的处理器
logger.addHandler(debug_handler)
logger.addHandler(prod_handler)
# 默认情况下不继承
logger.propagate = False
return logger
当程序调用current_app.logger时,会得到create_logger函数返回的logger对象,如果我们开启的是调试模式,会使用debug_handler处理器;如果是非调试模式使用的是ProductionHandler处理器,日志的输出格式为:
# 调试模式格式
DEBUG_LOG_FORMAT = (
'-' * 80 + '\n' +
'%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n' +
'%(message)s\n' +
'-' * 80
)
# 非调试模式格式
PROD_LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
此外我们开发程序时可以看到除了我们调用current_app.logger产生的日志信息外,还有flask默认的日志信息,这个默认的日志输出我们是可以通过配置日志文件来修改的,但是current_app.logger产生的日志信息的格式是固定的,如果不满足我们的要求的话就需要手动创建logger对象来使用。
细节
我们加载日志文件的时候应该尽可能的早,避免在调用过一次app.logger之后才加载日志配置,所以最好在app被创建之前就加载日志配置文件。
# app.py
logging.config.fileConfig(Config.FILEPATH)
app = Flask(__name__)
在celery中使用logger
celery也封装了logger使用方法:
from celery.utils.log import get_task_logger
# 创建一个logger对象
logger = get_task_logger('name')
celery的logger调用的仍然是logging模块的logger.
# get_task_logger函数调用了get_logger函数
# 传入一个字符串获取一个logger对象
def get_logger(logger):
"""Get logger by name."""
# 判断该参数是不是字符串,是就获取一个logger对象
if isinstance(logger, string_t):
logger = logging.getLogger(logger)
# 没有处理器就添加NullHandler处理器
if not logger.handlers:
logger.addHandler(logging.NullHandler())
return logger
- 其相关的配置可以在celery的配置文件中设置;
# 在4.0版本后改成了小写,但是原来的还没有弃用
CELERYD_HIJACK_ROOT_LOGGER :默认true,先前所有的logger的配置都会失效,可以通过设置false禁用定制自己的日志处理程序;
CELERYD_LOG_COLOR :是否开启不同级别的颜色标记,默认开启;
CELERYD_LOG_FORMAT :设置celery全局的日志格式;默认格式:"[%(asctime)s: %(levelname)s/%(processName)s] %(message)s"
CELERYD_TASK_LOG_FORMAT:设置任务日志格式,默认:"[%(asctime)s: %(levelname)s/%(processName)s [%(task_name)s(%(task_id)s)] %(message)s"
CELERY_REDIRECT_STDOUTS:设置标准输入输出重定向到当前的处理器,默认为 true
CELERY_REDIRECT_STDOUTS_LEVEL:设定标准输入输出重定向到当前的处理器日志的输出级别;即指定使用print()输出的是什么级别的日志记录;默认wraning;
注意:
由于celery的运行是独立的,在flask中定义的logger对象的配置在celery的程序中是失效的,必须使用get_task_logger创建logger;
指定celery日志的输出等级,通过启动时用--loglevel参数来指定;
参考
http://docs.jinkan.org/docs/celery/configuration.html#logging
http://docs.celeryproject.org/en/latest/userguide/configuration.html
flask的自带logger和celery的自带logger的使用的更多相关文章
- 转: 带你玩转Visual Studio——带你理解多字节编码与Unicode码
上一篇文章带你玩转Visual Studio——带你跳出坑爹的Runtime Library坑帮我们理解了Windows中的各种类型C/C++运行时库及它的来龙去脉,这是C++开发中特别容易误入歧途的 ...
- 带缓冲I/O 和不带缓冲I/O的区别与联系
首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用.系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其 ...
- 带你玩转Visual Studio——带你了解VC++各种类型的工程
原文地址:http://blog.csdn.net/luoweifu/article/details/48816605 上一篇文章带你玩转Visual Studio——带你新建一个工程一文中提到新建一 ...
- 带你玩转Visual Studio——带你理解微软的预编译头技术
原文地址:http://blog.csdn.net/luoweifu/article/details/49010627 不陌生的stdafx.h 还记得带你玩转Visual Studio——带你新建一 ...
- 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小
少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...
- 带你玩转Visual Studio——带你理解多字节编码与Unicode码
目录(?)[-] 多字节字符与宽字节字符 char与wchar_t string与wstring string 与 wstring的相关转换 字符集Charcater Set与字符编码Encoding ...
- 【转载】IIS网站配置不带www域名直接跳转带www的域名
很多时候为了统一网站入口,需要将不带www的主域名解析到带www的域名记录下,当客户访问不带www的域名网址的时候自动跳转到带www的域名,在IIS Web服务器中可以通过URL重写模块来实现此功能, ...
- Flask实战第66天:celery实现异步任务
Celery文档:http://docs.celeryproject.org Celery 通过消息进行通信,用专用的工作线程不断监视任务队列以执行新工作. Celery需要消息传输来发送和接收消息. ...
- C/C++ 不带参数的回调函数 与 带参数的回调函数 函数指针数组 例子
先来不带参数的回调函数例子 #include <iostream> #include <windows.h> void printFunc() { std::cout<& ...
随机推荐
- Spark学习笔记之RDD中的Transformation和Action函数
总算可以开始写第一篇技术博客了,就从学习Spark开始吧.之前阅读了很多关于Spark的文章,对Spark的工作机制及编程模型有了一定了解,下面把Spark中对RDD的常用操作函数做一下总结,以pys ...
- 多线程里面的关键字,wait, notfiy, 锁(synchronized), lock接口
多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...
- SpringCloud的Hystrix(二) 某消费者应用(如:ui、网关)访问的多个微服务的断路监控
一.验证断路保护监控是否管理多个消费者 app 1.第1个消费者应用:访问自己封装rest服务 saleProd 2.第2个消费者应用:第二个应用没有反应 说明 1.每个应用实例的断路保护机制,只对本 ...
- HTTP协议扫盲(八 )响应报文之 Transfer-Encoding=chunked方式
一.什么是chunked编码? 分块传输编码(Chunked transfer encoding)是只在HTTP协议1.1版本(HTTP/1.1)中提供的一种数据传送机制.以往HTTP的应答中数据是整 ...
- CURL学习总结(1)
1.curl是什么? 百度百科定义: curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多种Linux发行版中,并且有DOS和Win32.W ...
- hadoop2.6.0实践:004 启动伪分布式hadoop的进程
[hadoop@LexiaofeiMaster hadoop-2.6.0]$ start-dfs.shStarting namenodes on [localhost]localhost: start ...
- C#程序编写规范
代码书写规则 1.尽量使用接口,然后使用类实现接口,提高程序的灵活性. 2.一行不要超过80个字符. 3.尽量不要手工更改计算机生成的代码,若必须要改,一定要改为和计算机生成的代码风格一样. 4.关键 ...
- word2vec初探(用python简单实现)
为什么要用这个? 因为看论文和博客的时候很常见,不论是干嘛的,既然这么火,不妨试试. 如何安装 从网上爬数据下来 对数据进行过滤.分词 用word2vec进行近义词查找等操作 完整的工程传到了我的gi ...
- vue2.0项目引入element-ui
在项目中,为了方便我们工作和开发效率,常常引入一些框架来帮助我们完成高效的工作,今天我们就用vue来搭建一下框架,并且引入element-ui这个框架.安装流程也是我从失败中摸索到的,希望能帮助大家. ...
- 彻底弄懂JS的事件冒泡和事件捕获
先上结论:在事件执行流中有两种执行方式.一种是事件冒泡(即事件的执行顺序是从下往上执行的) ; 另一种是捕获(即事件的执行顺序是从上往下执行的); 阻止事件冒泡: return false; ...