Skip to content

Commit

Permalink
Merge pull request #646 from nationalarchives/AYR-1297/audit-app-logs
Browse files Browse the repository at this point in the history
Ayr 1297/audit app logs
  • Loading branch information
colinbowen authored Nov 28, 2024
2 parents 4ccb394 + f2e1c35 commit 5c07ba8
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 18 deletions.
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -599,20 +599,31 @@ This config includes:
`setup_logging` is called during the initialization of the Flask app.
### Usage
We use two loggers in this application:
We can utilise the Flask logger by accessing Flask's `app.logger`. Since we define our routes with blueprints rather than the app directly, we can call access app through
- app_logger for application-related logs
- audit_logger for audit-specific logs
Both are attached to the Flask app instance for easy access across the app. Since we define routes using blueprints instead of directly on the app, we access these loggers through Flask’s current_app.
To use these loggers in your code, import current_app from Flask:
```python
from flask import current_app
```
for example:
Then, call the appropriate logger as follows:
```python
current_app.logger.info('Some info message')
current_app.logger.debug('Some debug message')
current_app.logger.warning('Some warning message')
current_app.logger.error('Some error message')
current_app.app_logger.info('Some info message')
current_app.app_logger.debug('Some debug message')
current_app.app_logger.warning('Some warning message')
current_app.app_logger.error('Some error message')
current_app.audit_logger.info('Some info message')
current_app.audit_logger.debug('Some debug message')
current_app.audit_logger.warning('Some warning message')
current_app.audit_logger.error('Some error message')
```
### Output
Expand Down
27 changes: 22 additions & 5 deletions app/logger_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging

from flask import has_request_context, request
from flask.logging import default_handler


class RequestFormatter(logging.Formatter):
Expand All @@ -12,15 +11,33 @@ def format(self, record):
else:
record.url = None
record.remote_addr = None

return super().format(record)


def setup_logger(name, level, formatter):
"""Helper function to set up a logger."""
logger = logging.getLogger(name)
logger.setLevel(level)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger


def setup_logging(app):
formatter = RequestFormatter(
"""Set up loggers for the app."""
audit_log_formatter = RequestFormatter(
"AUDIT_LOG\n"
"[%(asctime)s] %(remote_addr)s requested %(url)s\n"
"%(levelname)s in %(module)s: %(message)s"
)
default_handler.setFormatter(formatter)
app.audit_logger = setup_logger(
"audit_logger", logging.INFO, audit_log_formatter
)

app.logger.setLevel(logging.INFO)
app_log_formatter = RequestFormatter(
"APP_LOG\n"
"[%(asctime)s] %(remote_addr)s requested %(url)s\n"
"%(levelname)s in %(module)s: %(message)s"
)
app.app_logger = setup_logger("app_logger", logging.INFO, app_log_formatter)
8 changes: 4 additions & 4 deletions app/main/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ def record(record_id: uuid.UUID):
try:
presigned_url = create_presigned_url(file)
except Exception as e:
current_app.logger.info(
current_app.app_logger.info(
f"Failed to create presigned url for document render non-javascript fallback {e}"
)

Expand Down Expand Up @@ -732,7 +732,7 @@ def download_record(record_id: uuid.UUID):
try:
s3_file_object = s3.get_object(Bucket=bucket, Key=key)
except Exception as e:
current_app.logger.error(f"Failed to get object from S3: {e}")
current_app.app_logger.error(f"Failed to get object from S3: {e}")
abort(404)

download_filename = file.FileName
Expand All @@ -747,7 +747,7 @@ def download_record(record_id: uuid.UUID):
file_content = s3_file_object["Body"].read()
file_type = download_filename.split(".")[-1].lower()
except Exception as e:
current_app.logger.error(f"Error reading S3 file content: {e}")
current_app.app_logger.error(f"Error reading S3 file content: {e}")
abort(500)

content_type = s3_file_object.get("ContentType", "application/octet-stream")
Expand All @@ -766,7 +766,7 @@ def download_record(record_id: uuid.UUID):
as_attachment=True,
download_name=download_filename,
)
current_app.logger.info(
current_app.audit_logger.info(
json.dumps({"user_id": session["user_id"], "file": key})
)
return response
Expand Down
6 changes: 3 additions & 3 deletions app/main/util/render_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def get_download_filename(file):
def create_presigned_url(file):
file_extension = file.FileName.split(".")[-1].lower()
if file_extension not in current_app.config["SUPPORTED_RENDER_EXTENSIONS"]:
current_app.logger.warning(
current_app.app_logger.warning(
f"Rendering file format '{file_extension}' is not currently supported by AYR."
)
return None
Expand Down Expand Up @@ -88,7 +88,7 @@ def generate_pdf_manifest(record_id):
try:
presigned_url = create_presigned_url(file)
except Exception as e:
current_app.logger.info(
current_app.app_logger.info(
f"Failed to create presigned url for document render non-javascript fallback {e}"
)

Expand Down Expand Up @@ -166,7 +166,7 @@ def generate_image_manifest(s3_file_object, record_id):
try:
presigned_url = create_presigned_url(file)
except Exception as e:
current_app.logger.info(
current_app.app_logger.info(
f"Failed to create presigned url for document render non-javascript fallback {e}"
)

Expand Down

0 comments on commit 5c07ba8

Please sign in to comment.