jaeger.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "detail/hex.h"
  5. #include "detail/string.h"
  6. #include "opentelemetry/context/propagation/text_map_propagator.h"
  7. #include "opentelemetry/trace/context.h"
  8. #include "opentelemetry/trace/default_span.h"
  9. OPENTELEMETRY_BEGIN_NAMESPACE
  10. namespace trace
  11. {
  12. namespace propagation
  13. {
  14. static const nostd::string_view kJaegerTraceHeader = "uber-trace-id";
  15. class JaegerPropagator : public context::propagation::TextMapPropagator
  16. {
  17. public:
  18. void Inject(context::propagation::TextMapCarrier &carrier,
  19. const context::Context &context) noexcept override
  20. {
  21. SpanContext span_context = trace::GetSpan(context)->GetContext();
  22. if (!span_context.IsValid())
  23. {
  24. return;
  25. }
  26. const size_t trace_id_length = 32;
  27. const size_t span_id_length = 16;
  28. // trace-id(32):span-id(16):0:debug(2)
  29. char trace_identity[trace_id_length + span_id_length + 6];
  30. span_context.trace_id().ToLowerBase16(
  31. nostd::span<char, 2 * TraceId::kSize>{&trace_identity[0], trace_id_length});
  32. trace_identity[trace_id_length] = ':';
  33. span_context.span_id().ToLowerBase16(
  34. nostd::span<char, 2 * SpanId::kSize>{&trace_identity[trace_id_length + 1], span_id_length});
  35. trace_identity[trace_id_length + span_id_length + 1] = ':';
  36. trace_identity[trace_id_length + span_id_length + 2] = '0';
  37. trace_identity[trace_id_length + span_id_length + 3] = ':';
  38. trace_identity[trace_id_length + span_id_length + 4] = '0';
  39. trace_identity[trace_id_length + span_id_length + 5] = span_context.IsSampled() ? '1' : '0';
  40. carrier.Set(kJaegerTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
  41. }
  42. context::Context Extract(const context::propagation::TextMapCarrier &carrier,
  43. context::Context &context) noexcept override
  44. {
  45. SpanContext span_context = ExtractImpl(carrier);
  46. nostd::shared_ptr<Span> sp{new DefaultSpan(span_context)};
  47. if (span_context.IsValid())
  48. {
  49. return trace::SetSpan(context, sp);
  50. }
  51. else
  52. {
  53. return context;
  54. }
  55. }
  56. bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
  57. {
  58. return callback(kJaegerTraceHeader);
  59. }
  60. private:
  61. static constexpr uint8_t kIsSampled = 0x01;
  62. static TraceFlags GetTraceFlags(uint8_t jaeger_flags)
  63. {
  64. uint8_t sampled = jaeger_flags & kIsSampled;
  65. return TraceFlags(sampled);
  66. }
  67. static SpanContext ExtractImpl(const context::propagation::TextMapCarrier &carrier)
  68. {
  69. nostd::string_view trace_identity = carrier.Get(kJaegerTraceHeader);
  70. const size_t trace_field_count = 4;
  71. nostd::string_view trace_fields[trace_field_count];
  72. if (detail::SplitString(trace_identity, ':', trace_fields, trace_field_count) !=
  73. trace_field_count)
  74. {
  75. return SpanContext::GetInvalid();
  76. }
  77. nostd::string_view trace_id_hex = trace_fields[0];
  78. nostd::string_view span_id_hex = trace_fields[1];
  79. nostd::string_view flags_hex = trace_fields[3];
  80. if (!detail::IsValidHex(trace_id_hex) || !detail::IsValidHex(span_id_hex) ||
  81. !detail::IsValidHex(flags_hex))
  82. {
  83. return SpanContext::GetInvalid();
  84. }
  85. uint8_t trace_id[16];
  86. if (!detail::HexToBinary(trace_id_hex, trace_id, sizeof(trace_id)))
  87. {
  88. return SpanContext::GetInvalid();
  89. }
  90. uint8_t span_id[8];
  91. if (!detail::HexToBinary(span_id_hex, span_id, sizeof(span_id)))
  92. {
  93. return SpanContext::GetInvalid();
  94. }
  95. uint8_t flags;
  96. if (!detail::HexToBinary(flags_hex, &flags, sizeof(flags)))
  97. {
  98. return SpanContext::GetInvalid();
  99. }
  100. return SpanContext(TraceId(trace_id), SpanId(span_id), GetTraceFlags(flags), true);
  101. }
  102. };
  103. } // namespace propagation
  104. } // namespace trace
  105. OPENTELEMETRY_END_NAMESPACE