Line data Source code
1 : #pragma once 2 : 3 : #include <string> 4 : 5 : #include "envoy/common/platform.h" 6 : #include "envoy/config/core/v3/base.pb.h" 7 : #include "envoy/local_info/local_info.h" 8 : #include "envoy/runtime/runtime.h" 9 : #include "envoy/tracing/tracer.h" 10 : 11 : #include "source/common/formatter/substitution_formatter.h" 12 : #include "source/common/http/header_map_impl.h" 13 : #include "source/common/tracing/common_values.h" 14 : #include "source/common/tracing/null_span_impl.h" 15 : #include "source/common/tracing/tracer_impl.h" 16 : 17 : namespace Envoy { 18 : namespace Tracing { 19 : 20 : template <class T> class HttpTraceContextBase : public TraceContext { 21 : public: 22 : static_assert(std::is_same<typename std::remove_const<T>::type, Http::RequestHeaderMap>::value, 23 : "T must be Http::RequestHeaderMap or const Http::RequestHeaderMap"); 24 : 25 251 : HttpTraceContextBase(T& request_headers) : request_headers_(request_headers) {} 26 : 27 0 : absl::string_view protocol() const override { return request_headers_.getProtocolValue(); } 28 0 : absl::string_view host() const override { return request_headers_.getHostValue(); } 29 0 : absl::string_view path() const override { return request_headers_.getPathValue(); } 30 0 : absl::string_view method() const override { return request_headers_.getMethodValue(); } 31 0 : void forEach(IterateCallback callback) const override { 32 0 : request_headers_.iterate([cb = std::move(callback)](const Http::HeaderEntry& entry) { 33 0 : if (cb(entry.key().getStringView(), entry.value().getStringView())) { 34 0 : return Http::HeaderMap::Iterate::Continue; 35 0 : } 36 0 : return Http::HeaderMap::Iterate::Break; 37 0 : }); 38 0 : } 39 0 : absl::optional<absl::string_view> get(absl::string_view key) const override { 40 0 : Http::LowerCaseString lower_key{std::string(key)}; 41 0 : const auto entry = request_headers_.get(lower_key); 42 0 : if (!entry.empty()) { 43 0 : return entry[0]->value().getStringView(); 44 0 : } 45 0 : return absl::nullopt; 46 0 : } 47 0 : void set(absl::string_view, absl::string_view) override {} 48 0 : void remove(absl::string_view) override {} 49 0 : OptRef<const Http::RequestHeaderMap> requestHeaders() const override { return request_headers_; }; 50 0 : OptRef<Http::RequestHeaderMap> requestHeaders() override { return {}; }; 51 : 52 : protected: 53 : T& request_headers_; 54 : }; 55 : 56 : // Read only http trace context that could be constructed from const Http::RequestHeaderMap. 57 : // This is mainly used for custom tag extraction. 58 : using ReadOnlyHttpTraceContext = HttpTraceContextBase<const Http::RequestHeaderMap>; 59 : 60 : class HttpTraceContext : public HttpTraceContextBase<Http::RequestHeaderMap> { 61 : public: 62 : using HttpTraceContextBase::HttpTraceContextBase; 63 : 64 0 : void set(absl::string_view key, absl::string_view value) override { 65 0 : request_headers_.setCopy(Http::LowerCaseString(std::string(key)), value); 66 0 : } 67 0 : void remove(absl::string_view key) override { 68 0 : request_headers_.remove(Http::LowerCaseString(std::string(key))); 69 0 : } 70 0 : OptRef<const Http::RequestHeaderMap> requestHeaders() const override { return request_headers_; }; 71 0 : OptRef<Http::RequestHeaderMap> requestHeaders() override { return request_headers_; }; 72 : }; 73 : 74 : class HttpTracerUtility { 75 : public: 76 : /** 77 : * Adds information obtained from the downstream request headers as tags to the active span. 78 : * Then finishes the span. 79 : */ 80 : static void finalizeDownstreamSpan(Span& span, const Http::RequestHeaderMap* request_headers, 81 : const Http::ResponseHeaderMap* response_headers, 82 : const Http::ResponseTrailerMap* response_trailers, 83 : const StreamInfo::StreamInfo& stream_info, 84 : const Config& tracing_config); 85 : 86 : /** 87 : * Adds information obtained from the upstream request headers as tags to the active span. 88 : * Then finishes the span. 89 : */ 90 : static void finalizeUpstreamSpan(Span& span, const StreamInfo::StreamInfo& stream_info, 91 : const Config& tracing_config); 92 : 93 : /** 94 : * Adds tags to the current "unfinished" span when processing upstream response headers. 95 : * NOOP if headers are nullptr. 96 : */ 97 : static void onUpstreamResponseHeaders(Span& span, 98 : const Http::ResponseHeaderMap* response_headers); 99 : 100 : /** 101 : * Adds tags to the current "unfinished" span when processing upstream response trailers. 102 : * NOOP if trailers are nullptr. 103 : */ 104 : static void onUpstreamResponseTrailers(Span& span, 105 : const Http::ResponseTrailerMap* response_trailers); 106 : 107 : private: 108 : static void setCommonTags(Span& span, const StreamInfo::StreamInfo& stream_info, 109 : const Config& tracing_config); 110 : }; 111 : 112 : } // namespace Tracing 113 : } // namespace Envoy