|
35 | 35 |
|
36 | 36 | #ifdef __linux__ |
37 | 37 | const void* elastic_apm_profiling_correlation_process_storage_v1 = nullptr; |
| 38 | +thread_local struct datadog::tracing::TLSStorage* |
| 39 | + elastic_apm_profiling_correlation_tls_v1 = nullptr; |
| 40 | +thread_local std::unique_ptr<datadog::tracing::TLSStorage> tls_info_holder = |
| 41 | + nullptr; |
38 | 42 | #endif |
39 | 43 |
|
40 | 44 | namespace datadog { |
@@ -115,6 +119,33 @@ Tracer::Tracer(const FinalizedTracerConfig& config, |
115 | 119 | store_config(); |
116 | 120 | } |
117 | 121 |
|
| 122 | +#ifdef __linux__ |
| 123 | +void Tracer::correlate(const Span& span) { |
| 124 | + // See Layout: |
| 125 | + // https://github.com/elastic/apm/blob/149cd3e39a77a58002344270ed2ad35357bdd02d/specs/agents/universal-profiling-integration.md#thread-local-storage-layout |
| 126 | + tls_info_holder = std::make_unique<datadog::tracing::TLSStorage>(); |
| 127 | + elastic_apm_profiling_correlation_tls_v1 = tls_info_holder.get(); |
| 128 | + |
| 129 | + struct TLSStorage* tls_data = elastic_apm_profiling_correlation_tls_v1; |
| 130 | + tls_data->valid = 0; |
| 131 | + |
| 132 | + tls_data->layout_minor_version = 1; |
| 133 | + tls_data->trace_present = 1; // We are in a span so no errors |
| 134 | + tls_data->trace_flags = |
| 135 | + span.trace_segment().sampling_decision().has_value() && |
| 136 | + (span.trace_segment().sampling_decision().value().priority > 0) |
| 137 | + ? 1 |
| 138 | + : 0; |
| 139 | + auto trace_id = span.trace_id(); |
| 140 | + tls_data->trace_id_low = trace_id.low; |
| 141 | + tls_data->trace_id_high = trace_id.high; |
| 142 | + tls_data->span_id = span.id(); |
| 143 | + tls_data->transaction_id = span.trace_segment().local_root_id(); |
| 144 | + |
| 145 | + tls_data->valid = 1; |
| 146 | +} |
| 147 | +#endif |
| 148 | + |
118 | 149 | std::string Tracer::config() const { |
119 | 150 | // clang-format off |
120 | 151 | auto config = nlohmann::json::object({ |
@@ -206,6 +237,11 @@ Span Tracer::create_span(const SpanConfig& config) { |
206 | 237 | Span span{span_data_ptr, segment, |
207 | 238 | [generator = generator_]() { return generator->span_id(); }, |
208 | 239 | clock_}; |
| 240 | + |
| 241 | +#ifdef __linux__ |
| 242 | + correlate(span); |
| 243 | +#endif |
| 244 | + |
209 | 245 | return span; |
210 | 246 | } |
211 | 247 |
|
@@ -417,6 +453,11 @@ Expected<Span> Tracer::extract_span(const DictReader& reader, |
417 | 453 | Span span{span_data_ptr, segment, |
418 | 454 | [generator = generator_]() { return generator->span_id(); }, |
419 | 455 | clock_}; |
| 456 | + |
| 457 | +#ifdef __linux__ |
| 458 | + correlate(span); |
| 459 | +#endif |
| 460 | + |
420 | 461 | return span; |
421 | 462 | } |
422 | 463 |
|
|
0 commit comments