-
Notifications
You must be signed in to change notification settings - Fork 501
Description
This issue is specific to Windows environment and using DLL libraries.
I build a simple executable which sets span exporter and creates a span. It also calls a library function that crates another span. Here is the main executable
int main(int argc, const char* argv[])
try
{
// Configure trace provider that exports to stdout
using prv_factory = trace_sdk::TracerProviderFactory;
using prc_factory = trace_sdk::SimpleSpanProcessorFactory;
using exp_factory = exporter::trace::OStreamSpanExporterFactory;
trace::Provider::SetTracerProvider(
std::shared_ptr<trace::TracerProvider>{
prv_factory::Create(prc_factory::Create(exp_factory::Create(std::cout)))
}
);
// Get provider and create a span
auto provider = trace::Provider::GetTracerProvider();
auto tracer = provider->GetTracer("try", "0.0.1");
auto span = tracer->StartSpan("main");
trace::Scope scope{tracer->WithActiveSpan(span)};
// Call library function that creates another span.
// Expecting that it will use trace provider configured above.
foo();
cout << "Done!" << endl;
}
catch(...) {}
Function foo()
defined in a DLL library does this
extern "C" EXPORT void foo()
{
auto provider = trace::Provider::GetTracerProvider();
auto tracer = provider->GetTracer("lib", "0.0.1");
auto span = tracer->StartSpan("foo");
cout << "foo DONE!" << endl;
}
When I build this code on Linux it produces the expected output with two spans, the "foo" span a child of "main" span:
~/cpp/otel-issue/build./try
foo DONE!
{
name : foo
trace_id : 79194137338009900a5afe676c2c2471
span_id : 6f26aecf124938e5
tracestate : parent_span_id: 0d9ec5b22ac67a29
start : 1732718683944699646
duration : 24848
description : span kind : Internal
status : Unset
attributes : events : links : resources : service.name: unknown_service
telemetry.sdk.version: 1.17.0
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
instr-lib : lib-0.0.1
}
Done!
{
name : main
trace_id : 79194137338009900a5afe676c2c2471
span_id : 0d9ec5b22ac67a29
tracestate : parent_span_id: 0000000000000000
start : 1732718683944630175
duration : 216489
description : span kind : Internal
status : Unset
attributes : events : links : resources : service.name: unknown_service
telemetry.sdk.version: 1.17.0
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
instr-lib : try-0.0.1
}
However, if I build and run the same code on Windows the output is as follows without the "foo" span:
C:\Work\MySQL\cpp\build-internals>Release\try.exe
foo DONE!
Done!
{
name : main
trace_id : c265485eac059ec46d9d170a4f004d81
span_id : e615d927b958fde0
tracestate :
parent_span_id: 0000000000000000
start : 1732718442900722900
duration : 694400
description :
span kind : Internal
status : Unset
attributes :
events :
links :
resources :
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.17.0
service.name: unknown_service
instr-lib : try-0.0.1
}
As you can see I am testing with otel 1.17.0. My guess is that in case of Windows the connection between tracer provider configured in the main application and the one obtained inside DLL is broken. Therefore the function inside DLL gets the phony provider which ignores all traces sent to it. This is why the span from foo() is not seen in the Windows output.