This is an automated email from the ASF dual-hosted git repository. ash pushed a commit to branch v2-0-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 99f10224f0b468ebf08df3ef2f8d0fa0538169f4 Author: Jun <junnp...@users.noreply.github.com> AuthorDate: Fri Feb 26 22:45:56 2021 +0800 Fix statsd metrics not sending when using daemon mode (#14454) It seems that the daemonContext will close the socket of statsd. ``` return self.statsd.incr(stat, count, rate) File "/usr/local/lib/python3.8/site-packages/statsd/client/base.py", line 35, in incr self._send_stat(stat, '%s|c' % count, rate) File "/usr/local/lib/python3.8/site-packages/statsd/client/base.py", line 59, in _send_stat self._after(self._prepare(stat, value, rate)) File "/usr/local/lib/python3.8/site-packages/statsd/client/base.py", line 74, in _after self._send(data) File "/opt/airflow/airflow/stats.py", line 40, in _send self._sock.sendto(data.encode('ascii'), self._addr) OSError: [Errno 9] Bad file descriptor ``` (cherry picked from commit 0aa597e2ffd71d3587f629c0a1cb3d904e07b6e6) --- airflow/stats.py | 27 +++++++++++++++------------ tests/core/test_stats.py | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/airflow/stats.py b/airflow/stats.py index 7472647..8207220 100644 --- a/airflow/stats.py +++ b/airflow/stats.py @@ -348,25 +348,28 @@ class SafeDogStatsdLogger: class _Stats(type): + factory = None instance: Optional[StatsLogger] = None def __getattr__(cls, name): + if not cls.instance: + try: + cls.instance = cls.factory() + except (socket.gaierror, ImportError) as e: + log.error("Could not configure StatsClient: %s, using DummyStatsLogger instead.", e) + cls.instance = DummyStatsLogger() return getattr(cls.instance, name) def __init__(cls, *args, **kwargs): super().__init__(cls) - if cls.__class__.instance is None: - try: - is_datadog_enabled_defined = conf.has_option('metrics', 'statsd_datadog_enabled') - if is_datadog_enabled_defined and conf.getboolean('metrics', 'statsd_datadog_enabled'): - cls.__class__.instance = cls.get_dogstatsd_logger() - elif conf.getboolean('metrics', 'statsd_on'): - cls.__class__.instance = cls.get_statsd_logger() - else: - cls.__class__.instance = DummyStatsLogger() - except (socket.gaierror, ImportError) as e: - log.error("Could not configure StatsClient: %s, using DummyStatsLogger instead.", e) - cls.__class__.instance = DummyStatsLogger() + if cls.__class__.factory is None: + is_datadog_enabled_defined = conf.has_option('metrics', 'statsd_datadog_enabled') + if is_datadog_enabled_defined and conf.getboolean('metrics', 'statsd_datadog_enabled'): + cls.__class__.factory = cls.get_dogstatsd_logger + elif conf.getboolean('metrics', 'statsd_on'): + cls.__class__.factory = cls.get_statsd_logger + else: + cls.__class__.factory = DummyStatsLogger @classmethod def get_statsd_logger(cls): diff --git a/tests/core/test_stats.py b/tests/core/test_stats.py index 428192b..b635e62 100644 --- a/tests/core/test_stats.py +++ b/tests/core/test_stats.py @@ -136,6 +136,7 @@ class TestStats(unittest.TestCase): ), ): importlib.reload(airflow.stats) + airflow.stats.Stats.incr("dummy_key") def tearDown(self) -> None: # To avoid side-effect