feat: add debug log for request and response (#19781) -- reformatted based on comment (thanks to @QuantumGhost)

pull/19783/head
hashjang 1 year ago
parent 457149dfac
commit b0051dce39

@ -54,6 +54,7 @@ def initialize_extensions(app: DifyApp):
ext_otel, ext_otel,
ext_proxy_fix, ext_proxy_fix,
ext_redis, ext_redis,
ext_request_logging,
ext_sentry, ext_sentry,
ext_set_secretkey, ext_set_secretkey,
ext_storage, ext_storage,
@ -83,6 +84,7 @@ def initialize_extensions(app: DifyApp):
ext_blueprints, ext_blueprints,
ext_commands, ext_commands,
ext_otel, ext_otel,
ext_request_logging,
] ]
for ext in extensions: for ext in extensions:
short_name = ext.__name__.split(".")[-1] short_name = ext.__name__.split(".")[-1]

@ -17,6 +17,12 @@ class DeploymentConfig(BaseSettings):
default=False, default=False,
) )
# Request logging configuration
ENABLE_REQUEST_LOGGING: bool = Field(
description="Enable request and response body logging",
default=False,
)
EDITION: str = Field( EDITION: str = Field(
description="Deployment edition of the application (e.g., 'SELF_HOSTED', 'CLOUD')", description="Deployment edition of the application (e.g., 'SELF_HOSTED', 'CLOUD')",
default="SELF_HOSTED", default="SELF_HOSTED",

@ -1,4 +1,3 @@
import json
import logging import logging
import os import os
import sys import sys
@ -61,49 +60,6 @@ def init_app(app: DifyApp):
if handler.formatter: if handler.formatter:
handler.formatter.converter = time_converter handler.formatter.converter = time_converter
# for debugging purposes, log the request context
@app.before_request
def log_request():
# only log if DEBUG is enabled
if logging.getLogger().isEnabledFor(logging.DEBUG):
content_type = flask.request.content_type
# only log body if the request is JSON
if flask.request.data and "application/json" in content_type.lower():
try:
json_data = json.loads(flask.request.data)
formatted_json = json.dumps(json_data, ensure_ascii=False, indent=2)
logging.debug(
"Received Request %s -> %s, Request Body:\n%s",
flask.request.method,
flask.request.path,
formatted_json,
)
except Exception:
logging.exception("Failed to parse JSON request")
else:
logging.debug("Received Request %s -> %s", flask.request.method, flask.request.path)
# for debugging purposes, log the response
@app.after_request
def log_response(response):
# only log if DEBUG is enabled
if logging.getLogger().isEnabledFor(logging.DEBUG):
# only log body if the response is JSON
if response.content_type and "application/json" in response.content_type.lower():
try:
response_data = response.get_data(as_text=True)
json_data = json.loads(response_data)
formatted_json = json.dumps(json_data, ensure_ascii=False, indent=2)
logging.debug(
"Response %s %s, Response Body:\n%s", response.status, response.content_type, formatted_json
)
except Exception:
logging.exception("Failed to parse JSON response")
else:
logging.debug("Response %s %s", response.status, response.content_type)
return response
def get_request_id(): def get_request_id():
if getattr(flask.g, "request_id", None): if getattr(flask.g, "request_id", None):

@ -0,0 +1,61 @@
import json
import logging
import flask
from flask import Flask
from flask.signals import request_finished, request_started
from configs import dify_config
logger = logging.getLogger(__name__)
def init_app(app: Flask):
"""Initialize the request logging extension."""
if not dify_config.ENABLE_REQUEST_LOGGING:
return
@request_started.connect_via(app)
def log_request_started(sender, **extra):
"""Log the start of a request."""
if not logger.isEnabledFor(logging.DEBUG):
return
request = flask.request
content_type = request.content_type
if request.data and "application/json" in content_type.lower():
try:
json_data = json.loads(request.data)
formatted_json = json.dumps(json_data, ensure_ascii=False, indent=2)
logger.debug(
"Received Request %s -> %s, Request Body:\n%s",
request.method,
request.path,
formatted_json,
)
except Exception:
logger.exception("Failed to parse JSON request")
else:
logger.debug("Received Request %s -> %s", request.method, request.path)
@request_finished.connect_via(app)
def log_request_finished(sender, response, **extra):
"""Log the end of a request."""
if not logger.isEnabledFor(logging.DEBUG) or response is None:
return
if response.content_type and "application/json" in response.content_type.lower():
try:
response_data = response.get_data(as_text=True)
json_data = json.loads(response_data)
formatted_json = json.dumps(json_data, ensure_ascii=False, indent=2)
logger.debug(
"Response %s %s, Response Body:\n%s",
response.status,
response.content_type,
formatted_json,
)
except Exception:
logger.exception("Failed to parse JSON response")
else:
logger.debug("Response %s %s", response.status, response.content_type)
Loading…
Cancel
Save