给Hello World添加日志

回顾

通过上篇内容,我们已经使用「Flask」完成了我们的第一个接口。我们可以看到,使用「Flask」来编写接口是十分简单的。那么接下来,我们丰富一下上面的例子。

需求

现在的需求来了,在我们平时的开发过程中,总会遇到一些问题。但是又不是必现的,所以我们可以通过一些手段来写入日志,去发现问题。一个很明显的例子就是try/exception,遇到未知问题的时候可以将问题记录至日志并在事后排查。


日志模块选用

logging

我们知道,在Python中有系统自带的功能及其强大的logging模块供我们使用,它的强大不多做介绍了。网上的demo很多,稍微copy一个日志类就能使用。

logbook

这里我采用的是github上的「logbook」库,单看api调用的话,比logging方便较多。可能因为我是个喜欢尝鲜的人^_^

安装logbook

在终端输入pip3 install logbook并回车。

分类

日志模块属于pity的工具类,笔者将之划分到app/utils下。

编写日志类

import logbook

from app import pity

class Log(object):
    handler = None

    def __init__(self, name='pity', filename=pity.config['LOG_NAME']):  # Logger标识默认为app
        """
        :param name: 业务名称
        :param filename: 文件名称
        """
        self.handler = logbook.FileHandler(filename, encoding='utf-8')
        self.logger = logbook.Logger(name)
        self.handler.push_application()

    def info(self, *args, **kwargs):
        return self.logger.info(*args, **kwargs)

    def error(self, *args, **kwargs):
        return self.logger.error(*args, **kwargs)

    def warning(self, *args, **kwargs):
        return self.logger.warning(*args, **kwargs)

    def debug(self, *args, **kwargs):
        return self.logger.debug(*args, **kwargs)

在这里,我们定义了一个「Log」类,这个类接受的name是日志的分类,如果不传入则默认为「pity」,filename(日志文件名)默认值为引入config.py中配置的「LOG_NAME」

然后将logbook中的handler设为写入的文件,并将info/error/warning/debug等常用方法封装在Log类中。

修改run.py

from server.app import app
from server.app.utils.logger import Log

@app.route('/')
def hello_world():
    log = Log("hello world专用")
    log.info("有人访问你的网站了")
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

运行run.py

进入浏览器输入http://localhost:5000


报错截图

发现居然报错了,我们仔细查看下控制台:


控制台报错信息

看提示是「没有找到对应的文件或目录」, 原来我们的pity目录下没有「logs」目录, 而这种日志库一般也不会帮忙创建目录,所以我们暂时手动在pity目录下建立logs目录即可。

建立以后重启服务, 「再次尝试」


成功截图

查看logs/pity.log文件

可以看到,日志文件配置生效,妈妈再也不用担心我意外出错了。


将日志类改为单例模式(选修课)

  • 编辑utils/decorator.py
'''
    这是一个装饰器方法文件
'''

class SingletonDecorator:
    def __init__(self, cls):
        self.cls = cls
        self.instance = None

    def __call__(self, *args, **kwds):
        if self.instance is None:
            self.instance = self.cls(*args, **kwds)
        return self.instance

如图所示,这是一个单例类的装饰器。首先判断该类的实例是否是None,为None的话则生成新实例,否则返回该实例。这样就确保了只生成一次实例。

当然这只是一个办法,可能在多线程的情况下会出问题。后续的优化和了解,就交给同学们自己了。

  • 给Log类加上装饰器
import logbook

from app import pity
from .decorator import SingletonDecorator

# 注意这里
@SingletonDecorator
class Log(object):
    handler = None

    def __init__(self, name='pity', filename=pity.config['LOG_NAME']):  # Logger标识默认为app
        """
        :param name: 业务名称
        :param filename: 文件名称
        """
        self.handler = logbook.FileHandler(filename, encoding='utf-8')
        self.logger = logbook.Logger(name)
        self.handler.push_application()

    def info(self, *args, **kwargs):
        return self.logger.info(*args, **kwargs)

    def error(self, *args, **kwargs):
        return self.logger.error(*args, **kwargs)

    def warning(self, *args, **kwargs):
        return self.logger.warning(*args, **kwargs)

    def debug(self, *args, **kwargs):
        return self.logger.debug(*args, **kwargs)

作业

发现一个小问题,日志的时间似乎不对,可能是哪里出了问题呢?

全部代码地址: https://github.com/wuranxu/pity

「觉得有用的话可以帮忙点个Star哦QAQ」

测试平台系列(3) 给Hello World添加日志的更多相关文章

  1. 测试平台系列(85) 把redis运用到实战中

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们让支持了前置条件 ...

  2. 测试平台系列(2) 给Pity添加配置

    给Pity添加配置 回顾 还记得上篇文章创立的「Flask」实例吗?我们通过这个实例,给根路由 「/」 绑定了一个方法,从而使得用户访问不同路由的时候可以执行不同的方法. 配置 要知道,在一个「Web ...

  3. 测试平台系列(71) Python定时任务方案

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 定时任务 定时任务,顾名思义: ...

  4. 测试平台系列(72) 了解ApScheduler基本用法

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们调研了一下市面上 ...

  5. 测试平台系列(79) 编写Redis配置功能(下)

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们提出了优化Dao ...

  6. 测试平台系列(90) 编写oss客户端

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们编写了在线执行测试 ...

  7. 测试平台系列(92) 让http请求支持文件上传

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节呢,我们编写了oss的 ...

  8. 测试平台系列(55) 引入AceEditor(代码编辑器)

    大家好,我是米洛,求三连!求关注测试开发坑货! 回顾 我们上一节已经写好了左侧数据表目录,今天继续完成sql编辑器的部分. 调研组件 monaco 因为我们的项目用的是React,市面上很多编辑器都是 ...

  9. 测试平台系列(80) 封装Redis客户端

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们编写了Redis ...

随机推荐

  1. Linux系统编程【3.1】——编写ls命令

    ls命令简介 老规矩,直接在终端输入:man ls (有关于man命令的简介可以参考笔者前期博客:Linux系统编程[1]--编写more命令) 可以看到,ls命令的作用是显示目录中的文件名,它带有可 ...

  2. WSL2 Ubuntu apt-get update失败

    情况: 这个问题在github上也有讨论:https://github.com/microsoft/WSL/issues/4342 不过经过我的尝试,是DNS问题,这是默认的配置: 这个配置来自win ...

  3. 【非原创】codeforces 1025D - Recovering BST【区间dp+二叉搜索树】

    题目:戳这里 题意:给一个不下降序列,有n个数.问能否构造一个二叉搜索树,满足父亲和儿子之间的gcd>1. 解题思路:其实这题就是构造个二叉搜索树,只不过多了个条件.主要得了解二叉搜索树的性质, ...

  4. linux repo init 遇到的问题

    问题描述: 利用repo从远程服务器上取代码时候,出现错误  fatal: cannot make .repo directory:Permission denied, 加了sudo 之后,还是不行, ...

  5. SDN总结

    之前做项目用到了SDN,知道其作用,但是对其不是特别熟悉,今天特来总结一下相关知识点: 1. SDN的典型架构分为哪三层 主要分为应用层,控制层,和基础设施层: 2. SDN技术的关键点是 控制平面和 ...

  6. codeforces 758D

    D. Ability To Convert time limit per test 1 second memory limit per test 256 megabytes input standar ...

  7. MobX All In One

    MobX All In One Simple, scalable state management. https://mobx.js.org/README.html https://github.co ...

  8. LeetCode & Binary Search 解题模版

    LeetCode & Binary Search 解题模版 In computer science, binary search, also known as half-interval se ...

  9. macOS open url from terminal

    macOS open url from terminal open URL && start terminal bash open url in chrome open chrome ...

  10. c++ 动态解析PE导出表

    测试环境是x86 main #include <iostream> #include <Windows.h> #include <TlHelp32.h> #incl ...