Line data Source code
1 : #pragma once
2 :
3 : #include <chrono>
4 : #include <cstdint>
5 : #include <string>
6 :
7 : #include "envoy/common/pure.h"
8 : #include "envoy/common/time.h"
9 : #include "envoy/config/core/v3/base.pb.h"
10 : #include "envoy/http/header_map.h"
11 : #include "envoy/http/protocol.h"
12 : #include "envoy/network/socket.h"
13 : #include "envoy/ssl/connection.h"
14 : #include "envoy/stream_info/filter_state.h"
15 : #include "envoy/stream_info/stream_id_provider.h"
16 : #include "envoy/tracing/trace_reason.h"
17 : #include "envoy/upstream/host_description.h"
18 :
19 : #include "source/common/common/assert.h"
20 : #include "source/common/protobuf/protobuf.h"
21 : #include "source/common/singleton/const_singleton.h"
22 :
23 : #include "absl/types/optional.h"
24 :
25 : namespace Envoy {
26 :
27 : namespace Router {
28 : class Route;
29 : using RouteConstSharedPtr = std::shared_ptr<const Route>;
30 : } // namespace Router
31 :
32 : namespace Upstream {
33 : class ClusterInfo;
34 : using ClusterInfoConstSharedPtr = std::shared_ptr<const ClusterInfo>;
35 : } // namespace Upstream
36 :
37 : namespace StreamInfo {
38 :
39 : enum ResponseFlag {
40 : // Local server healthcheck failed.
41 : FailedLocalHealthCheck = 0x1,
42 : // No healthy upstream.
43 : NoHealthyUpstream = 0x2,
44 : // Request timeout on upstream.
45 : UpstreamRequestTimeout = 0x4,
46 : // Local codec level reset was sent on the stream.
47 : LocalReset = 0x8,
48 : // Remote codec level reset was received on the stream.
49 : UpstreamRemoteReset = 0x10,
50 : // Local reset by a connection pool due to an initial connection failure.
51 : UpstreamConnectionFailure = 0x20,
52 : // If the stream was locally reset due to connection termination.
53 : UpstreamConnectionTermination = 0x40,
54 : // The stream was reset because of a resource overflow.
55 : UpstreamOverflow = 0x80,
56 : // No route found for a given request.
57 : NoRouteFound = 0x100,
58 : // Request was delayed before proxying.
59 : DelayInjected = 0x200,
60 : // Abort with error code was injected.
61 : FaultInjected = 0x400,
62 : // Request was ratelimited locally by rate limit filter.
63 : RateLimited = 0x800,
64 : // Request was unauthorized by external authorization service.
65 : UnauthorizedExternalService = 0x1000,
66 : // Unable to call Ratelimit service.
67 : RateLimitServiceError = 0x2000,
68 : // If the stream was reset due to a downstream connection termination.
69 : DownstreamConnectionTermination = 0x4000,
70 : // Exceeded upstream retry limit.
71 : UpstreamRetryLimitExceeded = 0x8000,
72 : // Request hit the stream idle timeout, triggering a 408.
73 : StreamIdleTimeout = 0x10000,
74 : // Request specified x-envoy-* header values that failed strict header checks.
75 : InvalidEnvoyRequestHeaders = 0x20000,
76 : // Downstream request had an HTTP protocol error
77 : DownstreamProtocolError = 0x40000,
78 : // Upstream request reached to user defined max stream duration.
79 : UpstreamMaxStreamDurationReached = 0x80000,
80 : // True if the response was served from an Envoy cache filter.
81 : ResponseFromCacheFilter = 0x100000,
82 : // Filter config was not received within the permitted warming deadline.
83 : NoFilterConfigFound = 0x200000,
84 : // Request or connection exceeded the downstream connection duration.
85 : DurationTimeout = 0x400000,
86 : // Upstream response had an HTTP protocol error
87 : UpstreamProtocolError = 0x800000,
88 : // No cluster found for a given request.
89 : NoClusterFound = 0x1000000,
90 : // Overload Manager terminated the stream.
91 : OverloadManager = 0x2000000,
92 : // DNS resolution failed.
93 : DnsResolutionFailed = 0x4000000,
94 : // Drop certain percentage of overloaded traffic.
95 : DropOverLoad = 0x8000000,
96 : // ATTENTION: MAKE SURE THIS REMAINS EQUAL TO THE LAST FLAG.
97 : LastFlag = DropOverLoad,
98 : };
99 :
100 : /**
101 : * Constants for the response code details field of StreamInfo for details sent
102 : * by core (non-extension) code.
103 : *
104 : * These provide details about the stream state such as whether the
105 : * response is from the upstream or from envoy (in case of a local reply).
106 : * Custom extensions can define additional values provided they are appropriately
107 : * scoped to avoid collisions.
108 : */
109 : struct ResponseCodeDetailValues {
110 : // Response code was set by the upstream.
111 : const std::string ViaUpstream = "via_upstream";
112 : // Envoy is doing non-streaming proxying, and the request payload exceeded
113 : // configured limits.
114 : const std::string RequestPayloadTooLarge = "request_payload_too_large";
115 : // Envoy is doing non-streaming proxying, and the response payload exceeded
116 : // configured limits.
117 : const std::string ResponsePayloadTooLarge = "response_payload_too_large";
118 : // Envoy is doing streaming proxying, but too much data arrived while waiting
119 : // to attempt a retry.
120 : const std::string RequestPayloadExceededRetryBufferLimit =
121 : "request_payload_exceeded_retry_buffer_limit";
122 : // The per-stream keepalive timeout was exceeded.
123 : const std::string StreamIdleTimeout = "stream_idle_timeout";
124 : // The per-stream max duration timeout was exceeded.
125 : const std::string MaxDurationTimeout = "max_duration_timeout";
126 : // The per-stream total request timeout was exceeded.
127 : const std::string RequestOverallTimeout = "request_overall_timeout";
128 : // The per-stream request header timeout was exceeded.
129 : const std::string RequestHeaderTimeout = "request_header_timeout";
130 : // The request was rejected due to the Overload Manager reaching configured resource limits.
131 : const std::string Overload = "overload";
132 : // The HTTP/1.0 or HTTP/0.9 request was rejected due to HTTP/1.0 support not being configured.
133 : const std::string LowVersion = "low_version";
134 : // The request was rejected due to a missing Host: or :authority field.
135 : const std::string MissingHost = "missing_host_header";
136 : // The request was rejected due to x-envoy-* headers failing strict header validation.
137 : const std::string InvalidEnvoyRequestHeaders = "request_headers_failed_strict_check";
138 : // The request was rejected due to a missing Path or :path header field.
139 : const std::string MissingPath = "missing_path_rejected";
140 : // The request was rejected due to an invalid Path or :path header field.
141 : const std::string InvalidPath = "invalid_path";
142 : // The request was rejected due to using an absolute path on a route not supporting them.
143 : const std::string AbsolutePath = "absolute_path_rejected";
144 : // The request was rejected because path normalization was configured on and failed, probably due
145 : // to an invalid path.
146 : const std::string PathNormalizationFailed = "path_normalization_failed";
147 : // The request was rejected because it attempted an unsupported upgrade.
148 : const std::string UpgradeFailed = "upgrade_failed";
149 :
150 : // The request was rejected by the HCM because there was no route configuration found.
151 : const std::string RouteConfigurationNotFound = "route_configuration_not_found";
152 : // The request was rejected by the router filter because there was no route found.
153 : const std::string RouteNotFound = "route_not_found";
154 : // A direct response was generated by the router filter.
155 : const std::string DirectResponse = "direct_response";
156 : // The request was rejected by the router filter because there was no cluster found for the
157 : // selected route.
158 : const std::string ClusterNotFound = "cluster_not_found";
159 : // The request was rejected by the router filter because the cluster was in maintenance mode.
160 : const std::string MaintenanceMode = "maintenance_mode";
161 : // The request was rejected by the router filter because the DROP_OVERLOAD configuration.
162 : const std::string DropOverload = "drop_overload";
163 : // The request was rejected by the router filter because there was no healthy upstream found.
164 : const std::string NoHealthyUpstream = "no_healthy_upstream";
165 : // The request was forwarded upstream but the response timed out.
166 : const std::string ResponseTimeout = "response_timeout";
167 : // The final upstream try timed out.
168 : const std::string UpstreamPerTryTimeout = "upstream_per_try_timeout";
169 : // The final upstream try idle timed out.
170 : const std::string UpstreamPerTryIdleTimeout = "upstream_per_try_idle_timeout";
171 : // The request was destroyed because of user defined max stream duration.
172 : const std::string UpstreamMaxStreamDurationReached = "upstream_max_stream_duration_reached";
173 : // The upstream connection was reset before a response was started. This
174 : // will generally be accompanied by details about why the reset occurred.
175 : const std::string EarlyUpstreamReset = "upstream_reset_before_response_started";
176 : // The upstream connection was reset after a response was started. This
177 : // will generally be accompanied by details about why the reset occurred but
178 : // indicates that original "success" headers may have been sent downstream
179 : // despite the subsequent failure.
180 : const std::string LateUpstreamReset = "upstream_reset_after_response_started";
181 : // The request was rejected due to no matching filter chain.
182 : const std::string FilterChainNotFound = "filter_chain_not_found";
183 : // The client disconnected unexpectedly.
184 : const std::string DownstreamRemoteDisconnect = "downstream_remote_disconnect";
185 : // The client connection was locally closed for the given reason.
186 : const std::string DownstreamLocalDisconnect = "downstream_local_disconnect({})";
187 : // The max connection duration was exceeded.
188 : const std::string DurationTimeout = "duration_timeout";
189 : // The max request downstream header duration was exceeded.
190 : const std::string DownstreamHeaderTimeout = "downstream_header_timeout";
191 : // The response was generated by the admin filter.
192 : const std::string AdminFilterResponse = "admin_filter_response";
193 : // The original stream was replaced with an internal redirect.
194 : const std::string InternalRedirect = "internal_redirect";
195 : // The request was rejected because configured filters erroneously removed required request
196 : // headers.
197 : const std::string FilterRemovedRequiredRequestHeaders = "filter_removed_required_request_headers";
198 : // The request was rejected because configured filters erroneously removed required response
199 : // headers.
200 : const std::string FilterRemovedRequiredResponseHeaders =
201 : "filter_removed_required_response_headers";
202 : // The request was rejected because the original IP couldn't be detected.
203 : const std::string OriginalIPDetectionFailed = "rejecting_because_detection_failed";
204 : // A filter called addDecodedData at the wrong point in the filter chain.
205 : const std::string FilterAddedInvalidRequestData = "filter_added_invalid_request_data";
206 : // A filter called addDecodedData at the wrong point in the filter chain.
207 : const std::string FilterAddedInvalidResponseData = "filter_added_invalid_response_data";
208 : // Changes or additions to details should be reflected in
209 : // docs/root/configuration/http/http_conn_man/response_code_details.rst
210 : };
211 :
212 : using ResponseCodeDetails = ConstSingleton<ResponseCodeDetailValues>;
213 :
214 : /**
215 : * Constants for the locally closing a connection. This is used in response code
216 : * details field of StreamInfo for details sent by core (non-extension) code.
217 : * This is incomplete as some details may be
218 : *
219 : * Custom extensions can define additional values provided they are appropriately
220 : * scoped to avoid collisions.
221 : */
222 : struct LocalCloseReasonValues {
223 : const std::string DeferredCloseOnDrainedConnection = "deferred_close_on_drained_connection";
224 : const std::string IdleTimeoutOnConnection = "on_idle_timeout";
225 : const std::string CloseForConnectRequestOrTcpTunneling =
226 : "close_for_connect_request_or_tcp_tunneling";
227 : const std::string Http2PingTimeout = "http2_ping_timeout";
228 : const std::string Http2ConnectionProtocolViolation = "http2_connection_protocol_violation";
229 : const std::string TransportSocketTimeout = "transport_socket_timeout";
230 : const std::string TriggeredDelayedCloseTimeout = "triggered_delayed_close_timeout";
231 : const std::string TcpProxyInitializationFailure = "tcp_initializion_failure:";
232 : const std::string TcpSessionIdleTimeout = "tcp_session_idle_timeout";
233 : const std::string MaxConnectionDurationReached = "max_connection_duration_reached";
234 : const std::string ClosingUpstreamTcpDueToDownstreamRemoteClose =
235 : "closing_upstream_tcp_connection_due_to_downstream_remote_close";
236 : const std::string ClosingUpstreamTcpDueToDownstreamLocalClose =
237 : "closing_upstream_tcp_connection_due_to_downstream_local_close";
238 : const std::string ClosingUpstreamTcpDueToDownstreamResetClose =
239 : "closing_upstream_tcp_connection_due_to_downstream_reset_close";
240 : const std::string NonPooledTcpConnectionHostHealthFailure =
241 : "non_pooled_tcp_connection_host_health_failure";
242 : };
243 :
244 : using LocalCloseReasons = ConstSingleton<LocalCloseReasonValues>;
245 :
246 : struct UpstreamTiming {
247 : /**
248 : * Records the latency from when the upstream request was created to when the
249 : * connection pool callbacks (either success of failure were triggered).
250 : */
251 208 : void recordConnectionPoolCallbackLatency(MonotonicTime start, TimeSource& time_source) {
252 208 : ASSERT(!connection_pool_callback_latency_);
253 208 : connection_pool_callback_latency_ =
254 208 : std::chrono::duration_cast<std::chrono::nanoseconds>(time_source.monotonicTime() - start);
255 208 : }
256 :
257 : /**
258 : * Sets the time when the first byte of the request was sent upstream.
259 : */
260 202 : void onFirstUpstreamTxByteSent(TimeSource& time_source) {
261 202 : ASSERT(!first_upstream_tx_byte_sent_);
262 202 : first_upstream_tx_byte_sent_ = time_source.monotonicTime();
263 202 : }
264 :
265 : /**
266 : * Sets the time when the last byte of the request was sent upstream.
267 : */
268 147 : void onLastUpstreamTxByteSent(TimeSource& time_source) {
269 147 : ASSERT(!last_upstream_tx_byte_sent_);
270 147 : last_upstream_tx_byte_sent_ = time_source.monotonicTime();
271 147 : }
272 :
273 : /**
274 : * Sets the time when the first byte of the response is received from upstream.
275 : */
276 141 : void onFirstUpstreamRxByteReceived(TimeSource& time_source) {
277 141 : ASSERT(!first_upstream_rx_byte_received_);
278 141 : first_upstream_rx_byte_received_ = time_source.monotonicTime();
279 141 : }
280 :
281 : /**
282 : * Sets the time when the last byte of the response is received from upstream.
283 : */
284 98 : void onLastUpstreamRxByteReceived(TimeSource& time_source) {
285 98 : ASSERT(!last_upstream_rx_byte_received_);
286 98 : last_upstream_rx_byte_received_ = time_source.monotonicTime();
287 98 : }
288 :
289 1328 : void onUpstreamConnectStart(TimeSource& time_source) {
290 1328 : ASSERT(!upstream_connect_start_);
291 1328 : upstream_connect_start_ = time_source.monotonicTime();
292 1328 : }
293 :
294 1170 : void onUpstreamConnectComplete(TimeSource& time_source) {
295 1170 : upstream_connect_complete_ = time_source.monotonicTime();
296 1170 : }
297 :
298 0 : void onUpstreamHandshakeComplete(TimeSource& time_source) {
299 0 : upstream_handshake_complete_ = time_source.monotonicTime();
300 0 : }
301 :
302 0 : absl::optional<MonotonicTime> upstreamHandshakeComplete() const {
303 0 : return upstream_handshake_complete_;
304 0 : }
305 :
306 0 : absl::optional<std::chrono::nanoseconds> connectionPoolCallbackLatency() const {
307 0 : return connection_pool_callback_latency_;
308 0 : }
309 :
310 : absl::optional<std::chrono::nanoseconds> connection_pool_callback_latency_;
311 : absl::optional<MonotonicTime> first_upstream_tx_byte_sent_;
312 : absl::optional<MonotonicTime> last_upstream_tx_byte_sent_;
313 : absl::optional<MonotonicTime> first_upstream_rx_byte_received_;
314 : absl::optional<MonotonicTime> last_upstream_rx_byte_received_;
315 :
316 : absl::optional<MonotonicTime> upstream_connect_start_;
317 : absl::optional<MonotonicTime> upstream_connect_complete_;
318 : absl::optional<MonotonicTime> upstream_handshake_complete_;
319 : };
320 :
321 : class DownstreamTiming {
322 : public:
323 0 : void setValue(absl::string_view key, MonotonicTime value) { timings_[key] = value; }
324 :
325 0 : absl::optional<MonotonicTime> getValue(absl::string_view value) const {
326 0 : auto ret = timings_.find(value);
327 0 : if (ret == timings_.end()) {
328 0 : return {};
329 0 : }
330 0 : return ret->second;
331 0 : }
332 :
333 2203 : absl::optional<MonotonicTime> lastDownstreamRxByteReceived() const {
334 2203 : return last_downstream_rx_byte_received_;
335 2203 : }
336 0 : absl::optional<MonotonicTime> firstDownstreamTxByteSent() const {
337 0 : return first_downstream_tx_byte_sent_;
338 0 : }
339 0 : absl::optional<MonotonicTime> lastDownstreamTxByteSent() const {
340 0 : return last_downstream_tx_byte_sent_;
341 0 : }
342 0 : absl::optional<MonotonicTime> downstreamHandshakeComplete() const {
343 0 : return downstream_handshake_complete_;
344 0 : }
345 0 : absl::optional<MonotonicTime> lastDownstreamAckReceived() const {
346 0 : return last_downstream_ack_received_;
347 0 : }
348 0 : absl::optional<MonotonicTime> lastDownstreamHeaderRxByteReceived() const {
349 0 : return last_downstream_header_rx_byte_received_;
350 0 : }
351 :
352 388 : void onLastDownstreamRxByteReceived(TimeSource& time_source) {
353 388 : ASSERT(!last_downstream_rx_byte_received_);
354 388 : last_downstream_rx_byte_received_ = time_source.monotonicTime();
355 388 : }
356 562 : void onFirstDownstreamTxByteSent(TimeSource& time_source) {
357 562 : ASSERT(!first_downstream_tx_byte_sent_);
358 562 : first_downstream_tx_byte_sent_ = time_source.monotonicTime();
359 562 : }
360 505 : void onLastDownstreamTxByteSent(TimeSource& time_source) {
361 505 : ASSERT(!last_downstream_tx_byte_sent_);
362 505 : last_downstream_tx_byte_sent_ = time_source.monotonicTime();
363 505 : }
364 0 : void onDownstreamHandshakeComplete(TimeSource& time_source) {
365 0 : // An existing value can be overwritten, e.g. in resumption case.
366 0 : downstream_handshake_complete_ = time_source.monotonicTime();
367 0 : }
368 0 : void onLastDownstreamAckReceived(TimeSource& time_source) {
369 0 : ASSERT(!last_downstream_ack_received_);
370 0 : last_downstream_ack_received_ = time_source.monotonicTime();
371 0 : }
372 547 : void onLastDownstreamHeaderRxByteReceived(TimeSource& time_source) {
373 547 : ASSERT(!last_downstream_header_rx_byte_received_);
374 547 : last_downstream_header_rx_byte_received_ = time_source.monotonicTime();
375 547 : }
376 :
377 : private:
378 : absl::flat_hash_map<std::string, MonotonicTime> timings_;
379 : // The time when the last byte of the request was received.
380 : absl::optional<MonotonicTime> last_downstream_rx_byte_received_;
381 : // The time when the first byte of the response was sent downstream.
382 : absl::optional<MonotonicTime> first_downstream_tx_byte_sent_;
383 : // The time when the last byte of the response was sent downstream.
384 : absl::optional<MonotonicTime> last_downstream_tx_byte_sent_;
385 : // The time the TLS handshake completed. Set at connection level.
386 : absl::optional<MonotonicTime> downstream_handshake_complete_;
387 : // The time the final ack was received from the client.
388 : absl::optional<MonotonicTime> last_downstream_ack_received_;
389 : // The time when the last header byte was received.
390 : absl::optional<MonotonicTime> last_downstream_header_rx_byte_received_;
391 : };
392 :
393 : // Measure the number of bytes sent and received for a stream.
394 : struct BytesMeter {
395 10446 : BytesMeter() = default;
396 45 : uint64_t wireBytesSent() const { return wire_bytes_sent_; }
397 465 : uint64_t wireBytesReceived() const { return wire_bytes_received_; }
398 0 : uint64_t headerBytesSent() const { return header_bytes_sent_; }
399 0 : uint64_t headerBytesReceived() const { return header_bytes_received_; }
400 :
401 3308 : void addHeaderBytesSent(uint64_t added_bytes) { header_bytes_sent_ += added_bytes; }
402 8369 : void addHeaderBytesReceived(uint64_t added_bytes) { header_bytes_received_ += added_bytes; }
403 31453 : void addWireBytesSent(uint64_t added_bytes) { wire_bytes_sent_ += added_bytes; }
404 33349 : void addWireBytesReceived(uint64_t added_bytes) { wire_bytes_received_ += added_bytes; }
405 :
406 : struct BytesSnapshot {
407 : SystemTime snapshot_time;
408 : uint64_t header_bytes_sent{};
409 : uint64_t header_bytes_received{};
410 : uint64_t wire_bytes_sent{};
411 : uint64_t wire_bytes_received{};
412 : };
413 0 : void takeDownstreamPeriodicLoggingSnapshot(const SystemTime& snapshot_time) {
414 0 : downstream_periodic_logging_bytes_snapshot_ = std::make_unique<BytesSnapshot>();
415 0 :
416 0 : downstream_periodic_logging_bytes_snapshot_->snapshot_time = snapshot_time;
417 0 : downstream_periodic_logging_bytes_snapshot_->header_bytes_sent = header_bytes_sent_;
418 0 : downstream_periodic_logging_bytes_snapshot_->header_bytes_received = header_bytes_received_;
419 0 : downstream_periodic_logging_bytes_snapshot_->wire_bytes_sent = wire_bytes_sent_;
420 0 : downstream_periodic_logging_bytes_snapshot_->wire_bytes_received = wire_bytes_received_;
421 0 : }
422 0 : void takeUpstreamPeriodicLoggingSnapshot(const SystemTime& snapshot_time) {
423 0 : upstream_periodic_logging_bytes_snapshot_ = std::make_unique<BytesSnapshot>();
424 0 :
425 0 : upstream_periodic_logging_bytes_snapshot_->snapshot_time = snapshot_time;
426 0 : upstream_periodic_logging_bytes_snapshot_->header_bytes_sent = header_bytes_sent_;
427 0 : upstream_periodic_logging_bytes_snapshot_->header_bytes_received = header_bytes_received_;
428 0 : upstream_periodic_logging_bytes_snapshot_->wire_bytes_sent = wire_bytes_sent_;
429 0 : upstream_periodic_logging_bytes_snapshot_->wire_bytes_received = wire_bytes_received_;
430 0 : }
431 0 : const BytesSnapshot* bytesAtLastDownstreamPeriodicLog() const {
432 0 : return downstream_periodic_logging_bytes_snapshot_.get();
433 0 : }
434 0 : const BytesSnapshot* bytesAtLastUpstreamPeriodicLog() const {
435 0 : return upstream_periodic_logging_bytes_snapshot_.get();
436 0 : }
437 : // Adds the bytes from `existing` to `this`.
438 : // Additionally, captures the snapshots on `existing` and adds them to `this`.
439 404 : void captureExistingBytesMeter(BytesMeter& existing) {
440 : // Add bytes accumulated on `this` to the pre-existing periodic bytes collectors.
441 404 : if (existing.downstream_periodic_logging_bytes_snapshot_) {
442 0 : downstream_periodic_logging_bytes_snapshot_ =
443 0 : std::move(existing.downstream_periodic_logging_bytes_snapshot_);
444 0 : existing.downstream_periodic_logging_bytes_snapshot_ = nullptr;
445 0 : }
446 404 : if (existing.upstream_periodic_logging_bytes_snapshot_) {
447 0 : upstream_periodic_logging_bytes_snapshot_ =
448 0 : std::move(existing.upstream_periodic_logging_bytes_snapshot_);
449 0 : existing.upstream_periodic_logging_bytes_snapshot_ = nullptr;
450 0 : }
451 :
452 : // Accumulate existing bytes.
453 404 : header_bytes_sent_ += existing.header_bytes_sent_;
454 404 : header_bytes_received_ += existing.header_bytes_received_;
455 404 : wire_bytes_sent_ += existing.wire_bytes_sent_;
456 404 : wire_bytes_received_ += existing.wire_bytes_received_;
457 404 : }
458 :
459 : private:
460 : uint64_t header_bytes_sent_{};
461 : uint64_t header_bytes_received_{};
462 : uint64_t wire_bytes_sent_{};
463 : uint64_t wire_bytes_received_{};
464 : std::unique_ptr<BytesSnapshot> downstream_periodic_logging_bytes_snapshot_;
465 : std::unique_ptr<BytesSnapshot> upstream_periodic_logging_bytes_snapshot_;
466 : };
467 :
468 : using BytesMeterSharedPtr = std::shared_ptr<BytesMeter>;
469 :
470 : class UpstreamInfo {
471 : public:
472 2922 : virtual ~UpstreamInfo() = default;
473 :
474 : /**
475 : * Dump the upstream info to the specified ostream.
476 : *
477 : * @param os the ostream to dump state to
478 : * @param indent_level the depth, for pretty-printing.
479 : *
480 : * This function is called on Envoy fatal errors so should avoid memory allocation.
481 : */
482 : virtual void dumpState(std::ostream& os, int indent_level = 0) const PURE;
483 :
484 : /**
485 : * @param connection ID of the upstream connection.
486 : */
487 : virtual void setUpstreamConnectionId(uint64_t id) PURE;
488 :
489 : /**
490 : * @return the ID of the upstream connection, or absl::nullopt if not available.
491 : */
492 : virtual absl::optional<uint64_t> upstreamConnectionId() const PURE;
493 :
494 : /**
495 : * @param interface name of the upstream connection's local socket.
496 : */
497 : virtual void setUpstreamInterfaceName(absl::string_view interface_name) PURE;
498 :
499 : /**
500 : * @return interface name of the upstream connection's local socket, or absl::nullopt if not
501 : * available.
502 : */
503 : virtual absl::optional<absl::string_view> upstreamInterfaceName() const PURE;
504 :
505 : /**
506 : * @param connection_info sets the upstream ssl connection.
507 : */
508 : virtual void
509 : setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) PURE;
510 :
511 : /**
512 : * @return the upstream SSL connection. This will be nullptr if the upstream
513 : * connection does not use SSL.
514 : */
515 : virtual Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const PURE;
516 :
517 : /*
518 : * @return the upstream timing for this stream
519 : * */
520 : virtual UpstreamTiming& upstreamTiming() PURE;
521 : virtual const UpstreamTiming& upstreamTiming() const PURE;
522 :
523 : /**
524 : * @param upstream_local_address sets the local address of the upstream connection. Note that it
525 : * can be different than the local address of the downstream connection.
526 : */
527 : virtual void setUpstreamLocalAddress(
528 : const Network::Address::InstanceConstSharedPtr& upstream_local_address) PURE;
529 :
530 : /**
531 : * @return the upstream local address.
532 : */
533 : virtual const Network::Address::InstanceConstSharedPtr& upstreamLocalAddress() const PURE;
534 :
535 : /**
536 : * @param upstream_remote_address sets the remote address of the upstream connection.
537 : */
538 : virtual void setUpstreamRemoteAddress(
539 : const Network::Address::InstanceConstSharedPtr& upstream_remote_address) PURE;
540 :
541 : /**
542 : * @return the upstream remote address.
543 : */
544 : virtual const Network::Address::InstanceConstSharedPtr& upstreamRemoteAddress() const PURE;
545 :
546 : /**
547 : * @param failure_reason the upstream transport failure reason.
548 : */
549 : virtual void setUpstreamTransportFailureReason(absl::string_view failure_reason) PURE;
550 :
551 : /**
552 : * @return const std::string& the upstream transport failure reason, e.g. certificate validation
553 : * failed.
554 : */
555 : virtual const std::string& upstreamTransportFailureReason() const PURE;
556 :
557 : /**
558 : * @param host the selected upstream host for the request.
559 : */
560 : virtual void setUpstreamHost(Upstream::HostDescriptionConstSharedPtr host) PURE;
561 :
562 : /**
563 : * @return upstream host description.
564 : */
565 : virtual Upstream::HostDescriptionConstSharedPtr upstreamHost() const PURE;
566 :
567 : /**
568 : * Filter State object to be shared between upstream and downstream filters.
569 : * @param pointer to upstream connections filter state.
570 : * @return pointer to filter state to be used by upstream connections.
571 : */
572 : virtual const FilterStateSharedPtr& upstreamFilterState() const PURE;
573 : virtual void setUpstreamFilterState(const FilterStateSharedPtr& filter_state) PURE;
574 :
575 : /**
576 : * Getters and setters for the number of streams started on this connection.
577 : * For upstream connections this is updated as streams are created.
578 : * For downstream connections this is latched at the time the upstream stream
579 : * is assigned.
580 : */
581 : virtual void setUpstreamNumStreams(uint64_t num_streams) PURE;
582 : virtual uint64_t upstreamNumStreams() const PURE;
583 :
584 : virtual void setUpstreamProtocol(Http::Protocol protocol) PURE;
585 : virtual absl::optional<Http::Protocol> upstreamProtocol() const PURE;
586 : };
587 :
588 : /**
589 : * Additional information about a completed request for logging.
590 : */
591 : class StreamInfo {
592 : public:
593 5319 : virtual ~StreamInfo() = default;
594 :
595 : /**
596 : * @param response_flag the response flag. Each filter can set independent response flags. The
597 : * flags are accumulated.
598 : */
599 : virtual void setResponseFlag(ResponseFlag response_flag) PURE;
600 :
601 : /**
602 : * @param code the HTTP response code to set for this request.
603 : */
604 : virtual void setResponseCode(uint32_t code) PURE;
605 :
606 : /**
607 : * @param rc_details the response code details string to set for this request. It should not
608 : * contain any empty or space characters (' ', '\t', '\f', '\v', '\n', '\r'). See
609 : * ResponseCodeDetailValues above for well-known constants.
610 : */
611 : virtual void setResponseCodeDetails(absl::string_view rc_details) PURE;
612 :
613 : /**
614 : * @param connection_termination_details the termination details string to set for this
615 : * connection.
616 : */
617 : virtual void
618 : setConnectionTerminationDetails(absl::string_view connection_termination_details) PURE;
619 :
620 : /**
621 : * @param response_flags the response_flags to intersect with.
622 : * @return true if the intersection of the response_flags argument and the currently set response
623 : * flags is non-empty.
624 : */
625 : virtual bool intersectResponseFlags(uint64_t response_flags) const PURE;
626 :
627 : /**
628 : * @return std::string& the name of the route. The name is get from the route() and it is
629 : * empty if there is no route.
630 : */
631 : virtual const std::string& getRouteName() const PURE;
632 :
633 : /**
634 : * @param std::string name denotes the name of the virtual cluster.
635 : */
636 : virtual void setVirtualClusterName(const absl::optional<std::string>& name) PURE;
637 :
638 : /**
639 : * @return std::string& the name of the virtual cluster which got matched.
640 : */
641 : virtual const absl::optional<std::string>& virtualClusterName() const PURE;
642 :
643 : /**
644 : * @param bytes_received denotes number of bytes to add to total received bytes.
645 : */
646 : virtual void addBytesReceived(uint64_t bytes_received) PURE;
647 :
648 : /**
649 : * @return the number of body bytes received by the stream.
650 : */
651 : virtual uint64_t bytesReceived() const PURE;
652 :
653 : /**
654 : * @param bytes_retransmitted denotes number of bytes to add to total retransmitted bytes.
655 : */
656 : virtual void addBytesRetransmitted(uint64_t bytes_retransmitted) PURE;
657 :
658 : /**
659 : * @return the number of bytes retransmitted by the stream.
660 : */
661 : virtual uint64_t bytesRetransmitted() const PURE;
662 :
663 : /**
664 : * @param packets_retransmitted denotes number of packets to add to total retransmitted packets.
665 : */
666 : virtual void addPacketsRetransmitted(uint64_t packets_retransmitted) PURE;
667 :
668 : /**
669 : * @return the number of packets retransmitted by the stream.
670 : */
671 : virtual uint64_t packetsRetransmitted() const PURE;
672 :
673 : /**
674 : * @return the protocol of the request.
675 : */
676 : virtual absl::optional<Http::Protocol> protocol() const PURE;
677 :
678 : /**
679 : * @param protocol the request's protocol.
680 : */
681 : virtual void protocol(Http::Protocol protocol) PURE;
682 :
683 : /**
684 : * @return the response code.
685 : */
686 : virtual absl::optional<uint32_t> responseCode() const PURE;
687 :
688 : /**
689 : * @return the response code details.
690 : */
691 : virtual const absl::optional<std::string>& responseCodeDetails() const PURE;
692 :
693 : /**
694 : * @return the termination details of the connection.
695 : */
696 : virtual const absl::optional<std::string>& connectionTerminationDetails() const PURE;
697 :
698 : /**
699 : * @return the time that the first byte of the request was received.
700 : */
701 : virtual SystemTime startTime() const PURE;
702 :
703 : /**
704 : * @return the monotonic time that the first byte of the request was received. Duration
705 : * calculations should be made relative to this value.
706 : */
707 : virtual MonotonicTime startTimeMonotonic() const PURE;
708 :
709 : /**
710 : * @return returns the time source.
711 : */
712 : virtual TimeSource& timeSource() const PURE;
713 :
714 : /**
715 : * Sets the upstream information for this stream.
716 : */
717 : virtual void setUpstreamInfo(std::shared_ptr<UpstreamInfo>) PURE;
718 :
719 : /**
720 : * Returns the upstream information for this stream.
721 : */
722 : virtual std::shared_ptr<UpstreamInfo> upstreamInfo() PURE;
723 : virtual OptRef<const UpstreamInfo> upstreamInfo() const PURE;
724 :
725 : /**
726 : * @return the current duration of the request, or the total duration of the request, if ended.
727 : */
728 : virtual absl::optional<std::chrono::nanoseconds> currentDuration() const PURE;
729 :
730 : /**
731 : * @return the total duration of the request (i.e., when the request's ActiveStream is destroyed)
732 : * and may be longer than lastDownstreamTxByteSent.
733 : */
734 : virtual absl::optional<std::chrono::nanoseconds> requestComplete() const PURE;
735 :
736 : /**
737 : * Sets the end time for the request. This method is called once the request has been fully
738 : * completed (i.e., when the request's ActiveStream is destroyed).
739 : */
740 : virtual void onRequestComplete() PURE;
741 :
742 : /**
743 : * @return the downstream timing information.
744 : */
745 : virtual DownstreamTiming& downstreamTiming() PURE;
746 : virtual OptRef<const DownstreamTiming> downstreamTiming() const PURE;
747 :
748 : /**
749 : * @param bytes_sent denotes the number of bytes to add to total sent bytes.
750 : */
751 : virtual void addBytesSent(uint64_t bytes_sent) PURE;
752 :
753 : /**
754 : * @return the number of body bytes sent in the response.
755 : */
756 : virtual uint64_t bytesSent() const PURE;
757 :
758 : /**
759 : * @return whether response flag is set or not.
760 : */
761 : virtual bool hasResponseFlag(ResponseFlag response_flag) const PURE;
762 :
763 : /**
764 : * @return whether any response flag is set or not.
765 : */
766 : virtual bool hasAnyResponseFlag() const PURE;
767 :
768 : /**
769 : * @return response flags encoded as an integer.
770 : */
771 : virtual uint64_t responseFlags() const PURE;
772 :
773 : /**
774 : * @return whether the request is a health check request or not.
775 : */
776 : virtual bool healthCheck() const PURE;
777 :
778 : /**
779 : * @param is_health_check whether the request is a health check request or not.
780 : */
781 : virtual void healthCheck(bool is_health_check) PURE;
782 :
783 : /**
784 : * @return the downstream connection info provider.
785 : */
786 : virtual const Network::ConnectionInfoProvider& downstreamAddressProvider() const PURE;
787 :
788 : /**
789 : * @return const Router::RouteConstSharedPtr Get the route selected for this request.
790 : */
791 : virtual Router::RouteConstSharedPtr route() const PURE;
792 :
793 : /**
794 : * @return const envoy::config::core::v3::Metadata& the dynamic metadata associated with this
795 : * request
796 : */
797 : virtual envoy::config::core::v3::Metadata& dynamicMetadata() PURE;
798 : virtual const envoy::config::core::v3::Metadata& dynamicMetadata() const PURE;
799 :
800 : /**
801 : * @param name the namespace used in the metadata in reverse DNS format, for example:
802 : * envoy.test.my_filter.
803 : * @param value the struct to set on the namespace. A merge will be performed with new values for
804 : * the same key overriding existing.
805 : */
806 : virtual void setDynamicMetadata(const std::string& name, const ProtobufWkt::Struct& value) PURE;
807 :
808 : /**
809 : * Object on which filters can share data on a per-request basis. For singleton data objects, only
810 : * one filter can produce a named data object. List data objects can be updated by multiple
811 : * filters (append only). Both object types can be consumed by multiple filters.
812 : * @return the filter state associated with this request.
813 : */
814 : virtual const FilterStateSharedPtr& filterState() PURE;
815 : virtual const FilterState& filterState() const PURE;
816 :
817 : /**
818 : * @param headers request headers.
819 : */
820 : virtual void setRequestHeaders(const Http::RequestHeaderMap& headers) PURE;
821 :
822 : /**
823 : * @return request headers.
824 : */
825 : virtual const Http::RequestHeaderMap* getRequestHeaders() const PURE;
826 :
827 : /**
828 : * @param Upstream Connection's ClusterInfo.
829 : */
830 : virtual void
831 : setUpstreamClusterInfo(const Upstream::ClusterInfoConstSharedPtr& upstream_cluster_info) PURE;
832 :
833 : /**
834 : * @return Upstream Connection's ClusterInfo.
835 : * This returns an optional to differentiate between unset(absl::nullopt),
836 : * no route or cluster does not exist(nullptr), and set to a valid cluster(not nullptr).
837 : */
838 : virtual absl::optional<Upstream::ClusterInfoConstSharedPtr> upstreamClusterInfo() const PURE;
839 :
840 : /**
841 : * @param provider The unique id implementation this stream uses.
842 : */
843 : virtual void setStreamIdProvider(StreamIdProviderSharedPtr provider) PURE;
844 :
845 : /**
846 : * @return the unique id for this stream if available.
847 : */
848 : virtual OptRef<const StreamIdProvider> getStreamIdProvider() const PURE;
849 :
850 : /**
851 : * Set the trace reason for the stream.
852 : */
853 : virtual void setTraceReason(Tracing::Reason reason) PURE;
854 :
855 : /**
856 : * @return the trace reason for the stream.
857 : */
858 : virtual Tracing::Reason traceReason() const PURE;
859 :
860 : /**
861 : * @param attempt_count, the number of times the request was attempted upstream.
862 : */
863 : virtual void setAttemptCount(uint32_t attempt_count) PURE;
864 :
865 : /**
866 : * @return the number of times the request was attempted upstream, absl::nullopt if the request
867 : * was never attempted upstream.
868 : */
869 : virtual absl::optional<uint32_t> attemptCount() const PURE;
870 :
871 : /**
872 : * @return the bytes meter for upstream http stream.
873 : */
874 : virtual const BytesMeterSharedPtr& getUpstreamBytesMeter() const PURE;
875 :
876 : /**
877 : * @return the bytes meter for downstream http stream.
878 : */
879 : virtual const BytesMeterSharedPtr& getDownstreamBytesMeter() const PURE;
880 :
881 : /**
882 : * @param upstream_bytes_meter, the bytes meter for upstream http stream.
883 : */
884 : virtual void setUpstreamBytesMeter(const BytesMeterSharedPtr& upstream_bytes_meter) PURE;
885 :
886 : /**
887 : * @param downstream_bytes_meter, the bytes meter for downstream http stream.
888 : */
889 : virtual void setDownstreamBytesMeter(const BytesMeterSharedPtr& downstream_bytes_meter) PURE;
890 :
891 : virtual bool isShadow() const PURE;
892 :
893 : static void syncUpstreamAndDownstreamBytesMeter(StreamInfo& downstream_info,
894 202 : StreamInfo& upstream_info) {
895 202 : downstream_info.setUpstreamBytesMeter(upstream_info.getUpstreamBytesMeter());
896 202 : upstream_info.setDownstreamBytesMeter(downstream_info.getDownstreamBytesMeter());
897 202 : }
898 :
899 : /**
900 : * Dump the info to the specified ostream.
901 : *
902 : * @param os the ostream to dump state to
903 : * @param indent_level the depth, for pretty-printing.
904 : *
905 : * This function is called on Envoy fatal errors so should avoid memory allocation.
906 : */
907 : virtual void dumpState(std::ostream& os, int indent_level = 0) const PURE;
908 :
909 : /**
910 : * @return absl::string_view the downstream transport failure reason,
911 : * e.g. certificate validation failed.
912 : */
913 : virtual absl::string_view downstreamTransportFailureReason() const PURE;
914 :
915 : /**
916 : * @param failure_reason the downstream transport failure reason.
917 : */
918 : virtual void setDownstreamTransportFailureReason(absl::string_view failure_reason) PURE;
919 :
920 : /**
921 : * Checked by streams after finishing serving the request.
922 : * @return bool true if the connection should be drained once this stream has
923 : * finished sending and receiving.
924 : */
925 : virtual bool shouldDrainConnectionUponCompletion() const PURE;
926 :
927 : /**
928 : * Called if the connection decides to drain itself after serving this request.
929 : * @param should_drain true to close the connection once this stream has
930 : * finished sending and receiving.
931 : */
932 : virtual void setShouldDrainConnectionUponCompletion(bool should_drain) PURE;
933 : };
934 :
935 : // An enum representation of the Proxy-Status error space.
936 : enum class ProxyStatusError {
937 : DnsTimeout,
938 : DnsError,
939 : DestinationNotFound,
940 : DestinationUnavailable,
941 : DestinationIpProhibited,
942 : DestinationIpUnroutable,
943 : ConnectionRefused,
944 : ConnectionTerminated,
945 : ConnectionTimeout,
946 : ConnectionReadTimeout,
947 : ConnectionWriteTimeout,
948 : ConnectionLimitReached,
949 : TlsProtocolError,
950 : TlsCertificateError,
951 : TlsAlertReceived,
952 : HttpRequestError,
953 : HttpRequestDenied,
954 : HttpResponseIncomplete,
955 : HttpResponseHeaderSectionSize,
956 : HttpResponseHeaderSize,
957 : HttpResponseBodySize,
958 : HttpResponseTrailerSectionSize,
959 : HttpResponseTrailerSize,
960 : HttpResponseTransferCoding,
961 : HttpResponseContentCoding,
962 : HttpResponseTimeout,
963 : HttpUpgradeFailed,
964 : HttpProtocolError,
965 : ProxyInternalResponse,
966 : ProxyInternalError,
967 : ProxyConfigurationError,
968 : ProxyLoopDetected,
969 : // ATTENTION: MAKE SURE THAT THIS REMAINS EQUAL TO THE LAST FLAG.
970 : LastProxyStatus = ProxyLoopDetected,
971 : };
972 :
973 : } // namespace StreamInfo
974 : } // namespace Envoy
|