Smarter Logging Filters

smarter.lib.logging.filters

Logging filters for the Smarter application.

This module provides custom logging filters for use with the Smarter platform’s logging configuration. The primary filter included is HealthCheckFilter, which suppresses log records generated by health check endpoints (such as /healthz/ or /readiness/) to reduce log noise and focus on meaningful application events.

Classes

HealthCheckFilter

A logging filter that excludes log records related to health check URLs. It can be used in Django or standard Python logging configurations to automatically filter out health check requests from logs.

Examples

To use the health check filter in a Django logging configuration:

LOGGING = {
    'filters': {
        'health_check': {
            '()': 'smarter.lib.logging.filters.HealthCheckFilter',
        },
    },
    'handlers': {
        'default': {
            'class': 'logging.StreamHandler',
            'filters': ['health_check'],
        },
    },
    ...
}

Any log entries containing a health check URL substring (as defined in health_check_urls) will be suppressed by this filter.

class smarter.lib.logging.filters.HealthCheckFilter(name='')[source]

Bases: Filter, SmarterHelperMixin

Logging filter to suppress log records for health check endpoints.

This filter is designed to be used with Python’s logging framework to automatically exclude log entries generated by health check endpoints (such as /healthz/ or /readiness/) from application logs. This helps reduce log noise and keeps logs focused on meaningful events.

The filter works by inspecting each log record’s message and checking if it contains any substring from the health_check_urls attribute, which should be a list of health check URL patterns. If a match is found, the log record is suppressed (not emitted).

Inherits from SmarterHelperMixin to provide access to shared configuration and helpers.

health_check_urls

List of URL substrings that identify health check endpoints. Log records containing any of these substrings in their message will be filtered out (not logged).

Type:

list of str

Examples

To use this filter in a Django logging configuration:

LOGGING = {
    ...
    'filters': {
        'health_check': {
            '()': 'smarter.lib.logging.filters.HealthCheckFilter',
        },
    },
    'handlers': {
        'default': {
            'class': 'logging.StreamHandler',
            'filters': ['health_check'],
        },
    },
    ...
}

The filter will then suppress log entries for any request matching the URLs in health_check_urls.

__init__(name='')

Initialize a filter.

Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event.

property amnesty_urls: list[str]

Returns a list of URLs that are exempt from certain checks.

Returns:

List of URL path strings that are exempt.

Return type:

list[str]

bool_environment_variable(var_name, default=False)

Retrieves a boolean value from an environment variable.

This method checks the specified environment variable and returns its value as a boolean. It recognizes common truthy values such as “true”, “1”, “yes”, and “on”. If the variable is not set or cannot be interpreted as a boolean, it returns the provided default value.

Parameters:
  • var_name (str) – The name of the environment variable to check.

  • default (bool) – The default boolean value to return if the environment variable is not set or invalid.

Returns:

The boolean value of the environment variable or the default.

Return type:

bool

data_to_dict(data)

Converts data to a dictionary, handling different types of input.

This method accepts either a dictionary or a string. If a string is provided, it will attempt to parse it as JSON first, and if that fails, as YAML. If parsing fails or the data type is unsupported, a SmarterValueError is raised.

Parameters:

data (Union[dict, str]) – The data to convert, either a dict or a JSON/YAML string.

Returns:

The data as a dictionary.

Return type:

dict

Raises:

SmarterValueError – If the data cannot be converted to a dictionary.

deserves_amnesty(slug)

Determines if a given URL deserves amnesty based on the amnesty URLs list. This excuses certain endpoints (like health checks) from select middleware checks.

Parameters:

slug (str) – The URL path to check.

Returns:

True if the URL deserves amnesty, False otherwise.

Return type:

bool

dict_is_contained_in(dict1, dict2)

Checks if one dictionary is contained within another. This method determines if all key-value pairs in dict1 are present in dict2.

Parameters:
  • dict1 (dict) – The dictionary to check for containment.

  • dict2 (dict) – The dictionary to check against for containment.

Returns:

True if dict1 is contained in dict2, False otherwise.

Return type:

bool

dict_is_subset(small, big)

Checks if one dictionary is a subset of another.

This method determines if all key-value pairs in the small dictionary are present in the big dictionary. It returns True if the small dictionary is a subset of the big dictionary, and False otherwise.

Parameters:
  • small (dict) – The dictionary to check as a subset.

  • big (dict) – The dictionary to check against as a superset.

Returns:

True if the small dictionary is a subset of the big dictionary, False otherwise.

Return type:

bool

filter(record)[source]

Determine whether a log record should be emitted based on health check URLs.

This filter inspects the log record’s path argument and excludes any log entries that match one of the configured health check URLs. This is typically used to suppress noisy log entries generated by health check endpoints (such as /healthz/ or /readiness/) in application logs.

The list of health check URLs is provided by the health_check_urls attribute, which should be a list of string patterns (e.g., “/healthz/”, “/readiness/”). Both the log path and the health check URLs are normalized by stripping leading/trailing slashes and lowercasing before comparison, so that variants like “/healthz”, “/healthz/”, or “healthz” all match.

Example record.args for a Uvicorn access log:

(
    "192.168.9.92:60250",   # client address
    "GET",                  # HTTP method
    "/healthz/",            # path
    "1.1",                  # HTTP version
    200,                    # status code
)
Return type:

bool

Parameters:

record (logging.LogRecord) – The log record to be filtered.

Returns:

False if the log record path matches a health check URL and should be suppressed; True otherwise (the log record will be emitted).

Return type:

bool

Examples

>>> filter = HealthCheckFilter()
>>> class DummyRecord:
...     name = "uvicorn.access" # Simulate a Uvicorn access log record
...     args = ("127.0.0.1:12345", "GET", "/healthz/", "1.1", 200)
>>> filter.health_check_urls = ["/healthz/", "/readiness/"]
>>> filter.filter(DummyRecord())
False
>>> DummyRecord.args = ("127.0.0.1:12345", "GET", "/api/v1/resource/", "1.1", 200)
>>> filter.filter(DummyRecord())
True
property formatted_class_name: str

Returns the class name formatted for logging.

Returns:

The formatted class name as a string.

Return type:

str

property formatted_state_not_ready: str

Returns the not-ready state formatted for logging.

Returns:

The formatted not-ready state as a string.

Return type:

str

property formatted_state_ready: str

Returns the readiness state formatted for logging.

Returns:

The formatted readiness state as a string.

Return type:

str

generate_fernet_encryption_key()

Generates a Fernet encryption key.

This method creates a new Fernet encryption key, which can be used for secure encryption and decryption of data. The generated key is returned as a URL-safe base64-encoded string.

Returns:

A new Fernet encryption key.

Return type:

str

get_readonly_csv_file(file_path)

Retrieves a read-only file object for a CSV file.

This method opens the specified CSV file in read-only mode and returns a file object that can be used to read its contents. It ensures that the file is not modified during the reading process.

Parameters:

file_path (str) – The path to the CSV file to open.

Returns:

A read-only file object for the specified CSV file.

Return type:

file

get_readonly_yaml_file(file_path)

Retrieves a read-only file object for a YAML file.

This method opens the specified YAML file in read-only mode and returns a file object that can be used to read its contents. It ensures that the file is not modified during the reading process.

Parameters:

file_path (str) – The path to the YAML file to open.

Returns:

A read-only file object for the specified YAML file.

Return type:

file

property health_check_urls: list[str]

Returns a list of URL paths that are considered health check endpoints.

Returns:

List of health check URL path strings.

Return type:

list[str]

mask_string(string='', mask_char='*', mask_length=4, string_length=8)

Masks a string for secure logging.

This utility function masks all but the last unmasked_chars characters of the input string, replacing them with asterisks. It is useful for logging sensitive information like API keys or passwords.

Parameters:
  • string (Optional[str]) – The string to be masked.

  • mask_char (str) – The character used for masking.

  • mask_length (int) – The number of characters to mask.

  • string_length (int) – The length of the string to consider for masking.

Returns:

The masked string.

Return type:

str

property ready: bool

Indicates whether the object is ready for use. This is a placeholder that should be overridden in subclasses.

Returns:

True if ready, False otherwise.

Return type:

bool

recursive_sort_dict(data)

Recursively sorts a dictionary by its keys.

This method takes a dictionary and returns a new dictionary with all keys sorted in ascending order. If any values are also dictionaries, they will be sorted recursively as well.

Parameters:

data (dict) – The dictionary to sort.

Returns:

A new dictionary with all keys sorted.

Return type:

dict

rfc1034_compliant_str(name)

Converts a string to an RFC 1034 compliant format.

This method takes a string and converts it to a format that complies with RFC 1034, which is commonly used for domain names. It replaces invalid characters with hyphens and ensures the resulting string is lowercase.

Parameters:

name (str) – The string to convert to RFC 1034 compliant format.

Returns:

The converted string in RFC 1034 compliant format.

Return type:

str

rfc1034_compliant_to_snake(name)

Converts an RFC 1034 compliant string to snake_case.

This method takes a string in RFC 1034 compliant format and converts it to snake_case. It replaces hyphens with underscores and ensures the resulting string is lowercase.

Parameters:

name (str) – The RFC 1034 compliant string to convert.

Returns:

The converted string in snake_case.

Return type:

str

smarter_build_absolute_uri(request)

Attempts to get the absolute URI from a request object.

This utility function tries to retrieve the request URL from any valid child class of django.http.HttpRequest. It is especially useful in unit tests or scenarios where the request object may not implement build_absolute_uri().

Parameters:

request (HttpRequest) – The request object.

Returns:

The absolute request URL.

Return type:

Optional[str]

Raises:

SmarterValueError – If the URI cannot be built from the request.

sorted_dict(data)

Returns a new dictionary with keys sorted.

Parameters:

data (dict) – The dictionary to sort.

Returns:

A new dictionary with sorted keys.

Return type:

dict

to_camel_case(data, convert_values=False)

Converts a snake_case string to camelCase.

This method takes a string in snake_case format and converts it to camelCase. It is useful for standardizing naming conventions across different formats.

Parameters:
  • data (Union[str, dict[str, object], list[object], object]) – The snake_case string to convert.

  • convert_values (bool) – Whether to convert the values of dictionaries and lists recursively.

Returns:

The converted string in camelCase.

Return type:

Any

to_snake_case(data, convert_values=False)

Converts a camelCase or PascalCase string to snake_case.

This method takes a string in camelCase or PascalCase format and converts it to snake_case. It is useful for standardizing naming conventions across different formats.

Parameters:
  • data (Union[str, dict[str, object], list[object], object]) – The camelCase or PascalCase string to convert.

  • convert_values (bool) – Whether to convert the values of dictionaries and lists recursively.

Returns:

The converted string in snake_case.

Return type:

Any

property unformatted_class_name: str

Returns the raw class name without formatting.

Returns:

The unformatted class name as a string.

Return type:

str

This is useful for logging or serialization where the plain class name is needed.