(1)最常见的应用是:
把info,warning,error同时输出到cmd窗口(显示)和(写入)log文件中;
其中info表示告诉用户,这个是普通的信息;
warning和error分别提醒用户,有些警告,甚至是错误信息,需要用户注意;
把debug类信息,只输出(写入)到log文件中;
1)example_01,关于logging.debug的示例:
import logging
logging.basicConfig(filename='sample.log',level=logging.DEBUG,format = '%(asctime)s:%(name)s:%(message)s')
def add(x,y):
return x + y
def subtract(x,y):
return x - y
def multiply(x,y):
return x * y
def devide(x, y):
return x / y
num_1 = 10
num_2 = 5
add_result = add(num_1, num_2)
logging.debug('Add:{} + {} = {}'.format(num_1,num_2,add_result))
sub_result = subtract(num_1,num_2)
logging.debug("Sub: {} -{} = {}".format(num_1,num_2,sub_result))
mul_result = multiply(num_1,num_2)
logging.debug('Multip : {} * {} = {}'.format(num_1,num_2,mul_result))
devi_result = devide(num_1,num_2)
logging.debug('Devi : {} / {} = {}'.format(num_1 , num_2,devi_result))
Python想要输出log到文件中,可以有两种方式:
logging.basicConfig加上filename参数
logging.FileHandler
此次相同目录下,运行上述文件后,会产生一个名称是filename设定的sample.log文件,中记录的内容:
2018-07-14 09:24:20,290:root:Add:10 + 5 = 15
2018-07-14 09:24:20,330:root:Sub: 10 -5 = 5
2018-07-14 09:24:20,331:root:Multip : 10 * 5 = 50
2018-07-14 09:25:12,185:root:Add:10 + 5 = 15
2018-07-14 09:25:12,186:root:Sub: 10 -5 = 5
2018-07-14 09:25:12,186:root:Multip : 10 * 5 = 50
2018-07-14 09:25:20,519:root:Add:10 + 5 = 15
2018-07-14 09:25:20,520:root:Sub: 10 -5 = 5
2018-07-14 09:25:20,520:root:Multip : 10 * 5 = 50
2018-07-14 09:25:20,520:root:Devi : 10 / 5 = 2.0
2018-07-14 09:25:43,205:root:Add:10 + 5 = 15
2018-07-14 09:25:45,216:root:Sub: 10 -5 = 5
2018-07-14 09:25:45,892:root:Multip : 10 * 5 = 50
2018-07-14 09:25:46,551:root:Devi : 10 / 5 = 2.0
2018-07-14 09:25:53,671:root:Add:10 + 5 = 15
2018-07-14 09:25:53,672:root:Sub: 10 -5 = 5
2018-07-14 09:25:53,672:root:Multip : 10 * 5 = 50
2018-07-14 09:25:53,672:root:Devi : 10 / 5 = 2.0
2018-07-14 09:53:12,459:root:Add:10 + 5 = 15
2018-07-14 09:53:12,459:root:Sub: 10 -5 = 5
2018-07-14 09:53:12,460:root:Multip : 10 * 5 = 50
2018-07-14 09:53:12,460:root:Devi : 10 / 5 = 2.0
2018-07-14 09:54:34,299:root:Add:10 + 5 = 15
2018-07-14 09:54:34,299:root:Sub: 10 -5 = 5
2018-07-14 09:54:34,299:root:Multip : 10 * 5 = 50
2018-07-14 09:54:34,300:root:Devi : 10 / 5 = 2.0
2)关于logging.info的输出
import logging
logging.getLogger().setLevel(logging.INFO)
logging.basicConfig(filename= 'employee.log',level = logging.INFO,
format='%(levelname)s:%(name)s:%(message)s')
class Employee:
def __init__(self,first,last):
self.first = first
self.last = last
logging.info('Created Employee: {}-{}'.format(self.fullname,self.email))
@property
def email(self):
return '{}.{}@email.com'.format(self.first,self.last)
@property
def fullname(self):
return '{}{}'.format(self.first,self.last)
a=Employee('Jack',222)
print(a.email)
print(a.fullname)
结果,employee.log文件中内容如下:
INFO:root:Created Employee: Jack222-Jack.222@email.com
INFO:root:Created Employee: Jack222-Jack.222@email.com
INFO:root:Created Employee: Jack222-Jack.222@email.com
3)logging与print 区别,为什么需要logging?
在写脚本的过程中,为了调试程序,我们往往会写很多print打印输出以便用于验证,验证正确后往往会注释掉,一旦验证的地方比较多,再一一注释比较麻烦,这样logging就应运而生了,直接把验证信息存在一个文件中(例如在logging.basicConfig(里面设置filename= ‘employee.log’,)or直接打印出出来,不用设置finame,就会直接打印在cmd窗口中。
4)实现log使用basicConfig与真正的logging 的区别
a)使用basicConfig方法:
import logging
# 设置默认的level为DEBUG
# 设置log的格式
logging.basicConfig(
level=logging.DEBUG,
format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s"
)
# 记录log
logging.debug(...)
logging.info(...)
logging.warn(...)
logging.error(...)
logging.critical(...)
b)使用真正的logger:
import logging
# 使用一个名字为fib的logger
logger = logging.getLogger('fib')
# 设置logger的level为DEBUG
logger.setLevel(logging.DEBUG)
# 创建一个输出日志到控制台的StreamHandler
hdr = logging.StreamHandler()
formatter = logging.Formatter('[%(asctime)s] %(name)s:%(levelname)s: %(message)s')
hdr.setFormatter(formatter)
# 给logger添加上handler
logger.addHandler(hdr)
对比结论:
a) 上面说的basicConfig方法可以满足你在绝大多数场景下的使用需求,但是basicConfig有一个 很大的缺点。
b) 调用basicConfig其实是给root logger添加了一个handler,这样当你的程序和别的使用了 logging的第三方模块一起工作时,会影响第三方模块的logger行为。这是由logger的继承特性决定的。
c) 使用logger也可以进行日志输出,不过这样的坏处就是代码量比basicConfig要大不少。 所以我建议如果是非常简单的小脚本的话,直接使用basicConfig就可以,如果是稍微大一些 项目,建议认真配置好logger。
d) 以上这些只是介绍了logging模块最简单的一些功能,作为print的替代品来使用,logging 模块还有很多非常强大好用的功能,比如从文件读取配置、各种各样的Handlers等等。 建议阅读一下logging的官方文档:
(2)关于api请求的案例:
import requests
from requests import Timeout
from common.exceptions.api_exception import ApiException
from common.exceptions.data_exception import DataException
from scpy.logger import get_logger
import json
logging = get_logger(__file__)
class ApiHelper(object):
"""
api 辅助器
"""
@staticmethod
def get_url_dict(url):
"""
get 请求返回字典表
:type url str
"""
try:
logging.info('request:' + url)
response = requests.get(url, timeout=120, headers={'Connection': 'keep-alive'})
logging.info('response:' + url)
return response.json() if response.ok else {}
except Timeout as e:
logging.error('error url: %s', url)
logging.error('error message: %s', e.message)
raise ApiException(message=u"api请求超时", code=ApiException.CODE_TIMEOUT, inner_exception=e)
except Exception as e:
logging.error('error url: %s', url)
logging.error('error message: %s', e.message)
raise DataException(inner_exception=e)
@staticmethod
def post_url_dict(url, data):
"""
get 请求返回字典表
:param data:
:type url str
"""
try:
headers = {'Content-Type': 'application/json',
'Connection': 'keep-alive'}
logging.info('request:' + url)
response = requests.post(url, data=json.dumps(data), timeout=120, headers=headers)
logging.info('response:' + url)
return response.json() if response.ok else {}
except Timeout as e:
logging.error('error url: %s', url)
logging.error('error message: %s', e.message)
raise ApiException(message=u"api请求超时", code=ApiException.CODE_TIMEOUT, inner_exception=e)
except Exception as e:
logging.error('error url: %s', url)
logging.error('error message: %s', e.message)
raise ApiException(message=u"api请求未知错误", inner_exception=e)
if __name__ == '__main__':
from api.api_utils.api_helper import ApiHelper as apiH
from conf.config import *
import json
res = apiH.get_url_dict(GET_CMP_BASIC_INFO + "北京龙盛源小额贷款有限公司")
print (json.dumps(res, ensure_ascii=False, indent=4))
**上述利用log监控api调用代码:**
apiH.get_url_dict(GET_CMP_BASIC_INFO + "北京龙盛源小额贷款有限公司")
**format的使用是根据字符串中的"{}"的一起使用的:**
url_network_company_format = GET_CMP_BASIC_INFO + u'{}'
url = url_network_company_format.format(company_name)