diff --git a/acceptance_tests/gunicorn_app/app_alembic/env.py b/acceptance_tests/gunicorn_app/app_alembic/env.py index c2b987e82..e414e8e82 100644 --- a/acceptance_tests/gunicorn_app/app_alembic/env.py +++ b/acceptance_tests/gunicorn_app/app_alembic/env.py @@ -63,7 +63,6 @@ def run_migrations_online(): context.run_migrations() -c2cwsgiutils.setup_process.bootstrap_application() if context.is_offline_mode(): run_migrations_offline() else: diff --git a/acceptance_tests/gunicorn_app/c2cwsgiutils_app/services.py b/acceptance_tests/gunicorn_app/c2cwsgiutils_app/services.py index 084ec31f7..d9461ce9d 100644 --- a/acceptance_tests/gunicorn_app/c2cwsgiutils_app/services.py +++ b/acceptance_tests/gunicorn_app/c2cwsgiutils_app/services.py @@ -2,6 +2,7 @@ import prometheus_client import requests +import sqlalchemy.sql.expression from pyramid.httpexceptions import ( HTTPBadRequest, HTTPForbidden, diff --git a/acceptance_tests/tests/docker-compose.yaml b/acceptance_tests/tests/docker-compose.yaml index b8d528eab..781502e3a 100644 --- a/acceptance_tests/tests/docker-compose.yaml +++ b/acceptance_tests/tests/docker-compose.yaml @@ -27,7 +27,7 @@ services: - C2C_REDIS_DB=1 - PYTHONMALLOC=debug - DEBUG_LOGCONFIG - - GUNICORN_WORKERS=1 + - GUNICORN_WORKERS=2 - GUNICORN_THREADS=10 # Test problematic environment variable (values contains % and duplicated with different cass) - TEST='%1' diff --git a/acceptance_tests/tests/tests/test_prometheus_client.py b/acceptance_tests/tests/tests/test_prometheus_client.py index 0ea8c3d06..fca2630c8 100644 --- a/acceptance_tests/tests/tests/test_prometheus_client.py +++ b/acceptance_tests/tests/tests/test_prometheus_client.py @@ -13,7 +13,7 @@ def test_prometheus_1(prometheus_1_connection): def test_prometheus_2(prometheus_2_connection): # One for the root process, one for each workers - assert ( - len(set(_PID_RE.findall(prometheus_2_connection.get("metrics", cache_expected=False, cors=False)))) - == 3 - ) + metrics = prometheus_2_connection.get("metrics", cache_expected=False, cors=False) + assert len(set(_PID_RE.findall(metrics))) == 0 + assert re.search(r"^c2cwsgiutils_python_resource\{.*", metrics, re.MULTILINE) is not None + assert re.search(r"^c2cwsgiutils_python_memory_info\{.*", metrics, re.MULTILINE) is not None diff --git a/acceptance_tests/waitress_app/app_alembic/env.py b/acceptance_tests/waitress_app/app_alembic/env.py index c2b987e82..e414e8e82 100644 --- a/acceptance_tests/waitress_app/app_alembic/env.py +++ b/acceptance_tests/waitress_app/app_alembic/env.py @@ -63,7 +63,6 @@ def run_migrations_online(): context.run_migrations() -c2cwsgiutils.setup_process.bootstrap_application() if context.is_offline_mode(): run_migrations_offline() else: diff --git a/acceptance_tests/waitress_app/c2cwsgiutils_app/services.py b/acceptance_tests/waitress_app/c2cwsgiutils_app/services.py index 084ec31f7..d9461ce9d 100644 --- a/acceptance_tests/waitress_app/c2cwsgiutils_app/services.py +++ b/acceptance_tests/waitress_app/c2cwsgiutils_app/services.py @@ -2,6 +2,7 @@ import prometheus_client import requests +import sqlalchemy.sql.expression from pyramid.httpexceptions import ( HTTPBadRequest, HTTPForbidden, diff --git a/c2cwsgiutils/loader.py b/c2cwsgiutils/loader.py index 2d351420e..fc7491f4b 100644 --- a/c2cwsgiutils/loader.py +++ b/c2cwsgiutils/loader.py @@ -1,9 +1,9 @@ -import logging +import logging.config from typing import Optional, cast from plaster_pastedeploy import Loader as BaseLoader -from c2cwsgiutils import get_config_defaults +from c2cwsgiutils import get_config_defaults, get_logconfig_dict _LOG = logging.getLogger(__name__) @@ -19,3 +19,21 @@ def _get_defaults(self, defaults: Optional[dict[str, str]] = None) -> dict[str, def __repr__(self) -> str: """Get the object representation.""" return f'c2cwsgiutils.loader.Loader(uri="{self.uri}")' + + def setup_logging(self, defaults: Optional[dict[str, str]] = None) -> None: + """ + Set up logging via :func:`logging.config.fileConfig`. + + Defaults are specified for the special ``__file__`` and ``here`` + variables, similar to PasteDeploy config loading. Extra defaults can + optionally be specified as a dict in ``defaults``. + + Arguments: + defaults: The defaults that will be used when passed to + :func:`logging.config.fileConfig`. + + """ + if "loggers" in self.get_sections(): + logging.config.dictConfig(get_logconfig_dict(self.uri.path)) + else: + logging.basicConfig() diff --git a/poetry.lock b/poetry.lock index 911d9192c..1504e9512 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3011,9 +3011,9 @@ test = ["zope.testing"] [extras] alembic = ["alembic"] -all = ["Paste", "SQLAlchemy", "SQLAlchemy-Utils", "alembic", "boltons", "cornice", "gunicorn", "lxml", "objgraph", "prometheus-client", "psutil", "psycopg2", "pyjwt", "pyramid", "pyramid-tm", "pyramid_mako", "redis", "requests-oauthlib", "sentry-sdk", "waitress", "zope.interface", "zope.sqlalchemy"] +all = ["Paste", "SQLAlchemy", "SQLAlchemy-Utils", "alembic", "boltons", "cornice", "coverage", "gunicorn", "lxml", "objgraph", "prometheus-client", "psutil", "psycopg2", "pyjwt", "pyramid", "pyramid-tm", "pyramid_mako", "redis", "requests-oauthlib", "sentry-sdk", "waitress", "zope.interface", "zope.sqlalchemy"] broadcast = ["redis"] -debug = ["objgraph", "psutil"] +debug = ["coverage", "objgraph", "psutil"] dev = ["waitress"] oauth2 = ["pyjwt", "requests-oauthlib"] sentry = ["sentry-sdk"] @@ -3026,4 +3026,4 @@ webserver = ["SQLAlchemy", "SQLAlchemy-Utils", "cornice", "gunicorn", "prometheu [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0" -content-hash = "7b3d63162c2e3b5ca5212808d10352cdd09d187061142810c1760b6b058ae843" +content-hash = "494e21f3e8636f8a64ac9907f19963d6c26562489d99c7a000da993c3fde5d31" diff --git a/pyproject.toml b/pyproject.toml index 622030fe6..01139ac52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,7 @@ prometheus-client = { version = "0.21.0", optional = true} pyramid_mako = { version = "1.1.0", optional = true} psutil = { version = "6.1.0", optional = true} Paste = { version = "3.10.1", optional = true} +coverage = { version = "7.6.4", optional = true} [tool.poetry.extras] standard = [ @@ -123,7 +124,7 @@ standard = [ "Paste", ] alembic = ["alembic"] -debug = ["objgraph", "psutil"] +debug = ["objgraph", "psutil", "coverage"] oauth2 = ["pyjwt", "requests-oauthlib"] sentry = ["sentry-sdk"] dev = ["waitress"] @@ -160,6 +161,7 @@ all = [ # debug "objgraph", "psutil", + "coverage", # oauth2 "pyjwt", "requests-oauthlib",