diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 627e741..738a01c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,16 +30,16 @@ jobs: pip install coverage codecov pytest poetry pip install -r packages/requirements-dev.txt -# - name: Run tests with coverage -# run: pytest --cov=django_logging --cov-report=xml -# -# - name: Run Tox tests -# run: tox + - name: Run tests with coverage + run: pytest --cov=django_logging --cov-report=xml + + - name: Run Tox tests + run: tox - name: Run pre-commit hooks run: pre-commit run --all-files --config=.pre-commit-config-ci.yaml -# - name: Upload coverage to Codecov -# run: codecov -# env: -# CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Upload coverage to Codecov + run: codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.pre-commit-config-ci.yaml b/.pre-commit-config-ci.yaml index 5f8059e..05b01ee 100644 --- a/.pre-commit-config-ci.yaml +++ b/.pre-commit-config-ci.yaml @@ -83,13 +83,13 @@ repos: files: ^(docs/(.*/)*.*\.rst) additional_dependencies: [ Sphinx==6.2.1 ] -# - repo: local -# hooks: -# - id: pytest -# name: Pytest -# entry: poetry run pytest -v -# language: system -# types: [ python ] -# stages: [ commit ] -# pass_filenames: false -# always_run: true + - repo: local + hooks: + - id: pytest + name: Pytest + entry: poetry run pytest -v + language: system + types: [ python ] + stages: [ commit ] + pass_filenames: false + always_run: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e192124..a0990bb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -85,14 +85,14 @@ repos: - repo: local hooks: -# - id: pytest -# name: Pytest -# entry: poetry run pytest -v -# language: system -# types: [ python ] -# stages: [ commit ] -# pass_filenames: false -# always_run: true + - id: pytest + name: Pytest + entry: poetry run pytest -v + language: system + types: [ python ] + stages: [ commit ] + pass_filenames: false + always_run: true - id: pylint name: pylint diff --git a/django_logging/contextvar/contextvar_manager.py b/django_logging/contextvar/contextvar_manager.py index d691ea2..459de32 100644 --- a/django_logging/contextvar/contextvar_manager.py +++ b/django_logging/contextvar/contextvar_manager.py @@ -55,7 +55,7 @@ def bind(self, **kwargs: Any) -> None: var = self._get_or_create(key) var.set(value) - def batch_bind(self, **kwargs: Any) -> Dict[str, contextvars.Token[Any]]: + def batch_bind(self, **kwargs: Any) -> Dict[str, contextvars.Token]: """Bind multiple context variables and return tokens for resetting. Args: @@ -82,7 +82,7 @@ def unbind(self, key: str) -> None: if full_key in self._context_vars: self._context_vars[full_key].set(Ellipsis) - def reset(self, tokens: Dict[str, contextvars.Token[Any]]) -> None: + def reset(self, tokens: Dict[str, contextvars.Token]) -> None: """Reset context variables to their previous state using tokens. Args: diff --git a/django_logging/templates/email_notifier_template.html b/django_logging/templates/email_notifier_template.html index dda0fd1..c1901fb 100644 --- a/django_logging/templates/email_notifier_template.html +++ b/django_logging/templates/email_notifier_template.html @@ -41,7 +41,7 @@ -

Log Message:

+

Message:

{{ message }}

{% if ip_address != "Unknown" %}

IP Address:

diff --git a/django_logging/utils/console_colorizer.py b/django_logging/utils/console_colorizer.py index d82f37e..dbe3b18 100644 --- a/django_logging/utils/console_colorizer.py +++ b/django_logging/utils/console_colorizer.py @@ -1,18 +1,17 @@ from django_logging.constants.ansi_colors import LOG_LEVEL_COLORS, AnsiColors -from django_logging.constants.config_types import LogLevel def colorize_log_format(log_format: str, levelname: str) -> str: colors = AnsiColors() color_mapping = { - "%(asctime)s": f"{colors.CYAN}%(asctime)s{colors.RESET}", + "%(asctime)s": f"{colors.BRIGHT_YELLOW}%(asctime)s{colors.RESET}", "%(created)f": f"{colors.BRIGHT_BLUE}%(created)f{colors.RESET}", "%(relativeCreated)d": f"{colors.MAGENTA}%(relativeCreated)d{colors.RESET}", "%(msecs)d": f"{colors.YELLOW}%(msecs)d{colors.RESET}", "%(levelname)s": f"{LOG_LEVEL_COLORS.get(levelname, '')}%(levelname)s{colors.RESET}", "%(levelno)d": f"{colors.RED}%(levelno)d{colors.RESET}", "%(name)s": f"{colors.BRIGHT_MAGENTA}%(name)s{colors.RESET}", - "%(module)s": f"{colors.BRIGHT_GREEN}%(module)s{colors.RESET}", + "%(module)s": f"{colors.PINK}%(module)s{colors.RESET}", "%(filename)s": f"{colors.YELLOW}%(filename)s{colors.RESET}", "%(pathname)s": f"{colors.CYAN}%(pathname)s{colors.RESET}", "%(lineno)d": f"{colors.RED}%(lineno)d{colors.RESET}", @@ -20,7 +19,8 @@ def colorize_log_format(log_format: str, levelname: str) -> str: "%(process)d": f"{colors.MAGENTA}%(process)d{colors.RESET}", "%(thread)d": f"{colors.CYAN}%(thread)d{colors.RESET}", "%(threadName)s": f"{colors.BRIGHT_MAGENTA}%(threadName)s{colors.RESET}", - "%(message)s": f"{colors.GRAY}%(message)s{colors.RESET}", + "%(message)s": f"{colors.ITALIC}%(message)s{colors.RESET}", + "%(context)s": f"{colors.CYAN}%(context)s{colors.RESET}", } for placeholder, colorized in color_mapping.items(): diff --git a/django_logging/utils/log_email_notifier/notifier.py b/django_logging/utils/log_email_notifier/notifier.py index d0322ce..be20c5b 100644 --- a/django_logging/utils/log_email_notifier/notifier.py +++ b/django_logging/utils/log_email_notifier/notifier.py @@ -32,10 +32,10 @@ def send_email() -> None: settings.DEFAULT_FROM_EMAIL, recipient_list, msg.as_string() ) server.quit() - logger.info("Log Record has been sent to ADMIN EMAIL successfully.") + logger.info("The Record has been sent to ADMIN EMAIL successfully.") except Exception as e: # pylint: disable=broad-exception-caught - logger.warning("Email Notifier failed to send Log Record: %s", e) + logger.warning("Email Notifier failed to send the Record: %s", e) finally: if event: diff --git a/packages/requirements-dev.txt b/packages/requirements-dev.txt index 9e8a590..c8f4e82 100644 --- a/packages/requirements-dev.txt +++ b/packages/requirements-dev.txt @@ -62,6 +62,7 @@ pylint-django==2.5.5 ; python_version >= "3.8" and python_version < "4.0" pylint-plugin-utils==0.8.2 ; python_version >= "3.8" and python_version < "4.0" pylint==3.2.7 ; python_version >= "3.8" and python_version < "4.0" pyproject-api==1.7.1 ; python_version >= "3.8" and python_version < "4.0" +pytest-asyncio==0.24.0 ; python_version >= "3.8" and python_version < "4.0" pytest-cov==5.0.0 ; python_version >= "3.8" and python_version < "4.0" pytest-django==4.9.0 ; python_version >= "3.8" and python_version < "4.0" pytest==8.3.2 ; python_version >= "3.8" and python_version < "4.0" diff --git a/pyproject.toml b/pyproject.toml index 77f19a4..a0de8ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ django = [ [tool.poetry.group.dev.dependencies] pytest = "^8.3.2" +pytest-asyncio = "^0.24.0" pytest-django = "^4.8.0" pytest-cov = "^5.0.0" pylint = "^3.2.6" @@ -168,14 +169,23 @@ addopts = "--cov --cov-report=term-missing --cov-report=html --cov-fail-under=90 markers = [ "commands: Tests for Django management commands in the logging package.", "commands_send_logs: Tests focused on the `send_logs` management command.", + "commands_generate_pretty_json: Tests for the command that generates pretty-formatted JSON logs.", + "commands_generate_pretty_xml: Tests for the command that generates pretty-formatted XML logs.", + "commands_logs_size_audit: Tests for the command that audits log sizes to ensure they don't exceed defined limits.", "filters: Tests that verify log filtering mechanisms.", "filters_level_filter: Tests for filtering logs based on their severity level.", "formatters: Tests for log formatters that structure log messages.", + "base_formatter: Tests for the base class of formatters.", + "flat_formatter: Tests for the formatter that creates flat log formats.", + "json_formatter: Tests for the formatter that structures logs as JSON objects.", + "xml_formatter: Tests for the formatter that structures logs as XML documents.", "colored_formatter: Tests for a formatter that adds color coding to log messages.", "handlers: Tests for components that dispatch log messages to their destinations.", "email_handler: Tests for the handler responsible for sending logs via email.", "middleware: Tests related to middleware components in logging.", + "base_middleware: Tests for the base class of middleware components.", "request_middleware: Tests for middleware handling incoming HTTP requests in logging.", + "monitor_log_size_middleware: Tests for middleware that monitors the size of log files.", "settings: Tests that ensure logging settings are correctly applied.", "settings_checks: Tests for validating the correctness of logging settings.", "settings_conf: Tests for verifying the configuration of logging settings.", @@ -185,12 +195,16 @@ markers = [ "utils_get_conf: Tests for utility functions that retrieve configuration settings.", "utils_log_and_notify: Tests for logging utilities that trigger notifications.", "utils_set_conf: Tests for utility functions that set configuration settings.", + "utils_process_file: Tests for utility functions that process files.", "validators: Tests for validating configurations and inputs in the logging package.", "config_validator: Tests focused on validators that check configuration settings.", "email_settings_validator: Tests for validators that ensure email settings are valid.", "decorators: Tests focused on custom decorators used throughout the package.", "decorators_execution_tracking: Tests specifically for the execution_tracking module.", + "contextvar: Tests for context variable handling in the logging package.", + "contextvar_manager: Tests for managing context variables across different log contexts.", ] +asyncio_default_fixture_loop_scope = [ "function" ] [tool.coverage.run] source = [ "django_logging" ]