Repository: scoutapp/scout_apm_python

Issue:
Hide scout message about event draining
When `log_level` is set to `ERROR` and logs are redirected to a log file through `log_file_path`, scout still logs a message like: `Scout draining 1 event for up to 2.0 seconds` on STDOUT, is it possible to remove this message from STDOUT?
Thank you!


Discussion:
Hi @Oscarchase 

This message is on stderr, and was added recently in version 2.11.0: #473 . We had a bit of debate how to send the message but ultimately copied Sentry, which does the same. If we added a configuration value to disable this, would that suit you?

Btw the `log_level` and `log_file_path` configuration values only affect the core agent, which is a separate process. They don't affect the Python logging configuration for Scout. We have some docs for [configuring Scout's python logging](https://docs.scoutapm.com/#python-logging). #497 will update the names of these configuration values to reduce confusion.

Thanks,

Adam

Hi @adamchainz,

I guess that a config value to disable this feature would be nice!
Thank you for the clarification on the log values.

Oscar

Resolving patch:
diff --git a/src/scout_apm/core/__init__.py b/src/scout_apm/core/__init__.py
--- a/src/scout_apm/core/__init__.py
+++ b/src/scout_apm/core/__init__.py
@@ -62,17 +62,18 @@ def shutdown():
     timeout_seconds = scout_config.value("shutdown_timeout_seconds")
 
     def callback(queue_size):
-        print(  # noqa: T001
-            (
-                "Scout draining {queue_size} event{s} for up to"
-                + " {timeout_seconds} seconds"
-            ).format(
-                queue_size=queue_size,
-                s=("" if queue_size == 1 else "s"),
-                timeout_seconds=timeout_seconds,
-            ),
-            file=sys.stderr,
-        )
+        if scout_config.value("shutdown_message_enabled"):
+            print(  # noqa: T001
+                (
+                    "Scout draining {queue_size} event{s} for up to"
+                    + " {timeout_seconds} seconds"
+                ).format(
+                    queue_size=queue_size,
+                    s=("" if queue_size == 1 else "s"),
+                    timeout_seconds=timeout_seconds,
+                ),
+                file=sys.stderr,
+            )
 
     CoreAgentSocketThread.wait_until_drained(
         timeout_seconds=timeout_seconds, callback=callback
diff --git a/src/scout_apm/core/config.py b/src/scout_apm/core/config.py
--- a/src/scout_apm/core/config.py
+++ b/src/scout_apm/core/config.py
@@ -73,6 +73,7 @@ def known_keys(self):
             "name",
             "revision_sha",
             "scm_subdirectory",
+            "shutdown_message_enabled",
             "shutdown_timeout_seconds",
             "socket_path",
         ]
@@ -221,6 +222,7 @@ def __init__(self):
             "name": "Python App",
             "revision_sha": self._git_revision_sha(),
             "scm_subdirectory": "",
+            "shutdown_message_enabled": True,
             "shutdown_timeout_seconds": 2.0,
             "uri_reporting": "filtered_params",
         }
@@ -285,6 +287,7 @@ def convert_to_list(value):
     "disabled_instruments": convert_to_list,
     "ignore": convert_to_list,
     "monitor": convert_to_bool,
+    "shutdown_message_enabled": convert_to_bool,
     "shutdown_timeout_seconds": convert_to_float,
 }
 


Test patch:
diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py
--- a/tests/unit/test_core.py
+++ b/tests/unit/test_core.py
@@ -57,6 +57,7 @@ def test_install_success(caplog):
 
 
 def test_shutdown(capsys):
+    scout_config
     report_app_metadata()  # queued but thread not running
     try:
         scout_config.set(shutdown_timeout_seconds=0.1)
@@ -67,3 +68,16 @@ def test_shutdown(capsys):
 
     captured = capsys.readouterr()
     assert "Scout draining" in captured.err
+
+
+def test_shutdown_message_disabled(capsys):
+    report_app_metadata()  # queued but thread not running
+    try:
+        scout_config.set(shutdown_timeout_seconds=0.1, shutdown_message_enabled=False)
+
+        shutdown()
+    finally:
+        Config.reset_all()
+
+    captured = capsys.readouterr()
+    assert not captured.err