2024-10-22 09:00:44 +08:00
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import sys
|
2024-12-15 12:22:25 +03:00
|
|
|
import uuid
|
2024-10-22 09:00:44 +08:00
|
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
|
2024-12-15 12:22:25 +03:00
|
|
|
import flask
|
|
|
|
|
2024-10-22 11:01:32 +08:00
|
|
|
from configs import dify_config
|
2024-11-30 23:05:22 +08:00
|
|
|
from dify_app import DifyApp
|
2024-10-22 11:01:32 +08:00
|
|
|
|
2024-10-22 09:00:44 +08:00
|
|
|
|
2024-11-30 23:05:22 +08:00
|
|
|
def init_app(app: DifyApp):
|
2024-12-24 18:38:51 +08:00
|
|
|
log_handlers: list[logging.Handler] = []
|
2024-10-22 11:01:32 +08:00
|
|
|
log_file = dify_config.LOG_FILE
|
2024-10-22 09:00:44 +08:00
|
|
|
if log_file:
|
|
|
|
log_dir = os.path.dirname(log_file)
|
|
|
|
os.makedirs(log_dir, exist_ok=True)
|
2024-11-12 00:53:12 +09:00
|
|
|
log_handlers.append(
|
2024-10-22 09:00:44 +08:00
|
|
|
RotatingFileHandler(
|
|
|
|
filename=log_file,
|
2024-10-23 17:24:36 +08:00
|
|
|
maxBytes=dify_config.LOG_FILE_MAX_SIZE * 1024 * 1024,
|
|
|
|
backupCount=dify_config.LOG_FILE_BACKUP_COUNT,
|
2024-11-12 00:53:12 +09:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Always add StreamHandler to log to console
|
2024-12-15 12:22:25 +03:00
|
|
|
sh = logging.StreamHandler(sys.stdout)
|
|
|
|
log_handlers.append(sh)
|
2024-10-22 09:00:44 +08:00
|
|
|
|
2025-04-18 09:42:38 +08:00
|
|
|
# Apply RequestIdFilter to all handlers
|
|
|
|
for handler in log_handlers:
|
|
|
|
handler.addFilter(RequestIdFilter())
|
|
|
|
|
2024-10-22 09:00:44 +08:00
|
|
|
logging.basicConfig(
|
2024-10-22 11:01:32 +08:00
|
|
|
level=dify_config.LOG_LEVEL,
|
2025-01-28 10:49:58 +08:00
|
|
|
format=dify_config.LOG_FORMAT,
|
2024-10-22 11:01:32 +08:00
|
|
|
datefmt=dify_config.LOG_DATEFORMAT,
|
2024-10-22 09:00:44 +08:00
|
|
|
handlers=log_handlers,
|
|
|
|
force=True,
|
|
|
|
)
|
2025-05-14 12:17:35 +08:00
|
|
|
|
|
|
|
# Apply RequestIdFormatter to all handlers
|
|
|
|
apply_request_id_formatter()
|
|
|
|
|
2025-04-14 21:28:31 +09:00
|
|
|
# Disable propagation for noisy loggers to avoid duplicate logs
|
|
|
|
logging.getLogger("sqlalchemy.engine").propagate = False
|
2024-10-22 11:01:32 +08:00
|
|
|
log_tz = dify_config.LOG_TZ
|
2024-10-22 09:00:44 +08:00
|
|
|
if log_tz:
|
2024-10-30 22:06:10 +08:00
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
import pytz
|
|
|
|
|
|
|
|
timezone = pytz.timezone(log_tz)
|
|
|
|
|
|
|
|
def time_converter(seconds):
|
2025-01-02 18:52:36 +08:00
|
|
|
return datetime.fromtimestamp(seconds, tz=timezone).timetuple()
|
2024-10-30 22:06:10 +08:00
|
|
|
|
2024-10-22 09:00:44 +08:00
|
|
|
for handler in logging.root.handlers:
|
2024-12-24 18:38:51 +08:00
|
|
|
if handler.formatter:
|
|
|
|
handler.formatter.converter = time_converter
|
2024-12-15 12:22:25 +03:00
|
|
|
|
|
|
|
|
|
|
|
def get_request_id():
|
|
|
|
if getattr(flask.g, "request_id", None):
|
|
|
|
return flask.g.request_id
|
|
|
|
|
|
|
|
new_uuid = uuid.uuid4().hex[:10]
|
|
|
|
flask.g.request_id = new_uuid
|
|
|
|
|
|
|
|
return new_uuid
|
|
|
|
|
|
|
|
|
|
|
|
class RequestIdFilter(logging.Filter):
|
|
|
|
# This is a logging filter that makes the request ID available for use in
|
|
|
|
# the logging format. Note that we're checking if we're in a request
|
|
|
|
# context, as we may want to log things before Flask is fully loaded.
|
|
|
|
def filter(self, record):
|
|
|
|
record.req_id = get_request_id() if flask.has_request_context() else ""
|
|
|
|
return True
|
2025-05-14 12:17:35 +08:00
|
|
|
|
|
|
|
|
|
|
|
class RequestIdFormatter(logging.Formatter):
|
|
|
|
def format(self, record):
|
|
|
|
if not hasattr(record, "req_id"):
|
|
|
|
record.req_id = ""
|
|
|
|
return super().format(record)
|
|
|
|
|
|
|
|
|
|
|
|
def apply_request_id_formatter():
|
|
|
|
for handler in logging.root.handlers:
|
|
|
|
if handler.formatter:
|
|
|
|
handler.formatter = RequestIdFormatter(dify_config.LOG_FORMAT, dify_config.LOG_DATEFORMAT)
|