import os import logging from logging.handlers import RotatingFileHandler from flask import request, session class RequestFormatter(logging.Formatter): """ Custom formatter to safely inject request data """ def format(self, record): record.user = getattr(record, "user", "Anonymous") record.ip = getattr(record, "ip", "N/A") record.method = getattr(record, "method", "N/A") record.url = getattr(record, "url", "N/A") return super().format(record) class LoggerService: @staticmethod def init_app(app): # Create logs folder if not exists if not os.path.exists("logs"): os.makedirs("logs") formatter = RequestFormatter( "%(asctime)s | %(levelname)s | " "User:%(user)s | IP:%(ip)s | " "Method:%(method)s | URL:%(url)s | " "%(message)s" ) # 🔹 INFO LOG info_handler = RotatingFileHandler( "logs/app.log", maxBytes=5 * 1024 * 1024, backupCount=5 ) info_handler.setLevel(logging.INFO) info_handler.setFormatter(formatter) # 🔹 ERROR LOG error_handler = RotatingFileHandler( "logs/error.log", maxBytes=5 * 1024 * 1024, backupCount=5 ) error_handler.setLevel(logging.ERROR) error_handler.setFormatter(formatter) # 🔹 CONSOLE LOG console_handler = logging.StreamHandler() console_handler.setLevel(logging.DEBUG) console_handler.setFormatter(formatter) app.logger.setLevel(logging.DEBUG) app.logger.addHandler(info_handler) app.logger.addHandler(error_handler) app.logger.addHandler(console_handler) # Auto request logging @app.before_request def log_request(): app.logger.info( "Request Started", extra=LoggerService.get_request_data() ) @staticmethod def get_request_data(): try: return { "user": session.get("user_email", "Anonymous"), "ip": request.remote_addr, "method": request.method, "url": request.url } except: return {}