天天看點

flask logging 最佳實踐

flask項目中, 你可以使用python 的 logging子產品實作記錄日志. 也可以使用 flask 基于logging子產品封裝過的app.logger實作.

直接上代碼

config.py

import os

import logging

basedir = os.path.abspath(os.path.dirname(__file__))

class InfoFilter(logging.Filter):

def filter(self, record):

"""only use INFO

篩選, 隻需要 INFO 級别的log

:param record:

:return:

"""

if logging.INFO <= record.levelno < logging.ERROR:

# 已經是INFO級别了

# 然後利用父類, 傳回 1

return super().filter(record)

else:

return 0

class Config:

SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'

SSL_DISABLE = False

SQLALCHEMY_RECORD_QUERIES = True

LOG_PATH = os.path.join(basedir, 'logs')

LOG_PATH_ERROR = os.path.join(LOG_PATH, 'error.log')

LOG_PATH_INFO = os.path.join(LOG_PATH, 'info.log')

LOG_FILE_MAX_BYTES = 100 * 1024 * 1024

# 輪轉數量是 10 個

LOG_FILE_BACKUP_COUNT = 10

@staticmethod

def init_app(app):

pass

class DevelopmentConfig(Config):

DEBUG = True

PRESERVE_CONTEXT_ON_EXCEPTION = False

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://xxx:[email protected]/xxx?charset=utf8'

@classmethod

def init_app(cls, app):

Config.init_app(app)

# email errors to the administrators

from logging.handlers import RotatingFileHandler

# Formatter

formatter = logging.Formatter(

'%(asctime)s %(levelname)s %(process)d %(thread)d '

'%(pathname)s %(lineno)s %(message)s')

# FileHandler Info

file_handler_info = RotatingFileHandler(filename=cls.LOG_PATH_INFO)

file_handler_info.setFormatter(formatter)

file_handler_info.setLevel(logging.INFO)

info_filter = InfoFilter()

file_handler_info.addFilter(info_filter)

app.logger.addHandler(file_handler_info)

# FileHandler Error

file_handler_error = RotatingFileHandler(filename=cls.LOG_PATH_ERROR)

file_handler_error.setFormatter(formatter)

file_handler_error.setLevel(logging.ERROR)

app.logger.addHandler(file_handler_error)

class TestingConfig(Config):

TESTING = True

SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \

'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')

WTF_CSRF_ENABLED = False

config = {

'development': DevelopmentConfig,

'testing': TestingConfig,

'default': DevelopmentConfig

}

app.py

from config import config

def create_app(config_name):

app = Flask(__name__)

app.json_encoder = AlchemyEncoder

app.config.from_object(config[config_name])

config[config_name].init_app(app)

return app

然後你就可以在其他任何一個子產品記錄log

from flask import current_app

try:

s = int('ss')

except ValueError as e:

current_app.logger.exception(e)

error.log

2018-07-02 21:44:12,976 ERROR 4848 139663008261888 /home/.../xxx.py 33 invalid literal for int() with base 10: 'ss'

Traceback (most recent call last):

File "/home/.../xxx.py", line 31, in show_product_manage

ValueError: invalid literal for int() with base 10: 'ss'

---------------------