Ubuntu服务器中Python Flask API请求日志记录实现方案咨询
Hey there! Let's get your Flask API logging working properly. Your current code only creates a timestamped file when you start the app, but it doesn't log any actual request details or trigger on each API hit. Here's how to fix this and meet your requirements:
If you want a separate log file for every API request (matching your exact filename format), use Flask's request hooks to trigger logging on each request, and properly format the timestamp for the filename.
from flask import Flask, request, jsonify from datetime import datetime app = Flask(__name__) def log_request_details(): # Generate the timestamped filename using your desired format current_time = datetime.now() timestamp = current_time.strftime("%H_%M_%S_%d_%m_%Y") log_filename = f"MY_Log_File__{timestamp}.txt" # Collect all relevant request details request_log = f"""Request Time: {current_time.strftime("%Y-%m-%d %H:%M:%S")} Client IP Address: {request.remote_addr} Request Method: {request.method} Request Path: {request.path} Request Headers: {dict(request.headers)} Request Body: {request.get_data(as_text=True)}""" # Write the log to the new file (use 'w' to create a new file each time) with open(log_filename, "w", encoding="utf-8") as log_file: log_file.write(request_log) # Use Flask's after_request hook to run logging after every request @app.after_request def after_request(response): log_request_details() return response # Example API route to test with @app.route('/api/hello', methods=['GET', 'POST']) def hello_api(): return jsonify({"message": "Hello from your logged API!"}) if __name__ == '__main__': # Run the app on all interfaces (for Ubuntu server access) app.run(host='0.0.0.0', port=5000)
Key Notes for This Solution:
- The
after_requesthook ensures logging runs after every successful request. If you need to log failed requests (like unhandled exceptions), add ateardown_requesthook too. - The timestamp is properly formatted using
strftime()to replace those%H/%Mplaceholders with actual time values. - We capture useful details like client IP, request method, headers, and body to make the logs actionable.
Creating a new file for every request can lead to hundreds/thousands of files over time. For Ubuntu production environments, use Python's logging module with rotating logs to keep things organized while still matching your filename pattern.
from flask import Flask, request, jsonify import logging from logging.handlers import TimedRotatingFileHandler from datetime import datetime app = Flask(__name__) def setup_logging(): # Define the log format with all request details log_format = "%(asctime)s | %(remote_addr)s | %(request_method)s | %(request_path)s | %(status_code)s | %(message)s" formatter = logging.Formatter(log_format) # Create a rotating handler that makes a new file at your desired interval handler = TimedRotatingFileHandler( baseFilename="MY_Log_File", when='H', # Rotate every hour (use 'D' for daily) interval=1, backupCount=24, # Keep the last 24 hours of logs encoding='utf-8' ) # Set the filename suffix to match your exact format handler.suffix = "%H_%M_%S_%d_%m_%Y.txt" handler.setFormatter(formatter) # Add the handler to Flask's logger app.logger.addHandler(handler) app.logger.setLevel(logging.INFO) # Custom filter to inject request data into log records class RequestDataFilter(logging.Filter): def filter(self, record): record.remote_addr = request.remote_addr record.request_method = request.method record.request_path = request.path record.status_code = getattr(request, 'status_code', 200) return True # Initialize logging and add the filter setup_logging() app.logger.addFilter(RequestDataFilter()) # Log request details after each request @app.after_request def after_request(response): request.status_code = response.status_code app.logger.info(f"Request Body: {request.get_data(as_text=True)}") return response # Example API route @app.route('/api/test', methods=['GET', 'POST']) def test_api(): return jsonify({"message": "Production-ready logged API!"}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
Why This Is Better for Production:
- Automatically rotates logs (no manual cleanup needed)
- Uses Flask's built-in logging system which is more efficient than manual file writes
- Keeps log files organized while still adhering to your naming convention
- Log Directory Permissions: If you want to store logs in a dedicated directory (like
/var/log/flask_api/), create it first and set proper permissions:
Then update the log filename path in your code to point to this directory.sudo mkdir /var/log/flask_api sudo chown your_username:your_username /var/log/flask_api - Use a WSGI Server: For production, don't use Flask's built-in
app.run(). Use Gunicorn or uWSGI instead:# Install Gunicorn pip install gunicorn # Run the app with 4 worker processes gunicorn -w 4 -b 0.0.0.0:5000 app:app - Background Execution: Use
systemdto run your API as a background service so logs keep recording even if you log out of the server.
内容的提问来源于stack exchange,提问作者Sharvaa

