From 8128081e8b55420a80dceada9dc10c8fb387948b Mon Sep 17 00:00:00 2001 From: Hema Shree Date: Wed, 12 Aug 2026 15:22:25 +0530 Subject: [PATCH 1/4] fix: strip URI scheme prefixes from DD_DOGSTATSD_URL --- .../docker_gunicorn_configuration.py | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/commerce_coordinator/docker_gunicorn_configuration.py b/commerce_coordinator/docker_gunicorn_configuration.py index 19979c7e8..124ce9d59 100644 --- a/commerce_coordinator/docker_gunicorn_configuration.py +++ b/commerce_coordinator/docker_gunicorn_configuration.py @@ -1,9 +1,13 @@ """ gunicorn configuration file, see https://docs.gunicorn.org/en/develop/configure.html for more info. """ +import logging import multiprocessing # pylint: disable=unused-import import os + +logger = logging.getLogger(__name__) + preload_app = True timeout = 300 bind = "0.0.0.0:8140" @@ -15,21 +19,23 @@ _dogstatsd_url = os.environ.get("DD_DOGSTATSD_URL", "").strip() if _dogstatsd_url: + # Strip protocol schemes so Gunicorn receives the raw file path or HOST:PORT if _dogstatsd_url.startswith("unix://"): - # Gunicorn accepts unix socket directly as "unix:///path". - _statsd_host = _dogstatsd_url if _dogstatsd_url != "unix://" else "" + _statsd_host = _dogstatsd_url[len("unix://"):] + elif _dogstatsd_url.startswith("unixpack://"): + _statsd_host = _dogstatsd_url[len("unixpack://"):] + elif _dogstatsd_url.startswith("udp://"): + _statsd_host = _dogstatsd_url[len("udp://"):] else: - # Strip "udp://" when present; Gunicorn expects plain "HOST:PORT". - _statsd_host = ( - _dogstatsd_url[len("udp://"):] - if _dogstatsd_url.startswith("udp://") - else _dogstatsd_url - ).strip() + _statsd_host = _dogstatsd_url if _statsd_host: statsd_host = _statsd_host statsd_prefix = "commerce-coordinator" + # Log parsed statsd host on startup for verification + logger.info("Configured statsd_host=%s", statsd_host) + def pre_request(worker, req): """Log requests before they are processed.""" From e0e1963eea01afaca0b48d142924498a8957365a Mon Sep 17 00:00:00 2001 From: Hema Shree Date: Tue, 18 Aug 2026 21:40:33 +0530 Subject: [PATCH 2/4] fix: format DD_DOGSTATSD_URL for gunicorn statsd_host --- .../docker_gunicorn_configuration.py | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/commerce_coordinator/docker_gunicorn_configuration.py b/commerce_coordinator/docker_gunicorn_configuration.py index 124ce9d59..85f514934 100644 --- a/commerce_coordinator/docker_gunicorn_configuration.py +++ b/commerce_coordinator/docker_gunicorn_configuration.py @@ -5,8 +5,8 @@ import multiprocessing # pylint: disable=unused-import import os - -logger = logging.getLogger(__name__) +# Use the specific gunicorn error logger +logger = logging.getLogger("gunicorn.error") preload_app = True timeout = 300 @@ -17,24 +17,34 @@ # StatsD / DogStatsD configuration _dogstatsd_url = os.environ.get("DD_DOGSTATSD_URL", "").strip() +statsd_host = None if _dogstatsd_url: - # Strip protocol schemes so Gunicorn receives the raw file path or HOST:PORT + # 1. Handle Unix Domain Sockets (requires 'unix:' or 'unixpack:' prefix for Gunicorn) if _dogstatsd_url.startswith("unix://"): - _statsd_host = _dogstatsd_url[len("unix://"):] + path = _dogstatsd_url[len("unix://"):] + if path: + statsd_host = f"unix:{path}" + elif _dogstatsd_url.startswith("unixpack://"): - _statsd_host = _dogstatsd_url[len("unixpack://"):] + path = _dogstatsd_url[len("unixpack://"):] + if path: + statsd_host = f"unixpack:{path}" + + # 2. Handle UDP or standard HOST:PORT (Gunicorn expects plain "HOST:PORT") elif _dogstatsd_url.startswith("udp://"): - _statsd_host = _dogstatsd_url[len("udp://"):] + statsd_host = _dogstatsd_url[len("udp://"):] + else: - _statsd_host = _dogstatsd_url + statsd_host = _dogstatsd_url - if _statsd_host: - statsd_host = _statsd_host + if statsd_host: statsd_prefix = "commerce-coordinator" - # Log parsed statsd host on startup for verification + # Log parsed statsd host on startup for verification using gunicorn.error logger logger.info("Configured statsd_host=%s", statsd_host) + else: + logger.info("DogStatsD URL provided but empty, skipping configuration.") def pre_request(worker, req): From c144ce3579367c58f1ed037550775f381d32f5df Mon Sep 17 00:00:00 2001 From: Hema Shree Date: Wed, 19 Aug 2026 10:26:40 +0530 Subject: [PATCH 3/4] fix: format DD_DOGSTATSD_URL for gunicorn statsd_host --- .../docker_gunicorn_configuration.py | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/commerce_coordinator/docker_gunicorn_configuration.py b/commerce_coordinator/docker_gunicorn_configuration.py index 85f514934..eff0a32b1 100644 --- a/commerce_coordinator/docker_gunicorn_configuration.py +++ b/commerce_coordinator/docker_gunicorn_configuration.py @@ -1,9 +1,9 @@ """ gunicorn configuration file, see https://docs.gunicorn.org/en/develop/configure.html for more info. """ -import logging import multiprocessing # pylint: disable=unused-import import os +import logging # Use the specific gunicorn error logger logger = logging.getLogger("gunicorn.error") @@ -16,35 +16,33 @@ # StatsD / DogStatsD configuration +# Gunicorn's statsd_host validator (validate_statsd_address) accepts: +# "HOST:PORT" -> Gunicorn parses into (host, port) tuple -> AF_INET UDP +# "unix://PATH" -> Gunicorn parses into a bare string path -> AF_UNIX SOCK_DGRAM _dogstatsd_url = os.environ.get("DD_DOGSTATSD_URL", "").strip() -statsd_host = None if _dogstatsd_url: - # 1. Handle Unix Domain Sockets (requires 'unix:' or 'unixpack:' prefix for Gunicorn) - if _dogstatsd_url.startswith("unix://"): - path = _dogstatsd_url[len("unix://"):] - if path: - statsd_host = f"unix:{path}" - - elif _dogstatsd_url.startswith("unixpack://"): - path = _dogstatsd_url[len("unixpack://"):] - if path: - statsd_host = f"unixpack:{path}" - - # 2. Handle UDP or standard HOST:PORT (Gunicorn expects plain "HOST:PORT") - elif _dogstatsd_url.startswith("udp://"): - statsd_host = _dogstatsd_url[len("udp://"):] - - else: - statsd_host = _dogstatsd_url - - if statsd_host: - statsd_prefix = "commerce-coordinator" - - # Log parsed statsd host on startup for verification using gunicorn.error logger - logger.info("Configured statsd_host=%s", statsd_host) + if _dogstatsd_url.startswith(("unix://", "unixgram://")): + # Normalize unixgram:// -> unix:// (Gunicorn's validator expects unix://) + _socket_path = _dogstatsd_url.split("://", 1)[1] + if _socket_path: + # Pass as a string; Gunicorn validator detects this and sets address_family = AF_UNIX + statsd_host = f"unix://{_socket_path}" + statsd_prefix = "commerce-coordinator" + logger.info("Configured statsd_host as UDS: %s", statsd_host) else: - logger.info("DogStatsD URL provided but empty, skipping configuration.") + # Strip udp:// if present; pass plain HOST:PORT string to Gunicorn + _statsd_host = ( + _dogstatsd_url[len("udp://"):] + if _dogstatsd_url.startswith("udp://") + else _dogstatsd_url + ).strip() + + if _statsd_host: + # Pass as a string; Gunicorn validator detects host:port and converts to (host, port) tuple + statsd_host = _statsd_host + statsd_prefix = "commerce-coordinator" + logger.info("Configured statsd_host as UDP: %s", statsd_host) def pre_request(worker, req): From 79d26541064d9a08e60fb6d65c827666ff24c41b Mon Sep 17 00:00:00 2001 From: Hema Shree Date: Wed, 19 Aug 2026 10:44:19 +0530 Subject: [PATCH 4/4] fix: format DD_DOGSTATSD_URL for gunicorn statsd_host --- .../docker_gunicorn_configuration.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/commerce_coordinator/docker_gunicorn_configuration.py b/commerce_coordinator/docker_gunicorn_configuration.py index eff0a32b1..efa4242ab 100644 --- a/commerce_coordinator/docker_gunicorn_configuration.py +++ b/commerce_coordinator/docker_gunicorn_configuration.py @@ -3,10 +3,6 @@ """ import multiprocessing # pylint: disable=unused-import import os -import logging - -# Use the specific gunicorn error logger -logger = logging.getLogger("gunicorn.error") preload_app = True timeout = 300 @@ -16,7 +12,7 @@ # StatsD / DogStatsD configuration -# Gunicorn's statsd_host validator (validate_statsd_address) accepts: +# Gunicorn's statsd_host validator (validate_statsd_address) accepts a STRING: # "HOST:PORT" -> Gunicorn parses into (host, port) tuple -> AF_INET UDP # "unix://PATH" -> Gunicorn parses into a bare string path -> AF_UNIX SOCK_DGRAM _dogstatsd_url = os.environ.get("DD_DOGSTATSD_URL", "").strip() @@ -25,11 +21,9 @@ if _dogstatsd_url.startswith(("unix://", "unixgram://")): # Normalize unixgram:// -> unix:// (Gunicorn's validator expects unix://) _socket_path = _dogstatsd_url.split("://", 1)[1] - if _socket_path: - # Pass as a string; Gunicorn validator detects this and sets address_family = AF_UNIX + if _socket_path: # guard against bare "unix://" with no path statsd_host = f"unix://{_socket_path}" statsd_prefix = "commerce-coordinator" - logger.info("Configured statsd_host as UDS: %s", statsd_host) else: # Strip udp:// if present; pass plain HOST:PORT string to Gunicorn _statsd_host = ( @@ -39,10 +33,8 @@ ).strip() if _statsd_host: - # Pass as a string; Gunicorn validator detects host:port and converts to (host, port) tuple statsd_host = _statsd_host statsd_prefix = "commerce-coordinator" - logger.info("Configured statsd_host as UDP: %s", statsd_host) def pre_request(worker, req):