Line data Source code
1 : #include "source/common/tracing/tracer_impl.h" 2 : 3 : #include "envoy/upstream/upstream.h" 4 : 5 : #include "source/common/stream_info/utility.h" 6 : 7 : #include "absl/strings/str_cat.h" 8 : 9 : namespace Envoy { 10 : namespace Tracing { 11 : 12 : namespace { 13 : 14 0 : static void annotateVerbose(Span& span, const StreamInfo::StreamInfo& stream_info) { 15 0 : const auto start_time = stream_info.startTime(); 16 0 : StreamInfo::TimingUtility timing(stream_info); 17 0 : if (timing.lastDownstreamRxByteReceived()) { 18 0 : span.log(start_time + std::chrono::duration_cast<SystemTime::duration>( 19 0 : *timing.lastDownstreamRxByteReceived()), 20 0 : Tracing::Logs::get().LastDownstreamRxByteReceived); 21 0 : } 22 0 : if (timing.firstUpstreamTxByteSent()) { 23 0 : span.log(start_time + std::chrono::duration_cast<SystemTime::duration>( 24 0 : *timing.firstUpstreamTxByteSent()), 25 0 : Tracing::Logs::get().FirstUpstreamTxByteSent); 26 0 : } 27 0 : if (timing.lastUpstreamTxByteSent()) { 28 0 : span.log(start_time + 29 0 : std::chrono::duration_cast<SystemTime::duration>(*timing.lastUpstreamTxByteSent()), 30 0 : Tracing::Logs::get().LastUpstreamTxByteSent); 31 0 : } 32 0 : if (timing.firstUpstreamRxByteReceived()) { 33 0 : span.log(start_time + std::chrono::duration_cast<SystemTime::duration>( 34 0 : *timing.firstUpstreamRxByteReceived()), 35 0 : Tracing::Logs::get().FirstUpstreamRxByteReceived); 36 0 : } 37 0 : if (timing.lastUpstreamRxByteReceived()) { 38 0 : span.log(start_time + std::chrono::duration_cast<SystemTime::duration>( 39 0 : *timing.lastUpstreamRxByteReceived()), 40 0 : Tracing::Logs::get().LastUpstreamRxByteReceived); 41 0 : } 42 0 : if (timing.firstDownstreamTxByteSent()) { 43 0 : span.log(start_time + std::chrono::duration_cast<SystemTime::duration>( 44 0 : *timing.firstDownstreamTxByteSent()), 45 0 : Tracing::Logs::get().FirstDownstreamTxByteSent); 46 0 : } 47 0 : if (timing.lastDownstreamTxByteSent()) { 48 0 : span.log(start_time + std::chrono::duration_cast<SystemTime::duration>( 49 0 : *timing.lastDownstreamTxByteSent()), 50 0 : Tracing::Logs::get().LastDownstreamTxByteSent); 51 0 : } 52 0 : } 53 : 54 : } // namespace 55 : 56 : const std::string TracerUtility::IngressOperation = "ingress"; 57 : const std::string TracerUtility::EgressOperation = "egress"; 58 : 59 0 : const std::string& TracerUtility::toString(OperationName operation_name) { 60 0 : switch (operation_name) { 61 0 : case OperationName::Ingress: 62 0 : return IngressOperation; 63 0 : case OperationName::Egress: 64 0 : return EgressOperation; 65 0 : } 66 : 67 0 : return EMPTY_STRING; // Make the compiler happy. 68 0 : } 69 : 70 0 : Decision TracerUtility::shouldTraceRequest(const StreamInfo::StreamInfo& stream_info) { 71 : // Exclude health check requests immediately. 72 0 : if (stream_info.healthCheck()) { 73 0 : return {Reason::HealthCheck, false}; 74 0 : } 75 : 76 0 : const Tracing::Reason trace_reason = stream_info.traceReason(); 77 0 : switch (trace_reason) { 78 0 : case Reason::ClientForced: 79 0 : case Reason::ServiceForced: 80 0 : case Reason::Sampling: 81 0 : return {trace_reason, true}; 82 0 : default: 83 0 : return {trace_reason, false}; 84 0 : } 85 0 : } 86 : 87 : void TracerUtility::finalizeSpan(Span& span, const TraceContext& trace_context, 88 : const StreamInfo::StreamInfo& stream_info, 89 0 : const Config& tracing_config, bool upstream_span) { 90 0 : span.setTag(Tracing::Tags::get().Component, Tracing::Tags::get().Proxy); 91 : 92 : // Response flag. 93 0 : span.setTag(Tracing::Tags::get().ResponseFlags, 94 0 : StreamInfo::ResponseFlagUtils::toShortString(stream_info)); 95 : 96 : // Downstream info. 97 0 : if (!upstream_span) { 98 0 : const auto& remote_address = stream_info.downstreamAddressProvider().directRemoteAddress(); 99 0 : span.setTag(Tracing::Tags::get().PeerAddress, remote_address->asStringView()); 100 0 : } 101 : 102 : // Cluster info. 103 0 : if (auto cluster_info = stream_info.upstreamClusterInfo(); 104 0 : cluster_info.has_value() && cluster_info.value() != nullptr) { 105 0 : span.setTag(Tracing::Tags::get().UpstreamCluster, cluster_info.value()->name()); 106 0 : span.setTag(Tracing::Tags::get().UpstreamClusterName, 107 0 : cluster_info.value()->observabilityName()); 108 0 : } 109 : 110 : // Upstream info. 111 0 : if (stream_info.upstreamInfo() && stream_info.upstreamInfo()->upstreamHost()) { 112 0 : auto upstream_address = stream_info.upstreamInfo()->upstreamHost()->address(); 113 : 114 0 : span.setTag(Tracing::Tags::get().UpstreamAddress, upstream_address->asStringView()); 115 : 116 : // Upstream address would be 'peer.address' in the case of an upstream span. 117 0 : if (upstream_span) { 118 0 : span.setTag(Tracing::Tags::get().PeerAddress, upstream_address->asStringView()); 119 0 : } 120 0 : } 121 : 122 : // Verbose timing log. 123 0 : if (tracing_config.verbose()) { 124 0 : annotateVerbose(span, stream_info); 125 0 : } 126 : 127 : // Custom tag from configuration. 128 0 : CustomTagContext ctx{trace_context, stream_info}; 129 0 : if (const CustomTagMap* custom_tag_map = tracing_config.customTags(); custom_tag_map) { 130 0 : for (const auto& it : *custom_tag_map) { 131 0 : it.second->applySpan(span, ctx); 132 0 : } 133 0 : } 134 : 135 : // Finish the span. 136 0 : span.finishSpan(); 137 0 : } 138 : 139 : TracerImpl::TracerImpl(DriverSharedPtr driver, const LocalInfo::LocalInfo& local_info) 140 0 : : driver_(std::move(driver)), local_info_(local_info) {} 141 : 142 : SpanPtr TracerImpl::startSpan(const Config& config, TraceContext& trace_context, 143 : const StreamInfo::StreamInfo& stream_info, 144 0 : const Tracing::Decision tracing_decision) { 145 0 : std::string span_name = TracerUtility::toString(config.operationName()); 146 : 147 0 : if (config.operationName() == OperationName::Egress) { 148 0 : span_name.append(" "); 149 0 : span_name.append(std::string(trace_context.host())); 150 0 : } 151 : 152 0 : SpanPtr active_span = 153 0 : driver_->startSpan(config, trace_context, stream_info, span_name, tracing_decision); 154 : 155 : // Set tags related to the local environment 156 0 : if (active_span) { 157 0 : active_span->setTag(Tracing::Tags::get().NodeId, local_info_.nodeName()); 158 0 : active_span->setTag(Tracing::Tags::get().Zone, local_info_.zoneName()); 159 0 : } 160 : 161 0 : return active_span; 162 0 : } 163 : 164 : } // namespace Tracing 165 : } // namespace Envoy