Add log to Hello World

review

We’ve done our first interface with Flask from the previous post. As you can see, writing interfaces in Flask is pretty straightforward. So let’s enrich the example above.

demand

Now the demand comes, in our usual development process, always encounter some problems. But it is not necessary, so we can use some means to write log, to find the problem. An obvious example is try/exception, where unknown problems can be logged and addressed after the fact.


Selection of log module

logging

As we know, Python has built-in functionality and a powerful logging module for us to use, and I won’t say much about its power. There are many online demo, a little copy of a log class can be used.

logbook

Here I used the LogBook library on Github, which is more convenient than logging when looking at API calls alone. Maybe it’s because I’m a taste taker

Install the logbook

On the terminal, type pip3 install logbook and press Enter.

classification

The logging module belongs to the tool class of pity, which is classified under app/utils.

Writing the logging class

import logbook

from app import pity


class Log(object) :
    handler = None

    def __init__(self, name='pity', filename=pity.config['LOG_NAME']) :  The default Logger identifier is app
        "" :param name: service name: param filename: 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)


Copy the code

Here, we define a Log class that accepts the name as the Log class. If not passed in, it defaults to ** “pity” **, and filename(the Log filename) defaults to the LOG_NAME configured in the import config.py.

Then set the handler in logBook as the file to write, and encapsulate common methods such as info/error/warning/debug in the Log class.

Modify the run. Py

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

@app.route('/')
def hello_world() :
    log = Log("Hello World only")
    log.info("Someone visited your website.")
    return 'Hello World! '


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


Copy the code

Run run. Py

Go to your browser and enter http://localhost:5000

An error screenshot

We found an error, so we took a closer look at the console:

The console reported an error message

Log directory: log directory: log directory: log directory: log directory: log directory: log directory: log directory: log directory: log directory: log directory

After establishment, restart the service and try again.

Successful screenshots

Check the logs/pity. Log file

As you can see, the log file configuration takes effect, and mom no longer has to worry about me accidentally making mistakes.


Change the log class to singleton mode (elective)

  • Edit 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.instanceCopy the code

As you can see, this is a decorator for a singleton class. First determine if the class instance is None. If None, a new instance is generated, otherwise the instance is returned. This ensures that the instance is generated only once.

Of course, this is only one solution, and it may not work in multi-threaded situations. The follow-up optimization and understanding will be left to the students themselves.

  • Add a decorator to the Log class
Import logBook from app import pity from. Decorator import SingletonDecorator # Log(object): handler = None def __init__(self, name='pity', filename=pity.config['LOG_NAME']): """ :param name: service 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)Copy the code

homework

Found a small problem, the log time seems to be wrong, may be something wrong?

All code address: github.com/wuranxu/pit…

“If you think it’s useful, you can help to order a Star oh QAQ.”

This article uses the Article Synchronization Assistant to synchronize