|
|
import logging
|
|
|
import time
|
|
|
|
|
|
from ipware import get_client_ip
|
|
|
from user_agents import parse
|
|
|
|
|
|
from blog.documents import ELASTICSEARCH_ENABLED, ElaspedTimeDocumentManager
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
class OnlineMiddleware(object):
|
|
|
"""
|
|
|
mk:
|
|
|
在线用户中间件类,用于记录页面加载时间和用户访问信息
|
|
|
|
|
|
该中间件会在每个请求处理前后记录时间,计算页面渲染耗时,
|
|
|
并将相关信息存储到Elasticsearch中(如果启用的话)。
|
|
|
|
|
|
Args:
|
|
|
get_response: Django中间件的get_response回调函数
|
|
|
"""
|
|
|
def __init__(self, get_response=None):
|
|
|
self.get_response = get_response
|
|
|
super().__init__()
|
|
|
|
|
|
def __call__(self, request):
|
|
|
"""
|
|
|
mk:
|
|
|
中间件调用方法,处理请求并记录页面加载时间
|
|
|
|
|
|
记录请求开始时间,处理请求,计算耗时,并将相关信息存储到Elasticsearch。
|
|
|
同时替换响应内容中的加载时间占位符。
|
|
|
|
|
|
Args:
|
|
|
request: Django HttpRequest对象,包含当前请求信息
|
|
|
|
|
|
Returns:
|
|
|
HttpResponse: 处理后的HTTP响应对象
|
|
|
"""
|
|
|
''' page render time '''
|
|
|
start_time = time.time()
|
|
|
response = self.get_response(request)
|
|
|
http_user_agent = request.META.get('HTTP_USER_AGENT', '')
|
|
|
ip, _ = get_client_ip(request)
|
|
|
user_agent = parse(http_user_agent)
|
|
|
if not response.streaming:
|
|
|
try:
|
|
|
# mk:计算页面渲染耗时
|
|
|
cast_time = time.time() - start_time
|
|
|
if ELASTICSEARCH_ENABLED:
|
|
|
# mk:将耗时转换为毫秒并四舍五入到小数点后两位
|
|
|
time_taken = round((cast_time) * 1000, 2)
|
|
|
url = request.path
|
|
|
from django.utils import timezone
|
|
|
# mk:创建Elasticsearch文档记录
|
|
|
ElaspedTimeDocumentManager.create(
|
|
|
url=url,
|
|
|
time_taken=time_taken,
|
|
|
log_datetime=timezone.now(),
|
|
|
useragent=user_agent,
|
|
|
ip=ip)
|
|
|
# mk:替换响应内容中的加载时间占位符
|
|
|
response.content = response.content.replace(
|
|
|
b'<!!LOAD_TIMES!!>', str.encode(str(cast_time)[:5]))
|
|
|
except Exception as e:
|
|
|
logger.error("Error OnlineMiddleware: %s" % e)
|
|
|
|
|
|
return response |