Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/airflow/sdk/_shared/observability/traces/base_tracer.py: 64%

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

90 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 

20from typing import TYPE_CHECKING, Any, Protocol 

21 

22import structlog 

23 

24if TYPE_CHECKING: 

25 from .. import Self 

26 

27log = structlog.getLogger(__name__) 

28 

29 

30def gen_context(trace_id, span_id): 

31 """Generate span context from trace_id and span_id.""" 

32 from .otel_tracer import gen_context as otel_gen_context 

33 

34 return otel_gen_context(trace_id, span_id) 

35 

36 

37def gen_links_from_kv_list(list): 

38 """Generate links from kv list of {trace_id:int, span_id:int}.""" 

39 from .otel_tracer import gen_links_from_kv_list 

40 

41 return gen_links_from_kv_list(list) 

42 

43 

44class EmptyContext: 

45 """If no Tracer is configured, EmptyContext is used as a fallback.""" 

46 

47 trace_id = 1 

48 span_id = 1 

49 

50 

51class EmptySpan: 

52 """If no Tracer is configured, EmptySpan is used as a fallback.""" 

53 

54 def __enter__(self) -> Self: 

55 """Enter.""" 

56 return self 

57 

58 def __exit__(self, *args, **kwargs): 

59 """Exit.""" 

60 pass 

61 

62 def __call__(self, obj): 

63 """Call.""" 

64 return obj 

65 

66 def get_span_context(self): 

67 """Get span context.""" 

68 return EMPTY_CTX 

69 

70 def set_attribute(self, key, value) -> None: 

71 """Set an attribute to the span.""" 

72 pass 

73 

74 def set_attributes(self, attributes) -> None: 

75 """Set multiple attributes at once.""" 

76 pass 

77 

78 def is_recording(self): 

79 return False 

80 

81 def add_event( 

82 self, 

83 name: str, 

84 attributes: Any | None = None, 

85 timestamp: int | None = None, 

86 ) -> None: 

87 """Add event to span.""" 

88 pass 

89 

90 def add_link( 

91 self, 

92 context: Any, 

93 attributes: Any | None = None, 

94 ) -> None: 

95 """Add link to the span.""" 

96 pass 

97 

98 def end(self, end_time=None, *args, **kwargs) -> None: 

99 """End.""" 

100 pass 

101 

102 

103EMPTY_SPAN = EmptySpan() 

104EMPTY_CTX = EmptyContext() 

105 

106 

107class Tracer(Protocol): 

108 """This class is only used for TypeChecking (for IDEs, mypy, etc).""" 

109 

110 instance: Tracer | EmptyTrace | None = None 

111 

112 @classmethod 

113 def get_tracer(cls, component): 

114 """Get a tracer.""" 

115 raise NotImplementedError() 

116 

117 @classmethod 

118 def start_span( 

119 cls, 

120 span_name: str, 

121 component: str | None = None, 

122 parent_sc=None, 

123 span_id=None, 

124 links=None, 

125 start_time=None, 

126 ): 

127 """Start a span.""" 

128 raise NotImplementedError() 

129 

130 @classmethod 

131 def use_span(cls, span): 

132 """Use a span as current.""" 

133 raise NotImplementedError() 

134 

135 @classmethod 

136 def get_current_span(self): 

137 raise NotImplementedError() 

138 

139 @classmethod 

140 def start_root_span(cls, span_name=None, component=None, start_time=None, start_as_current=True): 

141 """Start a root span.""" 

142 raise NotImplementedError() 

143 

144 @classmethod 

145 def start_child_span( 

146 cls, 

147 span_name=None, 

148 parent_context=None, 

149 component=None, 

150 links=None, 

151 start_time=None, 

152 start_as_current=True, 

153 ): 

154 """Start a child span.""" 

155 raise NotImplementedError() 

156 

157 @classmethod 

158 def inject(cls) -> dict: 

159 """Inject the current span context into a carrier and return it.""" 

160 raise NotImplementedError() 

161 

162 @classmethod 

163 def extract(cls, carrier) -> EmptyContext: 

164 """Extract the span context from a provided carrier.""" 

165 raise NotImplementedError() 

166 

167 

168class EmptyTrace: 

169 """If no Tracer is configured, EmptyTracer is used as a fallback.""" 

170 

171 @classmethod 

172 def get_tracer( 

173 cls, 

174 component: str, 

175 trace_id: int | None = None, 

176 span_id: int | None = None, 

177 ): 

178 """Get a tracer using provided node id and trace id.""" 

179 return cls 

180 

181 @classmethod 

182 def start_span( 

183 cls, 

184 span_name: str, 

185 component: str | None = None, 

186 parent_sc=None, 

187 span_id=None, 

188 links=None, 

189 start_time=None, 

190 ) -> EmptySpan: 

191 """Start a span.""" 

192 return EMPTY_SPAN 

193 

194 @classmethod 

195 def use_span(cls, span) -> EmptySpan: 

196 """Use a span as current.""" 

197 return EMPTY_SPAN 

198 

199 @classmethod 

200 def get_current_span(self) -> EmptySpan: 

201 """Get the current span.""" 

202 return EMPTY_SPAN 

203 

204 @classmethod 

205 def start_root_span( 

206 cls, span_name=None, component=None, start_time=None, start_as_current=True 

207 ) -> EmptySpan: 

208 """Start a root span.""" 

209 return EMPTY_SPAN 

210 

211 @classmethod 

212 def start_child_span( 

213 cls, 

214 span_name=None, 

215 parent_context=None, 

216 component=None, 

217 links=None, 

218 start_time=None, 

219 start_as_current=True, 

220 ) -> EmptySpan: 

221 """Start a child span.""" 

222 return EMPTY_SPAN 

223 

224 @classmethod 

225 def inject(cls): 

226 """Inject the current span context into a carrier and return it.""" 

227 return {} 

228 

229 @classmethod 

230 def extract(cls, carrier) -> EmptyContext: 

231 """Extract the span context from a provided carrier.""" 

232 return EMPTY_CTX