Repository: jazzband/django-axes (python)

Issue:
Streamline AXES startup verbose logs
At the moment, the verbose logging starting here: https://github.com/jazzband/django-axes/blob/876b6f3dc4377daa6e1d2a1244ea7a86bf952695/axes/apps.py#L33 emits 3 lines like this:
```
2022-05-07 02:02:21,568 [INFO] axes.apps: AXES: BEGIN LOG
2022-05-07 02:02:21,569 [INFO] axes.apps: AXES: Using django-axes version 5.31.0
2022-05-07 02:02:21,569 [INFO] axes.apps: AXES: blocking by IP only.
```
Would it not be nicer to just output one line? For example like this:
```
2022-05-07 02:02:21,568 [INFO] axes.apps: AXES: BEGIN LOG: version 5.31.0, blocking by IP only
```
I'd be happy to provide a PR if desired.

Pull request description:
Refine and streamline startup log
The new output is on one line and looks like this:

AXES: BEGIN version 5.32.1.dev14+g038dc7c.d20220507, blocking by IP only

Resolves #884.

Patch:
diff --git a/axes/apps.py b/axes/apps.py
index 52737ba..0f8413a 100644
--- a/axes/apps.py
+++ b/axes/apps.py
@@ -30,20 +30,15 @@ class AppConfig(apps.AppConfig):
 
         # Skip startup log messages if Axes is not set to verbose
         if settings.AXES_VERBOSE:
-            log.info("AXES: BEGIN LOG")
-            log.info(
-                "AXES: Using django-axes version %s",
-                get_distribution("django-axes").version,
-            )
-
             if settings.AXES_ONLY_USER_FAILURES:
-                log.info("AXES: blocking by username only.")
+                mode = "blocking by username only"
             elif settings.AXES_LOCK_OUT_BY_COMBINATION_USER_AND_IP:
-                log.info("AXES: blocking by combination of username and IP.")
+                mode = "blocking by combination of username and IP"
             elif settings.AXES_LOCK_OUT_BY_USER_OR_IP:
-                log.info("AXES: blocking by username or IP.")
+                mode = "blocking by username or IP"
             else:
-                log.info("AXES: blocking by IP only.")
+                mode = "blocking by IP only"
+            log.info("AXES: BEGIN version %s, %s", get_distribution("django-axes").version, mode)
 
     def ready(self):
         self.initialize()


Test patch:
diff --git a/tests/test_logging.py b/tests/test_logging.py
index 5240f95..35ae52e 100644
--- a/tests/test_logging.py
+++ b/tests/test_logging.py
@@ -2,11 +2,15 @@ from unittest.mock import patch
 
 from django.test import override_settings
 from django.urls import reverse
+from pkg_resources import get_distribution
 
 from axes.apps import AppConfig
 from axes.models import AccessAttempt, AccessLog
 from tests.base import AxesTestCase
 
+_BEGIN = "AXES: BEGIN version %s, %s"
+_VERSION = get_distribution("django-axes").version
+
 
 @patch("axes.apps.AppConfig.initialized", False)
 @patch("axes.apps.log")
@@ -33,22 +37,22 @@ class AppsTestCase(AxesTestCase):
     @override_settings(AXES_ONLY_USER_FAILURES=True)
     def test_axes_config_log_user_only(self, log):
         AppConfig.initialize()
-        log.info.assert_called_with("AXES: blocking by username only.")
+        log.info.assert_called_with(_BEGIN, _VERSION, "blocking by username only")
 
     @override_settings(AXES_ONLY_USER_FAILURES=False)
     def test_axes_config_log_ip_only(self, log):
         AppConfig.initialize()
-        log.info.assert_called_with("AXES: blocking by IP only.")
+        log.info.assert_called_with(_BEGIN, _VERSION, "blocking by IP only")
 
     @override_settings(AXES_LOCK_OUT_BY_COMBINATION_USER_AND_IP=True)
     def test_axes_config_log_user_ip(self, log):
         AppConfig.initialize()
-        log.info.assert_called_with("AXES: blocking by combination of username and IP.")
+        log.info.assert_called_with(_BEGIN, _VERSION, "blocking by combination of username and IP")
 
     @override_settings(AXES_LOCK_OUT_BY_USER_OR_IP=True)
     def test_axes_config_log_user_or_ip(self, log):
         AppConfig.initialize()
-        log.info.assert_called_with("AXES: blocking by username or IP.")
+        log.info.assert_called_with(_BEGIN, _VERSION, "blocking by username or IP")
 
 
 class AccessLogTestCase(AxesTestCase):