代码
视图代码
access_logger = logging. getLogger( "access" )
@blueprint. route ( "/v1/hello" , methods= [ 'POST' ] )
def demo_api ( ) :
save_data( data)
access_logger. info(
f"start: { time_start} , end: { time_end} , elapsed: { time_start - time_end} " ,
)
return ret
app初始化代码
import logging
import time
import os
from init_app import init
from db import db
from utils. logger. logger import init_logger
from utils. middlewares import error_handle
app = Flask( __name__)
def app_init ( app_obj) :
init_logger( app)
app. register_error_handler( Exception, error_handle)
init( app_obj)
db. init_app( app_obj)
util目录__init__代码
"""日志"""
__all__ = [ "init_logger" ]
from utils. logger. logger import init_logger
util目录日志filter,可以为日志添加属性
"""自定义日志Filter"""
import logging
from flask import has_request_context, request
class AccessFilter ( logging. Filter) :
"""从request中提取额外的格式化参数"""
def filter ( self, record: logging. LogRecord) - > bool :
"""提取请求url和真实ip"""
if has_request_context( ) :
record. real_ip = request. headers. get( "X_REAL_IP" , request. remote_addr)
record. content_length = f" { request. headers. get( 'Content-Length' , 0 , type = int ) / 1024 } KB"
data = request. form. to_dict( )
else :
if not hasattr ( record, "real_ip" ) :
record. real_ip = "UnknownIP"
return True
util目录日志初始化函数
from logging. config import dictConfig
from pathlib import Path
from flask import Flask
from utils. logger. filter import AccessFilter
def init_logger ( app: Flask) :
"""初始化自定义日志"""
file_base_path = Path( app. root_path) / "logs"
dictConfig(
{
"version" : 1 ,
"formatters" : {
"default" : {
"format" : "{asctime} {filename}[line:{lineno:d}] {levelname} {message}" ,
"datefmt" : "%Y-%m-%d %H:%M:%S" ,
"style" : "{" ,
} ,
"access" : {
"format" : "{asctime} {levelname} {real_ip} {access_key_id} {user_id} [TagCode:{tag}] {content_length} {message}" ,
"datefmt" : "%Y-%m-%d %H:%M:%S" ,
"style" : "{" ,
}
} ,
"filters" : {
"access" : { "()" : AccessFilter} ,
} ,
"handlers" : {
"console" : {
"class" : "logging.StreamHandler" ,
"level" : "DEBUG" if app. config[ "DEBUG" ] else "INFO" ,
"formatter" : "default" ,
} ,
"file" : {
"class" : "logging.handlers.TimedRotatingFileHandler" ,
"level" : "INFO" ,
"formatter" : "default" ,
"filename" : file_base_path / "app.log" ,
"when" : "MIDNIGHT" ,
"backupCount" : "30" ,
} ,
"error" : {
"class" : "logging.handlers.TimedRotatingFileHandler" ,
"level" : "ERROR" ,
"formatter" : "default" ,
"filename" : file_base_path / "error.log" ,
"when" : "MIDNIGHT" ,
} ,
"access" : {
"class" : "logging.handlers.TimedRotatingFileHandler" ,
"level" : "DEBUG" if app. config[ "DEBUG" ] else "INFO" ,
"formatter" : "access" ,
"filters" : [ "access" ] ,
"filename" : file_base_path / "access.log" ,
"when" : "MIDNIGHT" ,
} ,
} ,
"loggers" : {
"access" : {
"level" : "DEBUG" if app. config[ "DEBUG" ] else "INFO" ,
"propagate" : False ,
"handlers" : [ "access" ] ,
} ,
} ,
"root" : {
"level" : "DEBUG" if app. config[ "DEBUG" ] else "INFO" ,
"handlers" : [ "console" , "file" , "error" ] ,
} ,
}
)