Line data Source code
1 : #include "source/extensions/request_id/uuid/config.h" 2 : 3 : #include "envoy/http/header_map.h" 4 : #include "envoy/tracing/tracer.h" 5 : 6 : #include "source/common/common/random_generator.h" 7 : #include "source/common/common/utility.h" 8 : #include "source/common/stream_info/stream_id_provider_impl.h" 9 : 10 : namespace Envoy { 11 : namespace Extensions { 12 : namespace RequestId { 13 : 14 409 : void UUIDRequestIDExtension::set(Http::RequestHeaderMap& request_headers, bool force) { 15 409 : if (!force && request_headers.RequestId()) { 16 0 : return; 17 0 : } 18 : 19 : // TODO(PiotrSikora) PERF: Write UUID directly to the header map. 20 409 : std::string uuid = random_.uuid(); 21 409 : ASSERT(!uuid.empty()); 22 409 : request_headers.setRequestId(uuid); 23 409 : } 24 : 25 : void UUIDRequestIDExtension::setInResponse(Http::ResponseHeaderMap& response_headers, 26 0 : const Http::RequestHeaderMap& request_headers) { 27 0 : if (request_headers.RequestId()) { 28 0 : response_headers.setRequestId(request_headers.getRequestIdValue()); 29 0 : } 30 0 : } 31 : 32 : absl::optional<absl::string_view> 33 0 : UUIDRequestIDExtension::get(const Http::RequestHeaderMap& request_headers) const { 34 0 : if (request_headers.RequestId() == nullptr) { 35 0 : return absl::nullopt; 36 0 : } 37 0 : return request_headers.getRequestIdValue(); 38 0 : } 39 : 40 : absl::optional<uint64_t> 41 0 : UUIDRequestIDExtension::getInteger(const Http::RequestHeaderMap& request_headers) const { 42 0 : if (request_headers.RequestId() == nullptr) { 43 0 : return absl::nullopt; 44 0 : } 45 0 : const std::string uuid(request_headers.getRequestIdValue()); 46 0 : if (uuid.length() < 8) { 47 0 : return absl::nullopt; 48 0 : } 49 : 50 0 : uint64_t value; 51 0 : if (!StringUtil::atoull(uuid.substr(0, 8).c_str(), value, 16)) { 52 0 : return absl::nullopt; 53 0 : } 54 : 55 0 : return value; 56 0 : } 57 : 58 : Tracing::Reason 59 0 : UUIDRequestIDExtension::getTraceReason(const Http::RequestHeaderMap& request_headers) { 60 0 : if (request_headers.RequestId() == nullptr) { 61 0 : return Tracing::Reason::NotTraceable; 62 0 : } 63 0 : absl::string_view uuid = request_headers.getRequestIdValue(); 64 0 : if (uuid.length() != Random::RandomGeneratorImpl::UUID_LENGTH) { 65 0 : return Tracing::Reason::NotTraceable; 66 0 : } 67 : 68 0 : switch (uuid[TRACE_BYTE_POSITION]) { 69 0 : case TRACE_FORCED: 70 0 : return Tracing::Reason::ServiceForced; 71 0 : case TRACE_SAMPLED: 72 0 : return Tracing::Reason::Sampling; 73 0 : case TRACE_CLIENT: 74 0 : return Tracing::Reason::ClientForced; 75 0 : default: 76 0 : return Tracing::Reason::NotTraceable; 77 0 : } 78 0 : } 79 : 80 : void UUIDRequestIDExtension::setTraceReason(Http::RequestHeaderMap& request_headers, 81 0 : Tracing::Reason reason) { 82 0 : if (!pack_trace_reason_ || request_headers.RequestId() == nullptr) { 83 0 : return; 84 0 : } 85 0 : absl::string_view uuid_view = request_headers.getRequestIdValue(); 86 0 : if (uuid_view.length() != Random::RandomGeneratorImpl::UUID_LENGTH) { 87 0 : return; 88 0 : } 89 0 : std::string uuid(uuid_view); 90 : 91 0 : switch (reason) { 92 0 : case Tracing::Reason::ServiceForced: 93 0 : uuid[TRACE_BYTE_POSITION] = TRACE_FORCED; 94 0 : break; 95 0 : case Tracing::Reason::ClientForced: 96 0 : uuid[TRACE_BYTE_POSITION] = TRACE_CLIENT; 97 0 : break; 98 0 : case Tracing::Reason::Sampling: 99 0 : uuid[TRACE_BYTE_POSITION] = TRACE_SAMPLED; 100 0 : break; 101 0 : case Tracing::Reason::NotTraceable: 102 0 : uuid[TRACE_BYTE_POSITION] = NO_TRACE; 103 0 : break; 104 0 : default: 105 0 : break; 106 0 : } 107 0 : request_headers.setRequestId(uuid); 108 0 : } 109 : 110 : REGISTER_FACTORY(UUIDRequestIDExtensionFactory, Server::Configuration::RequestIDExtensionFactory); 111 : 112 : } // namespace RequestId 113 : } // namespace Extensions 114 : } // namespace Envoy