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