松开 opentelemetry span 的 parentid
Looses parentid of opentelemetry span
如果我将 span 发送到另一个线程并等待它完成,如何手动设置 parentID?案例是我不想在委托人下并行进行 2 个休息调用,当我传递跨度时,出于某种原因我失去了 parentID。
示例代码:
tracer_provider = TracerProvider()
console_span_processor = SimpleSpanProcessor(ConsoleSpanExporter())
tracer_provider.add_span_processor(console_span_processor)
trace.set_tracer_provider(tracer_provider)
class SubMethod(Thread):
def __init__(self, event: Event, name: str):
super().__init__()
self.event = event
self.name = name
self.parent = None
self.done = Event()
def run(self) -> None:
self.done.clear()
while True:
self.event.wait()
self.sub_method(self.parent, self.name)
self.parent = None
self.done.set()
self.done.clear()
def done_event(self):
return self.done
def set_parent(self, parent: Span):
self.parent = parent
def sub_method(self, span: Span, name: str):
with trace.get_tracer("Sub").start_as_current_span(name, links=[Link(span.get_span_context())]) as child:
sleep(1)
with trace.get_tracer("Sub").start_as_current_span(name + "->A", links=[Link(child.get_span_context())]) as sub_child:
sleep(1)
sub_child.set_attribute("asd", "asd")
def test_trace_with_methods():
event = Event()
event.clear()
sub1 = SubMethod(event, "A->A")
sub2 = SubMethod(event, "A->B")
sub1.start()
sub2.start()
with trace.get_tracer("Test").start_as_current_span("A") as parent:
sleep(1)
sub1.set_parent(parent)
sub2.set_parent(parent)
event.set()
event.clear()
sub1.done_event().wait()
sub2.done_event().wait()
控制台输出:
tests/test_utils.py {
"name": "A->A->A",
"context": {
"trace_id": "0x9c407a3651c194c0fbfb85b5927017a0",
"span_id": "0x205bca6e22f611ef",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x8e35e5c37299be5a",
"start_time": "2022-04-22T12:39:42.520765Z",
"end_time": "2022-04-22T12:39:43.527002Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"asd": "asd"
},
"events": [],
"links": [
{
"context": {
"trace_id": "0x9c407a3651c194c0fbfb85b5927017a0",
"span_id": "0x8e35e5c37299be5a",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A->A",
"context": {
"trace_id": "0x9c407a3651c194c0fbfb85b5927017a0",
"span_id": "0x8e35e5c37299be5a",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-04-22T12:39:41.514560Z",
"end_time": "2022-04-22T12:39:43.529754Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [
{
"context": {
"trace_id": "0x7e78052411918b921aa25a95aab601c3",
"span_id": "0x3b585aa12caa8e08",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A->B->A",
"context": {
"trace_id": "0x3623444de52074132ed1ec996cc94fbf",
"span_id": "0xd0042794d8fc3471",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x415dfe16a6278f4e",
"start_time": "2022-04-22T12:39:42.521046Z",
"end_time": "2022-04-22T12:39:43.529371Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"asd": "asd"
},
"events": [],
"links": [
{
"context": {
"trace_id": "0x3623444de52074132ed1ec996cc94fbf",
"span_id": "0x415dfe16a6278f4e",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A->B",
"context": {
"trace_id": "0x3623444de52074132ed1ec996cc94fbf",
"span_id": "0x415dfe16a6278f4e",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-04-22T12:39:41.516332Z",
"end_time": "2022-04-22T12:39:43.530239Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [
{
"context": {
"trace_id": "0x7e78052411918b921aa25a95aab601c3",
"span_id": "0x3b585aa12caa8e08",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A",
"context": {
"trace_id": "0x7e78052411918b921aa25a95aab601c3",
"span_id": "0x3b585aa12caa8e08",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-04-22T12:39:40.508204Z",
"end_time": "2022-04-22T12:39:43.531210Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
我确实在等待 subspans 完成,所以我看不到在这里断开父级连接的理由。
您应该使用 set_span_in_context
并在您的子 span 中传递返回的上下文。
...
from opentelemetry.trace.propagation import set_span_in_context
...
class SubMethod(Thread):
...
def sub_method(self, span: Span, name: str):
ctx = set_span_in_context(span)
with trace.get_tracer("Sub").start_as_current_span(name, ctx) as child:
...
如果我将 span 发送到另一个线程并等待它完成,如何手动设置 parentID?案例是我不想在委托人下并行进行 2 个休息调用,当我传递跨度时,出于某种原因我失去了 parentID。
示例代码:
tracer_provider = TracerProvider()
console_span_processor = SimpleSpanProcessor(ConsoleSpanExporter())
tracer_provider.add_span_processor(console_span_processor)
trace.set_tracer_provider(tracer_provider)
class SubMethod(Thread):
def __init__(self, event: Event, name: str):
super().__init__()
self.event = event
self.name = name
self.parent = None
self.done = Event()
def run(self) -> None:
self.done.clear()
while True:
self.event.wait()
self.sub_method(self.parent, self.name)
self.parent = None
self.done.set()
self.done.clear()
def done_event(self):
return self.done
def set_parent(self, parent: Span):
self.parent = parent
def sub_method(self, span: Span, name: str):
with trace.get_tracer("Sub").start_as_current_span(name, links=[Link(span.get_span_context())]) as child:
sleep(1)
with trace.get_tracer("Sub").start_as_current_span(name + "->A", links=[Link(child.get_span_context())]) as sub_child:
sleep(1)
sub_child.set_attribute("asd", "asd")
def test_trace_with_methods():
event = Event()
event.clear()
sub1 = SubMethod(event, "A->A")
sub2 = SubMethod(event, "A->B")
sub1.start()
sub2.start()
with trace.get_tracer("Test").start_as_current_span("A") as parent:
sleep(1)
sub1.set_parent(parent)
sub2.set_parent(parent)
event.set()
event.clear()
sub1.done_event().wait()
sub2.done_event().wait()
控制台输出:
tests/test_utils.py {
"name": "A->A->A",
"context": {
"trace_id": "0x9c407a3651c194c0fbfb85b5927017a0",
"span_id": "0x205bca6e22f611ef",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x8e35e5c37299be5a",
"start_time": "2022-04-22T12:39:42.520765Z",
"end_time": "2022-04-22T12:39:43.527002Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"asd": "asd"
},
"events": [],
"links": [
{
"context": {
"trace_id": "0x9c407a3651c194c0fbfb85b5927017a0",
"span_id": "0x8e35e5c37299be5a",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A->A",
"context": {
"trace_id": "0x9c407a3651c194c0fbfb85b5927017a0",
"span_id": "0x8e35e5c37299be5a",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-04-22T12:39:41.514560Z",
"end_time": "2022-04-22T12:39:43.529754Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [
{
"context": {
"trace_id": "0x7e78052411918b921aa25a95aab601c3",
"span_id": "0x3b585aa12caa8e08",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A->B->A",
"context": {
"trace_id": "0x3623444de52074132ed1ec996cc94fbf",
"span_id": "0xd0042794d8fc3471",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x415dfe16a6278f4e",
"start_time": "2022-04-22T12:39:42.521046Z",
"end_time": "2022-04-22T12:39:43.529371Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"asd": "asd"
},
"events": [],
"links": [
{
"context": {
"trace_id": "0x3623444de52074132ed1ec996cc94fbf",
"span_id": "0x415dfe16a6278f4e",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A->B",
"context": {
"trace_id": "0x3623444de52074132ed1ec996cc94fbf",
"span_id": "0x415dfe16a6278f4e",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-04-22T12:39:41.516332Z",
"end_time": "2022-04-22T12:39:43.530239Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [
{
"context": {
"trace_id": "0x7e78052411918b921aa25a95aab601c3",
"span_id": "0x3b585aa12caa8e08",
"trace_state": "[]"
},
"attributes": {}
}
],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
{
"name": "A",
"context": {
"trace_id": "0x7e78052411918b921aa25a95aab601c3",
"span_id": "0x3b585aa12caa8e08",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-04-22T12:39:40.508204Z",
"end_time": "2022-04-22T12:39:43.531210Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.1",
"service.name": "unknown_service"
}
}
我确实在等待 subspans 完成,所以我看不到在这里断开父级连接的理由。
您应该使用 set_span_in_context
并在您的子 span 中传递返回的上下文。
...
from opentelemetry.trace.propagation import set_span_in_context
...
class SubMethod(Thread):
...
def sub_method(self, span: Span, name: str):
ctx = set_span_in_context(span)
with trace.get_tracer("Sub").start_as_current_span(name, ctx) as child:
...