Skip to content

Commit cd474fd

Browse files
committed
push
1 parent 2ae5f6a commit cd474fd

1 file changed

Lines changed: 205 additions & 0 deletions

File tree

tests/test_propagate_attributes.py

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,3 +945,208 @@ def worker_raises_exception():
945945
self.verify_span_attribute(
946946
span_after, LangfuseOtelSpanAttributes.TRACE_USER_ID, "main_user"
947947
)
948+
949+
950+
class TestPropagateAttributesCrossTracer(TestPropagateAttributesBase):
951+
"""Tests for propagate_attributes with different OpenTelemetry tracers."""
952+
953+
def test_different_tracer_spans_get_attributes(
954+
self, langfuse_client, memory_exporter, tracer_provider
955+
):
956+
"""Verify spans from different tracers get propagated attributes."""
957+
# Get a different tracer (not the Langfuse tracer)
958+
other_tracer = tracer_provider.get_tracer("other-library", "1.0.0")
959+
960+
with langfuse_client.start_as_current_span(name="langfuse-parent"):
961+
with propagate_attributes(user_id="user_123", session_id="session_abc"):
962+
# Create span with Langfuse tracer
963+
langfuse_span = langfuse_client.start_span(name="langfuse-child")
964+
langfuse_span.end()
965+
966+
# Create span with different tracer
967+
with other_tracer.start_as_current_span(name="other-library-span"):
968+
pass
969+
970+
# Verify both spans have the propagated attributes
971+
langfuse_span_data = self.get_span_by_name(memory_exporter, "langfuse-child")
972+
self.verify_span_attribute(
973+
langfuse_span_data,
974+
LangfuseOtelSpanAttributes.TRACE_USER_ID,
975+
"user_123",
976+
)
977+
self.verify_span_attribute(
978+
langfuse_span_data,
979+
LangfuseOtelSpanAttributes.TRACE_SESSION_ID,
980+
"session_abc",
981+
)
982+
983+
other_span_data = self.get_span_by_name(memory_exporter, "other-library-span")
984+
self.verify_span_attribute(
985+
other_span_data,
986+
LangfuseOtelSpanAttributes.TRACE_USER_ID,
987+
"user_123",
988+
)
989+
self.verify_span_attribute(
990+
other_span_data,
991+
LangfuseOtelSpanAttributes.TRACE_SESSION_ID,
992+
"session_abc",
993+
)
994+
995+
def test_nested_spans_from_multiple_tracers(
996+
self, langfuse_client, memory_exporter, tracer_provider
997+
):
998+
"""Verify nested spans from multiple tracers all get propagated attributes."""
999+
tracer_a = tracer_provider.get_tracer("library-a", "1.0.0")
1000+
tracer_b = tracer_provider.get_tracer("library-b", "2.0.0")
1001+
1002+
with langfuse_client.start_as_current_span(name="root"):
1003+
with propagate_attributes(
1004+
user_id="user_123", metadata={"experiment": "cross_tracer"}
1005+
):
1006+
# Create nested spans from different tracers
1007+
with tracer_a.start_as_current_span(name="library-a-span"):
1008+
with tracer_b.start_as_current_span(name="library-b-span"):
1009+
langfuse_leaf = langfuse_client.start_span(name="langfuse-leaf")
1010+
langfuse_leaf.end()
1011+
1012+
# Verify all spans have the attributes
1013+
for span_name in ["library-a-span", "library-b-span", "langfuse-leaf"]:
1014+
span_data = self.get_span_by_name(memory_exporter, span_name)
1015+
self.verify_span_attribute(
1016+
span_data,
1017+
LangfuseOtelSpanAttributes.TRACE_USER_ID,
1018+
"user_123",
1019+
)
1020+
self.verify_span_attribute(
1021+
span_data,
1022+
f"{LangfuseOtelSpanAttributes.TRACE_METADATA}.experiment",
1023+
"cross_tracer",
1024+
)
1025+
1026+
def test_other_tracer_span_before_propagate_context(
1027+
self, langfuse_client, memory_exporter, tracer_provider
1028+
):
1029+
"""Verify spans created before propagate_attributes don't get attributes."""
1030+
other_tracer = tracer_provider.get_tracer("other-library", "1.0.0")
1031+
1032+
with langfuse_client.start_as_current_span(name="root"):
1033+
# Create span BEFORE propagate_attributes
1034+
with other_tracer.start_as_current_span(name="span-before"):
1035+
pass
1036+
1037+
# NOW set attributes
1038+
with propagate_attributes(user_id="user_123"):
1039+
# Create span AFTER propagate_attributes
1040+
with other_tracer.start_as_current_span(name="span-after"):
1041+
pass
1042+
1043+
# Verify: span-before does NOT have user_id, span-after DOES
1044+
span_before = self.get_span_by_name(memory_exporter, "span-before")
1045+
self.verify_missing_attribute(
1046+
span_before, LangfuseOtelSpanAttributes.TRACE_USER_ID
1047+
)
1048+
1049+
span_after = self.get_span_by_name(memory_exporter, "span-after")
1050+
self.verify_span_attribute(
1051+
span_after, LangfuseOtelSpanAttributes.TRACE_USER_ID, "user_123"
1052+
)
1053+
1054+
def test_mixed_tracers_with_metadata(
1055+
self, langfuse_client, memory_exporter, tracer_provider
1056+
):
1057+
"""Verify metadata propagates correctly to spans from different tracers."""
1058+
other_tracer = tracer_provider.get_tracer("instrumented-library", "1.0.0")
1059+
1060+
with langfuse_client.start_as_current_span(name="main"):
1061+
with propagate_attributes(
1062+
metadata={
1063+
"env": "production",
1064+
"version": "2.0",
1065+
"feature_flag": "enabled",
1066+
}
1067+
):
1068+
# Create spans from both tracers
1069+
langfuse_span = langfuse_client.start_span(name="langfuse-operation")
1070+
langfuse_span.end()
1071+
1072+
with other_tracer.start_as_current_span(name="library-operation"):
1073+
pass
1074+
1075+
# Verify both spans have all metadata
1076+
for span_name in ["langfuse-operation", "library-operation"]:
1077+
span_data = self.get_span_by_name(memory_exporter, span_name)
1078+
self.verify_span_attribute(
1079+
span_data,
1080+
f"{LangfuseOtelSpanAttributes.TRACE_METADATA}.env",
1081+
"production",
1082+
)
1083+
self.verify_span_attribute(
1084+
span_data,
1085+
f"{LangfuseOtelSpanAttributes.TRACE_METADATA}.version",
1086+
"2.0",
1087+
)
1088+
self.verify_span_attribute(
1089+
span_data,
1090+
f"{LangfuseOtelSpanAttributes.TRACE_METADATA}.feature_flag",
1091+
"enabled",
1092+
)
1093+
1094+
def test_propagate_without_langfuse_parent(
1095+
self, langfuse_client, memory_exporter, tracer_provider
1096+
):
1097+
"""Verify propagate_attributes works even when parent span is from different tracer."""
1098+
other_tracer = tracer_provider.get_tracer("other-library", "1.0.0")
1099+
1100+
# Parent span is from different tracer
1101+
with other_tracer.start_as_current_span(name="other-parent"):
1102+
with propagate_attributes(user_id="user_123", session_id="session_xyz"):
1103+
# Create children from both tracers
1104+
with other_tracer.start_as_current_span(name="other-child"):
1105+
pass
1106+
1107+
langfuse_child = langfuse_client.start_span(name="langfuse-child")
1108+
langfuse_child.end()
1109+
1110+
# Verify all spans have attributes (including non-Langfuse parent)
1111+
for span_name in ["other-parent", "other-child", "langfuse-child"]:
1112+
span_data = self.get_span_by_name(memory_exporter, span_name)
1113+
self.verify_span_attribute(
1114+
span_data,
1115+
LangfuseOtelSpanAttributes.TRACE_USER_ID,
1116+
"user_123",
1117+
)
1118+
self.verify_span_attribute(
1119+
span_data,
1120+
LangfuseOtelSpanAttributes.TRACE_SESSION_ID,
1121+
"session_xyz",
1122+
)
1123+
1124+
def test_attributes_persist_across_tracer_changes(
1125+
self, langfuse_client, memory_exporter, tracer_provider
1126+
):
1127+
"""Verify attributes persist as execution moves between different tracers."""
1128+
tracer_1 = tracer_provider.get_tracer("library-1", "1.0.0")
1129+
tracer_2 = tracer_provider.get_tracer("library-2", "1.0.0")
1130+
tracer_3 = tracer_provider.get_tracer("library-3", "1.0.0")
1131+
1132+
with langfuse_client.start_as_current_span(name="root"):
1133+
with propagate_attributes(user_id="persistent_user"):
1134+
# Bounce between different tracers
1135+
with tracer_1.start_as_current_span(name="step-1"):
1136+
pass
1137+
1138+
with tracer_2.start_as_current_span(name="step-2"):
1139+
with tracer_3.start_as_current_span(name="step-3"):
1140+
pass
1141+
1142+
langfuse_span = langfuse_client.start_span(name="step-4")
1143+
langfuse_span.end()
1144+
1145+
# Verify all steps have the user_id
1146+
for step_name in ["step-1", "step-2", "step-3", "step-4"]:
1147+
span_data = self.get_span_by_name(memory_exporter, step_name)
1148+
self.verify_span_attribute(
1149+
span_data,
1150+
LangfuseOtelSpanAttributes.TRACE_USER_ID,
1151+
"persistent_user",
1152+
)

0 commit comments

Comments
 (0)