Python Nginx

发布于 更新于

AI总结: 本文介绍了一个使用Flask框架的Python应用程序,该程序通过日志记录处理各种HTTP请求。应用程序配置了日志记录,以便将请求信息输出到控制台和文件中。请求的详细信息,包括请求方法、头部、查询参数和表单数据,会被记录下来。应用程序还使用PM2进行管理,并通过Nginx进行请求镜像,确保请求的所有头部信息得以保留。改进建议包括考虑添加对请求的JSON数据的处理,以及在日志记录中提供更多上下文信息以便于调试。

Python 3.6.8

app.py

import logging  
from flask import Flask, request  

app = Flask(__name__)  

logging.basicConfig(  
    level=logging.INFO,  
    format="%(asctime)s %(levelname)s %(message)s",  
    handlers=[  
        logging.StreamHandler(),  
        logging.FileHandler("app.log", encoding="utf-8")  
    ]  
)  

@app.route("/<path:path>", methods=["GET", "POST", "PUT", "DELETE"])  
def handle_request(path):  
    logging.info("---------------------------------------------")  

    try:  
        msg = "\n"  

        msg += f"{request.method} {request.headers['X-Forwarded-Proto']}://{request.headers['Host']}{request.headers['X-Mirror-Path']}" + "\n"  

        exclude_headers = {"Accept-Encoding", "Host", "Accept", "X-Mirror-Path", "Connection", "Content-Length", "X-Forwarded-Proto"}  
        filtered_headers = {k: v for k, v in request.headers.items() if k not in exclude_headers}  
        for k, v in filtered_headers.items():  
            msg += f"{k}: {v}" + "\n"  

        if request.args:  
            args_str = "&".join([f"{key}={value}" for key, value in request.args.items()])  
            msg += args_str  

        msg += "\n"  

        if request.form:  
            form_str = "&".join([f"{key}={value}" for key, value in request.form.items()])  
            msg += form_str  

        #if request.is_json:  
        #    msg += str(request.get_json())  
        #else:  
        #    msg += request.data.decode('utf-8')  

        # 尝试解析 JSON,force=True 表示忽略 Content-Type 也尝试解析  
        data = request.get_json(force=False, silent=True)  

        if data is not None:  
            msg += str(data)  
        else:  
            msg += request.get_data(as_text=True)  

        logging.info(msg)  
    except Exception as e:  
        logging.info(msg)  
        logging.error(e)  

    return "Request received and logged"  

if __name__ == "__main__":  
    app.run(host="0.0.0.0", port=9876, debug=True)  

pm2.json

{  
  "apps": [  
    {  
      "name": "mirrorlog",  
      "script": "python3 app.py",  
      "instances": 1,  
      "autorestart": true,  
      "watch": ["app.py"],  
      "log_date_format": "YYYY-MM-DD HH:mm Z",  
      "merge_logs": true,  
      "error_file": "pm2.log",  
      "out_file": "pm2.log"  
    }  
  ]  
}  
pm2 start pm2.json  

nginx

location / {  
    proxy_pass http://backend;  

    mirror /mirrorlog;  
    mirror_request_body on;  
}  

 # 定义镜像请求的处理路径  
location = /mirrorlog {  
    internal;  # 确保这个 location 只作为内部请求处理  
    proxy_pass http://127.0.0.1:9876;  # 代理请求到镜像后端  

    # 确保传递所有请求头  
    proxy_set_header Host $host;  # 保留原始请求中的 Host 头  
    proxy_set_header X-Real-IP $remote_addr;  # 保留客户端 IP  
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 保留原始的 X-Forwarded-For 头  
    proxy_set_header X-Forwarded-Proto $scheme;  # 保留请求协议(http 或 https)  
    proxy_set_header User-Agent $http_user_agent;  # 保留请求的 User-Agent 头  
    proxy_set_header Accept $http_accept;  # 保留请求的 Accept 头  
    proxy_set_header Content-Type $http_content_type;  # 保留请求的 Content-Type 头  

    proxy_set_header X-Mirror-Path $request_uri;  # 保留原始路径(包括查询参数)  
}