The SecureLogs Library provides logging functionality with Trace ID support and the ability to mask sensitive values in logs (such as credit card numbers, SSNs, tokens, etc.). It is designed for easy integration with FastAPI applications.
This guide will walk you through how to install, configure, and use the library to log trace information while hiding sensitive values.
- Installation
- Basic Setup
- Configuring Logger
- Using Sensitive Value Masking
- FastAPI Integration
- Example Output
- Configuration Options
- Conclusion
- Example Implementation
To install the SecureLogs Library, use pip
:
pip install SecureLogs
Once installed, you need to configure the logger and integrate it into your FastAPI project.
In your FastAPI application, import the necessary components from the library.
from uuid import UUID
from fastapi import Depends, FastAPI
from secure_logs import configure_logging, get_logger
from secure_logs import get_trace_id
from secure_logs.middleware import TraceIDMiddleware
You need to explicitly configure logging by calling configure_logging() with your preferred logging level (e.g., debug, info, etc.).
# Set up logging with the desired level
configure_logging(level="debug")
app = FastAPI()
app.add_middleware(TraceIDMiddleware)
The logger can be configured to mask sensitive values such as credit card numbers, tokens, and other confidential data. You can also define how many characters of the sensitive data should be shown after masking.
You can provide a list of regular expression patterns or strings that match sensitive data (e.g., credit card numbers, tokens).
Example patterns to mask:
Credit card numbers (\d{16})
SSNs ((?:\d{3}-\d{2}-\d{4}))
User-specific text (User)
Tokens ((?<=Bearer\s)[a-zA-Z0-9]+)
Use the get_logger()
function to initialize the logger and provide sensitive value patterns and the number of visible characters.
# Define patterns for sensitive data
sensitive_patterns = [
r"\d{16}", # Example: credit card numbers
r"(?:\d{3}-\d{2}-\d{4})", # Example: SSNs
"User", # Example: any text like 'User'
r"(?<=Bearer\s)[a-zA-Z0-9]+" # Example: token pattern
]
# Get the logger instance with sensitive patterns and show the last 2 characters
logger = get_logger(__name__, sensitive_patterns=sensitive_patterns, show_last=2)
logger.debug("Debug message with sensitive data: 1234567812345678.")
logger.info("User information: SSN 123-45-6789.")
logger.warning("Token authorization: Bearer abc123DEF456")
The library allows you to redact sensitive values in log messages based on user-defined patterns.
When logging a message, the logger will automatically mask sensitive data in accordance with the defined patterns.
Example Input:
logger.info("User credit card: 1234567812345678.")
logger.info("User SSN: 123-45-6789.")
logger.info("Token authorization: Bearer abc123DEF456")
Example Output:
2024-12-01 10:00:00 - __main__ - INFO - [trace_id: c0095715-d5bb-4991-9176-c5335368e481] [function: get_user_info] User credit card: **************78
2024-12-01 10:00:01 - __main__ - INFO - [trace_id: c0095715-d5bb-4991-9176-c5335368e481] [function: get_user_info] User SSN: ***-**-**89
2024-12-01 10:00:02 - __main__ - INFO - [trace_id: c0095715-d5bb-4991-9176-c5335368e481] [function: get_user_info] Token authorization: Bearer ********56
You can control how many characters should remain visible after masking the sensitive data by using the show_last option. By default, it will mask the entire sensitive value, but you can customize it like this:
# Mask with 2 visible characters after the mask
logger = get_logger(__name__, sensitive_patterns=sensitive_patterns, show_last=2)
The library works seamlessly with FastAPI. You can use TraceIDMiddleware to add trace IDs to every request and pass them along with the logs.
The middleware captures the trace ID from the request headers or generates a new one and passes it to the logger.
# Add TraceIDMiddleware to FastAPI
app.add_middleware(TraceIDMiddleware)
When defining your FastAPI endpoints, you can easily include the trace ID by using Depends(get_trace_id).
@app.get("/")
def say_hello(name: str = "Dev", trace_id: UUID = Depends(get_trace_id)):
logger.debug("This is debug level log.")
logger.info("This is info level log.")
logger.error("This is error level log.")
logger.warning("This is warning level log.")
return {"Message": f"Hello {name}"}
When logging messages with sensitive data, the library will mask sensitive parts of the values based on the configured patterns.
2024-12-01 10:00:00 - __main__ - INFO - User credit card: ****************
2024-12-01 10:00:01 - __main__ - INFO - User SSN: ***-**-6789
2024-12-01 10:00:02 - __main__ - INFO - Token authorization: Bearer **********
The logging level can be configured using the configure_logging function.
configure_logging(level="debug")
The available logging levels are:
DEBUG
INFO
WARNING
ERROR
CRITICAL
You can provide a list of regular expressions or exact strings for sensitive data. Here are some examples:
r"\d{16}"
: Match credit card numbers.r"(?:\d{3}-\d{2}-\d{4})"
: Match SSNs."User"
: Match the text "User".r"(?<=Bearer\s)[a-zA-Z0-9]+"
: Match tokens (e.g., Bearer tokens).
This option determines how many characters should remain visible after masking. The default is 0, which means the entire value is masked.
logger = get_logger(__name__, sensitive_patterns=sensitive_patterns, show_last=2)
The SecureLogs Library simplifies logging with trace ID support and provides powerful features to mask sensitive data in logs. With easy integration into FastAPI, this library ensures that sensitive data like credit card numbers, SSNs, and tokens are securely hidden while providing useful trace information.
By using this library, you can ensure your application’s logs are secure, readable, and traceable.
from uuid import UUID
from fastapi import Depends, FastAPI
from secure_logs import configure_logging, get_logger
from secure_logs import get_trace_id
from secure_logs.middleware import TraceIDMiddleware
# You can explicitly configure logging
configure_logging(level="debug") # Optional
app = FastAPI()
app.add_middleware(TraceIDMiddleware)
# Keep this in a common file from where you can access through out the project
# logger = get_logger(__name__,) # General implementation
# logger = get_logger(__name__, sensitive_patterns=['This', 'log']) # Hide sensitive values with *
# logger = get_logger(__name__, sensitive_patterns=['This', 'log'],show_last=1) # Hide sensitive values with * by showing only last 1 item
# Configure sensitive value filter
sensitive_patterns = [
r"\d{16}", # Example: credit card numbers
r"(?:\d{3}-\d{2}-\d{4})", # Example: SSNs
"User", # Example: any text
"level",
"log",
r"(?<=Bearer\s)[a-zA-Z0-9]+", # Example: token
]
logger = get_logger(__name__, sensitive_patterns=sensitive_patterns, show_last=2)
@app.get("/")
def say_hello(name: str = "Dev", trace_id: UUID = Depends(get_trace_id)):
logger.debug("This is debug level log.")
logger.info("This is info level log.")
logger.error("This is error level log.")
logger.warning("This is warning level log.")
return {"Message": f"Hello {name}"}
@app.get("/userinfo")
def get_user_info(trace_id: UUID = Depends(get_trace_id)):
logger.info("User credit card: 1234567812345678.")
logger.info("User SSN: 123-45-6789.")
logger.info("Token authorization: Bearer abc123DEF456")
return {"user": "Dev"}