Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/airflow/stats.py: 65%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

43 statements  

1# 

2# Licensed to the Apache Software Foundation (ASF) under one 

3# or more contributor license agreements. See the NOTICE file 

4# distributed with this work for additional information 

5# regarding copyright ownership. The ASF licenses this file 

6# to you under the Apache License, Version 2.0 (the 

7# "License"); you may not use this file except in compliance 

8# with the License. You may obtain a copy of the License at 

9# 

10# http://www.apache.org/licenses/LICENSE-2.0 

11# 

12# Unless required by applicable law or agreed to in writing, 

13# software distributed under the License is distributed on an 

14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 

15# KIND, either express or implied. See the License for the 

16# specific language governing permissions and limitations 

17# under the License. 

18from __future__ import annotations 

19 

20import logging 

21import socket 

22from typing import TYPE_CHECKING, Callable 

23 

24from airflow.configuration import conf 

25from airflow.metrics.base_stats_logger import NoStatsLogger 

26 

27if TYPE_CHECKING: 

28 from airflow.metrics.base_stats_logger import StatsLogger 

29 

30log = logging.getLogger(__name__) 

31 

32 

33class _Stats(type): 

34 factory: Callable 

35 instance: StatsLogger | NoStatsLogger | None = None 

36 

37 def __getattr__(cls, name: str) -> str: 

38 if not cls.instance: 

39 try: 

40 cls.instance = cls.factory() 

41 except (socket.gaierror, ImportError) as e: 

42 log.error("Could not configure StatsClient: %s, using NoStatsLogger instead.", e) 

43 cls.instance = NoStatsLogger() 

44 return getattr(cls.instance, name) 

45 

46 def __init__(cls, *args, **kwargs) -> None: 

47 super().__init__(cls) 

48 if not hasattr(cls.__class__, "factory"): 

49 is_datadog_enabled_defined = conf.has_option("metrics", "statsd_datadog_enabled") 

50 if is_datadog_enabled_defined and conf.getboolean("metrics", "statsd_datadog_enabled"): 

51 from airflow.metrics import datadog_logger 

52 

53 cls.__class__.factory = datadog_logger.get_dogstatsd_logger 

54 elif conf.getboolean("metrics", "statsd_on"): 

55 from airflow.metrics import statsd_logger 

56 

57 cls.__class__.factory = statsd_logger.get_statsd_logger 

58 elif conf.getboolean("metrics", "otel_on"): 

59 from airflow.metrics import otel_logger 

60 

61 cls.__class__.factory = otel_logger.get_otel_logger 

62 else: 

63 cls.__class__.factory = NoStatsLogger 

64 

65 @classmethod 

66 def get_constant_tags(cls) -> list[str]: 

67 """Get constant DataDog tags to add to all stats.""" 

68 tags_in_string = conf.get("metrics", "statsd_datadog_tags", fallback=None) 

69 if not tags_in_string: 

70 return [] 

71 return tags_in_string.split(",") 

72 

73 

74if TYPE_CHECKING: 

75 Stats: StatsLogger 

76else: 

77 

78 class Stats(metaclass=_Stats): 

79 """Empty class for Stats - we use metaclass to inject the right one."""