You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ext_logging.py 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import logging
  2. import os
  3. import sys
  4. import uuid
  5. from logging.handlers import RotatingFileHandler
  6. import flask
  7. from configs import dify_config
  8. from dify_app import DifyApp
  9. def init_app(app: DifyApp):
  10. log_handlers: list[logging.Handler] = []
  11. log_file = dify_config.LOG_FILE
  12. if log_file:
  13. log_dir = os.path.dirname(log_file)
  14. os.makedirs(log_dir, exist_ok=True)
  15. log_handlers.append(
  16. RotatingFileHandler(
  17. filename=log_file,
  18. maxBytes=dify_config.LOG_FILE_MAX_SIZE * 1024 * 1024,
  19. backupCount=dify_config.LOG_FILE_BACKUP_COUNT,
  20. )
  21. )
  22. # Always add StreamHandler to log to console
  23. sh = logging.StreamHandler(sys.stdout)
  24. log_handlers.append(sh)
  25. # Apply RequestIdFilter to all handlers
  26. for handler in log_handlers:
  27. handler.addFilter(RequestIdFilter())
  28. logging.basicConfig(
  29. level=dify_config.LOG_LEVEL,
  30. format=dify_config.LOG_FORMAT,
  31. datefmt=dify_config.LOG_DATEFORMAT,
  32. handlers=log_handlers,
  33. force=True,
  34. )
  35. # Apply RequestIdFormatter to all handlers
  36. apply_request_id_formatter()
  37. # Disable propagation for noisy loggers to avoid duplicate logs
  38. logging.getLogger("sqlalchemy.engine").propagate = False
  39. log_tz = dify_config.LOG_TZ
  40. if log_tz:
  41. from datetime import datetime
  42. import pytz
  43. timezone = pytz.timezone(log_tz)
  44. def time_converter(seconds):
  45. return datetime.fromtimestamp(seconds, tz=timezone).timetuple()
  46. for handler in logging.root.handlers:
  47. if handler.formatter:
  48. handler.formatter.converter = time_converter
  49. def get_request_id():
  50. if getattr(flask.g, "request_id", None):
  51. return flask.g.request_id
  52. new_uuid = uuid.uuid4().hex[:10]
  53. flask.g.request_id = new_uuid
  54. return new_uuid
  55. class RequestIdFilter(logging.Filter):
  56. # This is a logging filter that makes the request ID available for use in
  57. # the logging format. Note that we're checking if we're in a request
  58. # context, as we may want to log things before Flask is fully loaded.
  59. def filter(self, record):
  60. record.req_id = get_request_id() if flask.has_request_context() else ""
  61. return True
  62. class RequestIdFormatter(logging.Formatter):
  63. def format(self, record):
  64. if not hasattr(record, "req_id"):
  65. record.req_id = ""
  66. return super().format(record)
  67. def apply_request_id_formatter():
  68. for handler in logging.root.handlers:
  69. if handler.formatter:
  70. handler.formatter = RequestIdFormatter(dify_config.LOG_FORMAT, dify_config.LOG_DATEFORMAT)