|
3 | 3 | from datetime import datetime, timedelta, timezone
|
4 | 4 |
|
5 | 5 | from opentelemetry import trace as otel_trace, context
|
6 |
| -from opentelemetry.sdk.trace import ReadableSpan |
| 6 | +from opentelemetry.trace.status import StatusCode |
7 | 7 |
|
8 | 8 | import sentry_sdk
|
9 | 9 | from sentry_sdk.consts import INSTRUMENTER, SPANDATA
|
@@ -153,6 +153,8 @@ class TransactionKwargs(SpanKwargs, total=False):
|
153 | 153 | "url": TRANSACTION_SOURCE_ROUTE,
|
154 | 154 | }
|
155 | 155 |
|
| 156 | +tracer = otel_trace.get_tracer(__name__) |
| 157 | + |
156 | 158 |
|
157 | 159 | class _SpanRecorder:
|
158 | 160 | """Limits the number of spans recorded in a transaction."""
|
@@ -1160,32 +1162,158 @@ def _set_initial_sampling_decision(self, sampling_context):
|
1160 | 1162 | pass
|
1161 | 1163 |
|
1162 | 1164 |
|
1163 |
| -class OTelSpanWrapper: |
| 1165 | +class POTelSpan: |
1164 | 1166 | """
|
1165 |
| - Light-weight OTel span wrapper. |
1166 |
| -
|
1167 |
| - Meant for providing some level of compatibility with the old span interface. |
| 1167 | + OTel span wrapper providing compatibility with the old span interface. |
1168 | 1168 | """
|
1169 | 1169 |
|
1170 |
| - def __init__(self, otel_span=None, **kwargs): |
1171 |
| - # type: (Optional[ReadableSpan]) -> None |
1172 |
| - self.description = kwargs.get("description") |
1173 |
| - self._otel_span = otel_span |
| 1170 | + # XXX Maybe it makes sense to repurpose the existing Span class for this. |
| 1171 | + # For now I'm keeping this class separate to have a clean slate. |
| 1172 | + |
| 1173 | + # XXX The wrapper itself should have as little state as possible. |
| 1174 | + |
| 1175 | + def __init__( |
| 1176 | + self, |
| 1177 | + active=True, # type: bool |
| 1178 | + trace_id=None, # type: Optional[str] |
| 1179 | + span_id=None, # type: Optional[str] |
| 1180 | + parent_span_id=None, # type: Optional[str] |
| 1181 | + same_process_as_parent=True, # type: bool |
| 1182 | + sampled=None, # type: Optional[bool] |
| 1183 | + op=None, # type: Optional[str] |
| 1184 | + description=None, # type: Optional[str] |
| 1185 | + status=None, # type: Optional[str] |
| 1186 | + containing_transaction=None, # type: Optional[Transaction] |
| 1187 | + start_timestamp=None, # type: Optional[Union[datetime, float]] |
| 1188 | + scope=None, # type: Optional[sentry_sdk.Scope] |
| 1189 | + origin="manual", # type: str |
| 1190 | + ): |
| 1191 | + # type: (...) -> None |
| 1192 | + self._otel_span = tracer.start_span(description or "") |
| 1193 | + self._active = active |
| 1194 | + # XXX |
1174 | 1195 |
|
1175 | 1196 | def __enter__(self):
|
1176 |
| - # type: () -> OTelSpanWrapper |
1177 |
| - # Creates a Context object with parent set as current span |
1178 |
| - ctx = otel_trace.set_span_in_context(self._otel_span) |
1179 |
| - # Set as the implicit current context |
1180 |
| - self._ctx_token = context.attach(ctx) |
| 1197 | + # type: () -> POTelSpan |
| 1198 | + # create a Context object with parent set as current span |
| 1199 | + if self._active: |
| 1200 | + ctx = otel_trace.set_span_in_context(self._otel_span) |
| 1201 | + # set as the implicit current context |
| 1202 | + self._ctx_token = context.attach(ctx) |
| 1203 | + |
1181 | 1204 | return self
|
1182 | 1205 |
|
1183 | 1206 | def __exit__(self, ty, value, tb):
|
1184 | 1207 | # type: (Optional[Any], Optional[Any], Optional[Any]) -> None
|
1185 | 1208 | self._otel_span.end()
|
1186 |
| - context.detach(self._ctx_token) |
| 1209 | + |
| 1210 | + if self._active: |
| 1211 | + context.detach(self._ctx_token) |
| 1212 | + |
| 1213 | + @property |
| 1214 | + def containing_transaction(self): |
| 1215 | + # type: () -> Optional[Transaction] |
| 1216 | + pass |
1187 | 1217 |
|
1188 | 1218 | def start_child(self, **kwargs):
|
| 1219 | + # type: (str, **Any) -> POTelSpan |
| 1220 | + pass |
| 1221 | + |
| 1222 | + @classmethod |
| 1223 | + def continue_from_environ( |
| 1224 | + cls, |
| 1225 | + environ, # type: Mapping[str, str] |
| 1226 | + **kwargs, # type: Any |
| 1227 | + ): |
| 1228 | + # type: (...) -> POTelSpan |
| 1229 | + pass |
| 1230 | + |
| 1231 | + @classmethod |
| 1232 | + def continue_from_headers( |
| 1233 | + cls, |
| 1234 | + headers, # type: Mapping[str, str] |
| 1235 | + **kwargs, # type: Any |
| 1236 | + ): |
| 1237 | + # type: (...) -> POTelSpan |
| 1238 | + pass |
| 1239 | + |
| 1240 | + def iter_headers(self): |
| 1241 | + # type: () -> Iterator[Tuple[str, str]] |
| 1242 | + pass |
| 1243 | + |
| 1244 | + @classmethod |
| 1245 | + def from_traceparent( |
| 1246 | + cls, |
| 1247 | + traceparent, # type: Optional[str] |
| 1248 | + **kwargs, # type: Any |
| 1249 | + ): |
| 1250 | + # type: (...) -> Optional[Transaction] |
| 1251 | + pass |
| 1252 | + |
| 1253 | + def to_traceparent(self): |
| 1254 | + # type: () -> str |
| 1255 | + pass |
| 1256 | + |
| 1257 | + def to_baggage(self): |
| 1258 | + # type: () -> Optional[Baggage] |
| 1259 | + pass |
| 1260 | + |
| 1261 | + def set_tag(self, key, value): |
| 1262 | + # type: (str, Any) -> None |
| 1263 | + pass |
| 1264 | + |
| 1265 | + def set_data(self, key, value): |
| 1266 | + # type: (str, Any) -> None |
| 1267 | + pass |
| 1268 | + |
| 1269 | + def set_status(self, status): |
| 1270 | + # type: (str) -> None |
| 1271 | + pass |
| 1272 | + |
| 1273 | + def set_measurement(self, name, value, unit=""): |
| 1274 | + # type: (str, float, MeasurementUnit) -> None |
| 1275 | + pass |
| 1276 | + |
| 1277 | + def set_thread(self, thread_id, thread_name): |
| 1278 | + # type: (Optional[int], Optional[str]) -> None |
| 1279 | + pass |
| 1280 | + |
| 1281 | + def set_profiler_id(self, profiler_id): |
| 1282 | + # type: (Optional[str]) -> None |
| 1283 | + pass |
| 1284 | + |
| 1285 | + def set_http_status(self, http_status): |
| 1286 | + # type: (int) -> None |
| 1287 | + pass |
| 1288 | + |
| 1289 | + def is_success(self): |
| 1290 | + # type: () -> bool |
| 1291 | + return self._otel_span.status.code == StatusCode.OK |
| 1292 | + |
| 1293 | + def finish(self, scope=None, end_timestamp=None): |
| 1294 | + # type: (Optional[sentry_sdk.Scope], Optional[Union[float, datetime]]) -> Optional[str] |
| 1295 | + pass |
| 1296 | + |
| 1297 | + def to_json(self): |
| 1298 | + # type: () -> dict[str, Any] |
| 1299 | + pass |
| 1300 | + |
| 1301 | + def get_trace_context(self): |
| 1302 | + # type: () -> Any |
| 1303 | + pass |
| 1304 | + |
| 1305 | + def get_profile_context(self): |
| 1306 | + # type: () -> Optional[ProfileContext] |
| 1307 | + pass |
| 1308 | + |
| 1309 | + # transaction/root span methods |
| 1310 | + |
| 1311 | + def set_context(self, key, value): |
| 1312 | + # type: (str, Any) -> None |
| 1313 | + pass |
| 1314 | + |
| 1315 | + def get_baggage(self): |
| 1316 | + # type: () -> Baggage |
1189 | 1317 | pass
|
1190 | 1318 |
|
1191 | 1319 |
|
@@ -1232,18 +1360,16 @@ async def my_async_function():
|
1232 | 1360 |
|
1233 | 1361 |
|
1234 | 1362 | def start_span(**kwargs):
|
1235 |
| - otel_span = otel_trace.get_tracer(__name__).start_span() |
1236 |
| - span = OTelSpanWrapper(otel_span=otel_span, **kwargs) |
1237 |
| - return span |
| 1363 | + return POTelSpan(active=True, **kwargs) |
1238 | 1364 |
|
1239 | 1365 |
|
1240 | 1366 | def start_inactive_span(**kwargs):
|
1241 |
| - pass |
| 1367 | + return POTelSpan(active=False, **kwargs) |
1242 | 1368 |
|
1243 | 1369 |
|
1244 | 1370 | def start_transaction(**kwargs):
|
1245 | 1371 | # XXX force_transaction?
|
1246 |
| - pass |
| 1372 | + return POTelSpan(active=True, **kwargs) |
1247 | 1373 |
|
1248 | 1374 |
|
1249 | 1375 | # Circular imports
|
|
0 commit comments