Line data Source code
1 : #pragma once 2 : 3 : #include <cstdint> 4 : 5 : #include "envoy/api/api.h" 6 : #include "envoy/common/optref.h" 7 : #include "envoy/config/trace/v3/opentelemetry.pb.h" 8 : #include "envoy/runtime/runtime.h" 9 : #include "envoy/thread_local/thread_local.h" 10 : #include "envoy/tracing/trace_driver.h" 11 : 12 : #include "source/common/common/logger.h" 13 : #include "source/extensions/tracers/common/factory_base.h" 14 : #include "source/extensions/tracers/opentelemetry/grpc_trace_exporter.h" 15 : #include "source/extensions/tracers/opentelemetry/resource_detectors/resource_detector.h" 16 : #include "source/extensions/tracers/opentelemetry/samplers/sampler.h" 17 : #include "source/extensions/tracers/opentelemetry/span_context.h" 18 : 19 : #include "absl/strings/escaping.h" 20 : 21 : namespace Envoy { 22 : namespace Extensions { 23 : namespace Tracers { 24 : namespace OpenTelemetry { 25 : 26 : #define OPENTELEMETRY_TRACER_STATS(COUNTER) \ 27 : COUNTER(spans_sent) \ 28 : COUNTER(timer_flushed) 29 : 30 : struct OpenTelemetryTracerStats { 31 : OPENTELEMETRY_TRACER_STATS(GENERATE_COUNTER_STRUCT) 32 : }; 33 : 34 : /** 35 : * OpenTelemetry Tracer. It is stored in TLS and contains the exporter. 36 : */ 37 : class Tracer : Logger::Loggable<Logger::Id::tracing> { 38 : public: 39 : Tracer(OpenTelemetryTraceExporterPtr exporter, Envoy::TimeSource& time_source, 40 : Random::RandomGenerator& random, Runtime::Loader& runtime, Event::Dispatcher& dispatcher, 41 : OpenTelemetryTracerStats tracing_stats, const ResourceConstSharedPtr resource, 42 : SamplerSharedPtr sampler); 43 : 44 : void sendSpan(::opentelemetry::proto::trace::v1::Span& span); 45 : 46 : Tracing::SpanPtr startSpan(const std::string& operation_name, SystemTime start_time, 47 : 48 : Tracing::Decision tracing_decision, 49 : OptRef<const Tracing::TraceContext> trace_context, 50 : OTelSpanKind span_kind); 51 : 52 : Tracing::SpanPtr startSpan(const std::string& operation_name, SystemTime start_time, 53 : const SpanContext& previous_span_context, 54 : OptRef<const Tracing::TraceContext> trace_context, 55 : OTelSpanKind span_kind); 56 : 57 : private: 58 : /** 59 : * Enables the span-flushing timer. 60 : */ 61 : void enableTimer(); 62 : /* 63 : * Removes all spans from the span buffer and sends them to the collector. 64 : */ 65 : void flushSpans(); 66 : 67 : OpenTelemetryTraceExporterPtr exporter_; 68 : Envoy::TimeSource& time_source_; 69 : Random::RandomGenerator& random_; 70 : std::vector<::opentelemetry::proto::trace::v1::Span> span_buffer_; 71 : Runtime::Loader& runtime_; 72 : Event::TimerPtr flush_timer_; 73 : OpenTelemetryTracerStats tracing_stats_; 74 : const ResourceConstSharedPtr resource_; 75 : SamplerSharedPtr sampler_; 76 : }; 77 : 78 : /** 79 : * OpenTelemetry tracing implementation of the Envoy Span object. 80 : * Note that it has a pointer to its parent Tracer to access the shared Exporter. 81 : */ 82 : class Span : Logger::Loggable<Logger::Id::tracing>, public Tracing::Span { 83 : public: 84 : Span(const std::string& name, SystemTime start_time, Envoy::TimeSource& time_source, 85 : Tracer& parent_tracer, OTelSpanKind span_kind); 86 : 87 : // Tracing::Span functions 88 0 : void setOperation(absl::string_view /*operation*/) override{}; 89 : void setTag(absl::string_view /*name*/, absl::string_view /*value*/) override; 90 0 : void log(SystemTime /*timestamp*/, const std::string& /*event*/) override{}; 91 : void finishSpan() override; 92 : void injectContext(Envoy::Tracing::TraceContext& /*trace_context*/, 93 : const Upstream::HostDescriptionConstSharedPtr&) override; 94 : Tracing::SpanPtr spawnChild(const Tracing::Config& config, const std::string& name, 95 : SystemTime start_time) override; 96 : 97 : /** 98 : * Set the span's sampled flag. 99 : */ 100 0 : void setSampled(bool sampled) override { sampled_ = sampled; }; 101 : 102 : /** 103 : * @return whether or not the sampled attribute is set 104 : */ 105 : 106 0 : bool sampled() const { return sampled_; } 107 : 108 0 : std::string getBaggage(absl::string_view /*key*/) override { return EMPTY_STRING; }; 109 0 : void setBaggage(absl::string_view /*key*/, absl::string_view /*value*/) override{}; 110 : 111 : // Additional methods 112 : 113 : /** 114 : * Sets the span's trace id attribute. 115 : */ 116 0 : void setTraceId(const absl::string_view& trace_id_hex) { 117 0 : span_.set_trace_id(absl::HexStringToBytes(trace_id_hex)); 118 0 : } 119 : 120 0 : std::string getTraceIdAsHex() const override { return absl::BytesToHexString(span_.trace_id()); }; 121 : 122 0 : OTelSpanKind spankind() const { return span_.kind(); } 123 : 124 : /** 125 : * Sets the span's id. 126 : */ 127 0 : void setId(const absl::string_view& span_id_hex) { 128 0 : span_.set_span_id(absl::HexStringToBytes(span_id_hex)); 129 0 : } 130 : 131 0 : std::string spanId() { return absl::BytesToHexString(span_.span_id()); } 132 : 133 : /** 134 : * Sets the span's parent id. 135 : */ 136 0 : void setParentId(const absl::string_view& parent_span_id_hex) { 137 0 : span_.set_parent_span_id(absl::HexStringToBytes(parent_span_id_hex)); 138 0 : } 139 : 140 0 : std::string tracestate() const { return span_.trace_state(); } 141 : 142 : /** 143 : * Sets the span's tracestate. 144 : */ 145 0 : void setTracestate(const absl::string_view& tracestate) { 146 0 : span_.set_trace_state(std::string{tracestate}); 147 0 : } 148 : 149 : /** 150 : * Method to access the span for testing. 151 : */ 152 0 : const ::opentelemetry::proto::trace::v1::Span& spanForTest() const { return span_; } 153 : 154 : private: 155 : ::opentelemetry::proto::trace::v1::Span span_; 156 : Tracer& parent_tracer_; 157 : Envoy::TimeSource& time_source_; 158 : bool sampled_; 159 : }; 160 : 161 : using TracerPtr = std::unique_ptr<Tracer>; 162 : 163 : } // namespace OpenTelemetry 164 : } // namespace Tracers 165 : } // namespace Extensions 166 : } // namespace Envoy