Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/prometheus_client/validation.py: 32%

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

69 statements  

1import os 

2import re 

3 

4METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$') 

5METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') 

6RESERVED_METRIC_LABEL_NAME_RE = re.compile(r'^__.*$') 

7 

8 

9def _init_legacy_validation() -> bool: 

10 """Retrieve name validation setting from environment.""" 

11 return os.environ.get("PROMETHEUS_LEGACY_NAME_VALIDATION", 'False').lower() in ('true', '1', 't') 

12 

13 

14_legacy_validation = _init_legacy_validation() 

15 

16 

17def get_legacy_validation() -> bool: 

18 """Return the current status of the legacy validation setting.""" 

19 global _legacy_validation 

20 return _legacy_validation 

21 

22 

23def disable_legacy_validation(): 

24 """Disable legacy name validation, instead allowing all UTF8 characters.""" 

25 global _legacy_validation 

26 _legacy_validation = False 

27 

28 

29def enable_legacy_validation(): 

30 """Enable legacy name validation instead of allowing all UTF8 characters.""" 

31 global _legacy_validation 

32 _legacy_validation = True 

33 

34 

35def _validate_metric_name(name: str) -> None: 

36 """Raises ValueError if the provided name is not a valid metric name. 

37  

38 This check uses the global legacy validation setting to determine the validation scheme. 

39 """ 

40 if not name: 

41 raise ValueError("metric name cannot be empty") 

42 global _legacy_validation 

43 if _legacy_validation: 

44 if not METRIC_NAME_RE.match(name): 

45 raise ValueError("invalid metric name " + name) 

46 try: 

47 name.encode('utf-8') 

48 except UnicodeDecodeError: 

49 raise ValueError("invalid metric name " + name) 

50 

51 

52def _is_valid_legacy_metric_name(name: str) -> bool: 

53 """Returns true if the provided metric name conforms to the legacy validation scheme.""" 

54 return METRIC_NAME_RE.match(name) is not None 

55 

56 

57def _validate_metric_label_name_token(tok: str) -> None: 

58 """Raises ValueError if a parsed label name token is invalid.  

59  

60 UTF-8 names must be quoted. 

61 """ 

62 if not tok: 

63 raise ValueError("invalid label name token " + tok) 

64 global _legacy_validation 

65 quoted = tok[0] == '"' and tok[-1] == '"' 

66 if not quoted or _legacy_validation: 

67 if not METRIC_LABEL_NAME_RE.match(tok): 

68 raise ValueError("invalid label name token " + tok) 

69 return 

70 try: 

71 tok.encode('utf-8') 

72 except UnicodeDecodeError: 

73 raise ValueError("invalid label name token " + tok) 

74 

75 

76def _validate_labelname(l): 

77 """Raises ValueError if the provided name is not a valid label name. 

78  

79 This check uses the global legacy validation setting to determine the validation scheme. 

80 """ 

81 if get_legacy_validation(): 

82 if not METRIC_LABEL_NAME_RE.match(l): 

83 raise ValueError('Invalid label metric name: ' + l) 

84 if RESERVED_METRIC_LABEL_NAME_RE.match(l): 

85 raise ValueError('Reserved label metric name: ' + l) 

86 else: 

87 try: 

88 l.encode('utf-8') 

89 except UnicodeDecodeError: 

90 raise ValueError('Invalid label metric name: ' + l) 

91 if RESERVED_METRIC_LABEL_NAME_RE.match(l): 

92 raise ValueError('Reserved label metric name: ' + l) 

93 

94 

95def _is_valid_legacy_labelname(l: str) -> bool: 

96 """Returns true if the provided label name conforms to the legacy validation scheme.""" 

97 if METRIC_LABEL_NAME_RE.match(l) is None: 

98 return False 

99 return RESERVED_METRIC_LABEL_NAME_RE.match(l) is None 

100 

101 

102def _validate_labelnames(cls, labelnames): 

103 """Raises ValueError if any of the provided names is not a valid label name. 

104  

105 This check uses the global legacy validation setting to determine the validation scheme. 

106 """ 

107 labelnames = tuple(labelnames) 

108 for l in labelnames: 

109 _validate_labelname(l) 

110 if l in cls._reserved_labelnames: 

111 raise ValueError('Reserved label methe fric name: ' + l) 

112 return labelnames 

113 

114 

115def _validate_exemplar(exemplar): 

116 """Raises ValueError if the exemplar is invalid.""" 

117 runes = 0 

118 for k, v in exemplar.items(): 

119 _validate_labelname(k) 

120 runes += len(k) 

121 runes += len(v) 

122 if runes > 128: 

123 raise ValueError('Exemplar labels have %d UTF-8 characters, exceeding the limit of 128')