Repository: sanic-org/sanic

Issue:
Sanic enables writing of DeprecationWarning to the log
**Describe the bug**
Sanic changes the default DeprecationWarning behaviour to be written to the log.
The code line that cause it is in app.py line 104:
`filterwarnings("once", category=DeprecationWarning)`

This change makes all of the DeprecationWarning, *in every 3rd party library* we use, to be written to the log.


**Expected behavior**
I would expect that this will not happen in production 😅 


**Environment (please complete the following information):**
<!-- Please provide the information below. Instead, you can copy and paste the message that Sanic shows on startup. If you do, please remember to format it with ``` -->
 - OS: ubuntu & macOS
 - Sanic Version: 22.6


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/sanic-org/sanic/pull/2546?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org) Report
Base: **87.450**% // Head: **87.435**% // Decreases project coverage by **`-0.015%`** :warning:
> Coverage data is based on head [(`b49ed80`)](https://codecov.io/gh/sanic-org/sanic/pull/2546?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org) compared to base [(`e499940`)](https://codecov.io/gh/sanic-org/sanic/commit/e4999401ab3bbb00d7fda7067e1dbed8533d7eb5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org).
> Patch coverage: 83.333% of modified lines in pull request are covered.

> :exclamation: Current head b49ed80 differs from pull request most recent head 9d370a6. Consider uploading reports for the commit 9d370a6 to get more accurate results

<details><summary>Additional details and impacted files</summary>


```diff
@@              Coverage Diff              @@
##              main     #2546       +/-   ##
=============================================
- Coverage   87.450%   87.435%   -0.016%     
=============================================
  Files           69        69               
  Lines         5602      5611        +9     
  Branches       974       976        +2     
=============================================
+ Hits          4899      4906        +7     
- Misses         509       510        +1     
- Partials       194       195        +1     
```


| [Impacted Files](https://codecov.io/gh/sanic-org/sanic/pull/2546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org) | Coverage Δ | |
|---|---|---|
| [sanic/app.py](https://codecov.io/gh/sanic-org/sanic/pull/2546/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org#diff-c2FuaWMvYXBwLnB5) | `88.783% <ø> (-0.043%)` | :arrow_down: |
| [sanic/config.py](https://codecov.io/gh/sanic-org/sanic/pull/2546/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org#diff-c2FuaWMvY29uZmlnLnB5) | `97.385% <83.333%> (-1.206%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/sanic-org/sanic/pull/2546?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org).


Patch:
diff --git a/sanic/app.py b/sanic/app.py
index 73e9fc37..85d5fbce 100644
--- a/sanic/app.py
+++ b/sanic/app.py
@@ -42,7 +42,6 @@ from typing import (
     Union,
 )
 from urllib.parse import urlencode, urlunparse
-from warnings import filterwarnings
 
 from sanic_routing.exceptions import FinalizationError, NotFound
 from sanic_routing.route import Route
@@ -105,8 +104,6 @@ if TYPE_CHECKING:
 if OS_IS_WINDOWS:  # no cov
     enable_windows_color_support()
 
-filterwarnings("once", category=DeprecationWarning)
-
 
 class Sanic(BaseSanic, StartupMixin, metaclass=TouchUpMeta):
     """
diff --git a/sanic/config.py b/sanic/config.py
index b06ea038..5c90086d 100644
--- a/sanic/config.py
+++ b/sanic/config.py
@@ -1,9 +1,12 @@
 from __future__ import annotations
 
+import sys
+
 from inspect import getmembers, isclass, isdatadescriptor
 from os import environ
 from pathlib import Path
 from typing import Any, Callable, Dict, Optional, Sequence, Union
+from warnings import filterwarnings
 
 from sanic.constants import LocalCertCreator
 from sanic.errorpages import DEFAULT_FORMAT, check_error_format
@@ -13,6 +16,20 @@ from sanic.log import deprecation, error_logger
 from sanic.utils import load_module_from_file_location, str_to_bool
 
 
+if sys.version_info >= (3, 8):
+    from typing import Literal
+
+    FilterWarningType = Union[
+        Literal["default"],
+        Literal["error"],
+        Literal["ignore"],
+        Literal["always"],
+        Literal["module"],
+        Literal["once"],
+    ]
+else:
+    FilterWarningType = str
+
 SANIC_PREFIX = "SANIC_"
 
 
@@ -22,6 +39,7 @@ DEFAULT_CONFIG = {
     "AUTO_EXTEND": True,
     "AUTO_RELOAD": False,
     "EVENT_AUTOREGISTER": False,
+    "DEPRECATION_FILTER": "once",
     "FORWARDED_FOR_HEADER": "X-Forwarded-For",
     "FORWARDED_SECRET": None,
     "GRACEFUL_SHUTDOWN_TIMEOUT": 15.0,  # 15 sec
@@ -72,6 +90,7 @@ class Config(dict, metaclass=DescriptorMeta):
     AUTO_EXTEND: bool
     AUTO_RELOAD: bool
     EVENT_AUTOREGISTER: bool
+    DEPRECATION_FILTER: FilterWarningType
     FORWARDED_FOR_HEADER: str
     FORWARDED_SECRET: Optional[str]
     GRACEFUL_SHUTDOWN_TIMEOUT: float
@@ -130,6 +149,7 @@ class Config(dict, metaclass=DescriptorMeta):
             self.load_environment_vars(SANIC_PREFIX)
 
         self._configure_header_size()
+        self._configure_warnings()
         self._check_error_format()
         self._init = True
 
@@ -178,6 +198,8 @@ class Config(dict, metaclass=DescriptorMeta):
             self.LOCAL_CERT_CREATOR = LocalCertCreator[
                 self.LOCAL_CERT_CREATOR.upper()
             ]
+        elif attr == "DEPRECATION_FILTER":
+            self._configure_warnings()
 
     @property
     def FALLBACK_ERROR_FORMAT(self) -> str:
@@ -205,6 +227,13 @@ class Config(dict, metaclass=DescriptorMeta):
             self.REQUEST_MAX_SIZE,
         )
 
+    def _configure_warnings(self):
+        filterwarnings(
+            self.DEPRECATION_FILTER,
+            category=DeprecationWarning,
+            module=r"sanic.*",
+        )
+
     def _check_error_format(self, format: Optional[str] = None):
         check_error_format(format or self.FALLBACK_ERROR_FORMAT)
 


Test patch:
diff --git a/tests/test_deprecation.py b/tests/test_deprecation.py
index 3bf5bd36..04817f88 100644
--- a/tests/test_deprecation.py
+++ b/tests/test_deprecation.py
@@ -1,5 +1,6 @@
 import pytest
 
+from sanic import Sanic
 from sanic.log import deprecation
 
 
@@ -7,3 +8,13 @@ def test_deprecation():
     message = r"\[DEPRECATION v9\.9\] hello"
     with pytest.warns(DeprecationWarning, match=message):
         deprecation("hello", 9.9)
+
+
+@pytest.mark.parametrize(
+    "filter,expected",
+    (("default", 1), ("once", 1), ("ignore", 0)),
+)
+def test_deprecation_filter(app: Sanic, filter, expected, recwarn):
+    app.config.DEPRECATION_FILTER = filter
+    deprecation("hello", 9.9)
+    assert len(recwarn) == expected