python logging应用及与print的区别、log监控api调用、format的使用

(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)

猜你喜欢

转载自blog.csdn.net/sinat_26566137/article/details/81040927