Line data Source code
1 : #include "source/common/formatter/stream_info_formatter.h"
2 :
3 : #include <regex>
4 :
5 : #include "source/common/config/metadata.h"
6 : #include "source/common/http/utility.h"
7 : #include "source/common/runtime/runtime_features.h"
8 : #include "source/common/stream_info/utility.h"
9 :
10 : #include "absl/strings/str_format.h"
11 : #include "absl/strings/str_replace.h"
12 :
13 : namespace Envoy {
14 : namespace Formatter {
15 :
16 : namespace {
17 :
18 : static const std::string DefaultUnspecifiedValueString = "-";
19 :
20 676 : const std::regex& getSystemTimeFormatNewlinePattern() {
21 676 : CONSTRUCT_ON_FIRST_USE(std::regex, "%[-_0^#]*[1-9]*(E|O)?n");
22 676 : }
23 :
24 : } // namespace
25 :
26 : MetadataFormatter::MetadataFormatter(const std::string& filter_namespace,
27 : const std::vector<std::string>& path,
28 : absl::optional<size_t> max_length,
29 : MetadataFormatter::GetMetadataFunction get_func)
30 : : filter_namespace_(filter_namespace), path_(path), max_length_(max_length),
31 52 : get_func_(get_func) {}
32 :
33 : absl::optional<std::string>
34 45 : MetadataFormatter::formatMetadata(const envoy::config::core::v3::Metadata& metadata) const {
35 45 : ProtobufWkt::Value value = formatMetadataValue(metadata);
36 45 : if (value.kind_case() == ProtobufWkt::Value::kNullValue) {
37 36 : return absl::nullopt;
38 36 : }
39 :
40 9 : std::string str;
41 9 : if (value.kind_case() == ProtobufWkt::Value::kStringValue) {
42 8 : str = value.string_value();
43 8 : } else {
44 1 : #ifdef ENVOY_ENABLE_YAML
45 1 : absl::StatusOr<std::string> json_or_error =
46 1 : MessageUtil::getJsonStringFromMessage(value, false, true);
47 1 : if (json_or_error.ok()) {
48 1 : str = json_or_error.value();
49 1 : } else {
50 0 : str = json_or_error.status().message();
51 0 : }
52 : #else
53 : IS_ENVOY_BUG("Json support compiled out");
54 : #endif
55 1 : }
56 9 : SubstitutionFormatUtils::truncate(str, max_length_);
57 9 : return str;
58 45 : }
59 :
60 : ProtobufWkt::Value
61 45 : MetadataFormatter::formatMetadataValue(const envoy::config::core::v3::Metadata& metadata) const {
62 45 : if (path_.empty()) {
63 20 : const auto filter_it = metadata.filter_metadata().find(filter_namespace_);
64 20 : if (filter_it == metadata.filter_metadata().end()) {
65 20 : return SubstitutionFormatUtils::unspecifiedValue();
66 20 : }
67 0 : ProtobufWkt::Value output;
68 0 : output.mutable_struct_value()->CopyFrom(filter_it->second);
69 0 : return output;
70 20 : }
71 :
72 25 : const ProtobufWkt::Value& val =
73 25 : Config::Metadata::metadataValue(&metadata, filter_namespace_, path_);
74 25 : if (val.kind_case() == ProtobufWkt::Value::KindCase::KIND_NOT_SET) {
75 16 : return SubstitutionFormatUtils::unspecifiedValue();
76 16 : }
77 :
78 9 : return val;
79 25 : }
80 :
81 : absl::optional<std::string>
82 45 : MetadataFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
83 45 : auto metadata = get_func_(stream_info);
84 45 : return (metadata != nullptr) ? formatMetadata(*metadata) : absl::nullopt;
85 45 : }
86 :
87 0 : ProtobufWkt::Value MetadataFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
88 0 : auto metadata = get_func_(stream_info);
89 0 : return formatMetadataValue((metadata != nullptr) ? *metadata
90 0 : : envoy::config::core::v3::Metadata());
91 0 : }
92 :
93 : // TODO(glicht): Consider adding support for route/listener/cluster metadata as suggested by
94 : // @htuch. See: https://github.com/envoyproxy/envoy/issues/3006
95 : DynamicMetadataFormatter::DynamicMetadataFormatter(const std::string& filter_namespace,
96 : const std::vector<std::string>& path,
97 : absl::optional<size_t> max_length)
98 : : MetadataFormatter(filter_namespace, path, max_length,
99 1 : [](const StreamInfo::StreamInfo& stream_info) {
100 1 : return &stream_info.dynamicMetadata();
101 1 : }) {}
102 :
103 : ClusterMetadataFormatter::ClusterMetadataFormatter(const std::string& filter_namespace,
104 : const std::vector<std::string>& path,
105 : absl::optional<size_t> max_length)
106 : : MetadataFormatter(filter_namespace, path, max_length,
107 : [](const StreamInfo::StreamInfo& stream_info)
108 0 : -> const envoy::config::core::v3::Metadata* {
109 0 : auto cluster_info = stream_info.upstreamClusterInfo();
110 0 : if (!cluster_info.has_value() || cluster_info.value() == nullptr) {
111 0 : return nullptr;
112 0 : }
113 0 : return &cluster_info.value()->metadata();
114 0 : }) {}
115 :
116 : UpstreamHostMetadataFormatter::UpstreamHostMetadataFormatter(const std::string& filter_namespace,
117 : const std::vector<std::string>& path,
118 : absl::optional<size_t> max_length)
119 : : MetadataFormatter(filter_namespace, path, max_length,
120 : [](const StreamInfo::StreamInfo& stream_info)
121 44 : -> const envoy::config::core::v3::Metadata* {
122 44 : if (!stream_info.upstreamInfo().has_value()) {
123 0 : return nullptr;
124 0 : }
125 44 : Upstream::HostDescriptionConstSharedPtr host =
126 44 : stream_info.upstreamInfo()->upstreamHost();
127 44 : if (host == nullptr) {
128 0 : return nullptr;
129 0 : }
130 44 : return host->metadata().get();
131 51 : }) {}
132 :
133 : std::unique_ptr<FilterStateFormatter>
134 : FilterStateFormatter::create(const std::string& format, const absl::optional<size_t>& max_length,
135 14 : bool is_upstream) {
136 14 : std::string key, serialize_type, field_name;
137 14 : static constexpr absl::string_view PLAIN_SERIALIZATION{"PLAIN"};
138 14 : static constexpr absl::string_view TYPED_SERIALIZATION{"TYPED"};
139 14 : static constexpr absl::string_view FIELD_SERIALIZATION{"FIELD"};
140 :
141 14 : SubstitutionFormatUtils::parseSubcommand(format, ':', key, serialize_type, field_name);
142 14 : if (key.empty()) {
143 0 : throwEnvoyExceptionOrPanic("Invalid filter state configuration, key cannot be empty.");
144 0 : }
145 :
146 14 : if (serialize_type.empty()) {
147 0 : serialize_type = std::string(TYPED_SERIALIZATION);
148 0 : }
149 14 : if (serialize_type != PLAIN_SERIALIZATION && serialize_type != TYPED_SERIALIZATION &&
150 14 : serialize_type != FIELD_SERIALIZATION) {
151 0 : throwEnvoyExceptionOrPanic("Invalid filter state serialize type, only "
152 0 : "support PLAIN/TYPED/FIELD.");
153 0 : }
154 14 : if ((serialize_type == FIELD_SERIALIZATION) ^ !field_name.empty()) {
155 0 : throwEnvoyExceptionOrPanic("Invalid filter state serialize type, FIELD "
156 0 : "should be used with the field name.");
157 0 : }
158 :
159 14 : const bool serialize_as_string = serialize_type == PLAIN_SERIALIZATION;
160 :
161 14 : return std::make_unique<FilterStateFormatter>(key, max_length, serialize_as_string, is_upstream,
162 14 : field_name);
163 14 : }
164 :
165 : FilterStateFormatter::FilterStateFormatter(const std::string& key,
166 : absl::optional<size_t> max_length,
167 : bool serialize_as_string, bool is_upstream,
168 : const std::string& field_name)
169 14 : : key_(key), max_length_(max_length), is_upstream_(is_upstream) {
170 14 : if (!field_name.empty()) {
171 0 : format_ = FilterStateFormat::Field;
172 0 : field_name_ = field_name;
173 0 : factory_ = Registry::FactoryRegistry<StreamInfo::FilterState::ObjectFactory>::getFactory(key);
174 14 : } else if (serialize_as_string) {
175 14 : format_ = FilterStateFormat::String;
176 14 : } else {
177 0 : format_ = FilterStateFormat::Proto;
178 0 : }
179 14 : }
180 :
181 : const Envoy::StreamInfo::FilterState::Object*
182 10 : FilterStateFormatter::filterState(const StreamInfo::StreamInfo& stream_info) const {
183 10 : const StreamInfo::FilterState* filter_state = nullptr;
184 10 : if (is_upstream_) {
185 0 : const OptRef<const StreamInfo::UpstreamInfo> upstream_info = stream_info.upstreamInfo();
186 0 : if (upstream_info) {
187 0 : filter_state = upstream_info->upstreamFilterState().get();
188 0 : }
189 10 : } else {
190 10 : filter_state = &stream_info.filterState();
191 10 : }
192 :
193 10 : if (filter_state) {
194 10 : return filter_state->getDataReadOnly<StreamInfo::FilterState::Object>(key_);
195 10 : }
196 :
197 0 : return nullptr;
198 10 : }
199 :
200 : struct StringFieldVisitor {
201 0 : absl::optional<std::string> operator()(int64_t val) { return absl::StrCat(val); }
202 0 : absl::optional<std::string> operator()(absl::string_view val) { return std::string(val); }
203 0 : absl::optional<std::string> operator()(absl::monostate) { return {}; }
204 : };
205 :
206 : absl::optional<std::string>
207 10 : FilterStateFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
208 10 : const Envoy::StreamInfo::FilterState::Object* state = filterState(stream_info);
209 10 : if (!state) {
210 10 : return absl::nullopt;
211 10 : }
212 :
213 0 : switch (format_) {
214 0 : case FilterStateFormat::String: {
215 0 : absl::optional<std::string> plain_value = state->serializeAsString();
216 0 : if (plain_value.has_value()) {
217 0 : SubstitutionFormatUtils::truncate(plain_value.value(), max_length_);
218 0 : return plain_value.value();
219 0 : }
220 0 : return absl::nullopt;
221 0 : }
222 0 : case FilterStateFormat::Proto: {
223 0 : ProtobufTypes::MessagePtr proto = state->serializeAsProto();
224 0 : if (proto == nullptr) {
225 0 : return absl::nullopt;
226 0 : }
227 :
228 0 : #if defined(ENVOY_ENABLE_FULL_PROTOS)
229 0 : std::string value;
230 0 : const auto status = Protobuf::util::MessageToJsonString(*proto, &value);
231 0 : if (!status.ok()) {
232 : // If the message contains an unknown Any (from WASM or Lua), MessageToJsonString will fail.
233 : // TODO(lizan): add support of unknown Any.
234 0 : return absl::nullopt;
235 0 : }
236 :
237 0 : SubstitutionFormatUtils::truncate(value, max_length_);
238 0 : return value;
239 : #else
240 : PANIC("FilterStateFormatter::format requires full proto support");
241 : return absl::nullopt;
242 : #endif
243 0 : }
244 0 : case FilterStateFormat::Field: {
245 0 : if (!factory_) {
246 0 : return absl::nullopt;
247 0 : }
248 0 : const auto reflection = factory_->reflect(state);
249 0 : if (!reflection) {
250 0 : return absl::nullopt;
251 0 : }
252 0 : auto field_value = reflection->getField(field_name_);
253 0 : auto string_value = absl::visit(StringFieldVisitor(), field_value);
254 0 : if (!string_value) {
255 0 : return absl::nullopt;
256 0 : }
257 0 : SubstitutionFormatUtils::truncate(string_value.value(), max_length_);
258 0 : return string_value;
259 0 : }
260 0 : default:
261 0 : return absl::nullopt;
262 0 : }
263 0 : }
264 :
265 : ProtobufWkt::Value
266 0 : FilterStateFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
267 0 : const Envoy::StreamInfo::FilterState::Object* state = filterState(stream_info);
268 0 : if (!state) {
269 0 : return SubstitutionFormatUtils::unspecifiedValue();
270 0 : }
271 :
272 0 : switch (format_) {
273 0 : case FilterStateFormat::String: {
274 0 : absl::optional<std::string> plain_value = state->serializeAsString();
275 0 : if (plain_value.has_value()) {
276 0 : SubstitutionFormatUtils::truncate(plain_value.value(), max_length_);
277 0 : return ValueUtil::stringValue(plain_value.value());
278 0 : }
279 0 : return SubstitutionFormatUtils::unspecifiedValue();
280 0 : }
281 0 : case FilterStateFormat::Proto: {
282 0 : ProtobufTypes::MessagePtr proto = state->serializeAsProto();
283 0 : if (!proto) {
284 0 : return SubstitutionFormatUtils::unspecifiedValue();
285 0 : }
286 :
287 0 : #ifdef ENVOY_ENABLE_YAML
288 0 : ProtobufWkt::Value val;
289 0 : if (MessageUtil::jsonConvertValue(*proto, val)) {
290 0 : return val;
291 0 : }
292 0 : #endif
293 0 : return SubstitutionFormatUtils::unspecifiedValue();
294 0 : }
295 0 : case FilterStateFormat::Field: {
296 0 : if (!factory_) {
297 0 : return SubstitutionFormatUtils::unspecifiedValue();
298 0 : }
299 0 : const auto reflection = factory_->reflect(state);
300 0 : if (!reflection) {
301 0 : return SubstitutionFormatUtils::unspecifiedValue();
302 0 : }
303 0 : auto field_value = reflection->getField(field_name_);
304 0 : auto string_value = absl::visit(StringFieldVisitor(), field_value);
305 0 : if (!string_value) {
306 0 : return SubstitutionFormatUtils::unspecifiedValue();
307 0 : }
308 0 : SubstitutionFormatUtils::truncate(string_value.value(), max_length_);
309 0 : return ValueUtil::stringValue(string_value.value());
310 0 : }
311 0 : default:
312 0 : return SubstitutionFormatUtils::unspecifiedValue();
313 0 : }
314 0 : }
315 :
316 : // A SystemTime formatter that extracts the startTime from StreamInfo. Must be provided
317 : // an access log command that starts with `START_TIME`.
318 : StartTimeFormatter::StartTimeFormatter(const std::string& format)
319 : : SystemTimeFormatter(
320 : format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
321 0 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
322 0 : return stream_info.startTime();
323 0 : })) {}
324 :
325 : DownstreamPeerCertVStartFormatter::DownstreamPeerCertVStartFormatter(const std::string& format)
326 : : SystemTimeFormatter(
327 : format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
328 0 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
329 0 : const auto connection_info =
330 0 : stream_info.downstreamAddressProvider().sslConnection();
331 0 : return connection_info != nullptr
332 0 : ? connection_info->validFromPeerCertificate()
333 0 : : absl::optional<SystemTime>();
334 0 : })) {}
335 : DownstreamPeerCertVEndFormatter::DownstreamPeerCertVEndFormatter(const std::string& format)
336 : : SystemTimeFormatter(
337 : format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
338 4 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
339 4 : const auto connection_info =
340 4 : stream_info.downstreamAddressProvider().sslConnection();
341 4 : return connection_info != nullptr
342 4 : ? connection_info->expirationPeerCertificate()
343 4 : : absl::optional<SystemTime>();
344 4 : })) {}
345 : UpstreamPeerCertVStartFormatter::UpstreamPeerCertVStartFormatter(const std::string& format)
346 : : SystemTimeFormatter(
347 : format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
348 0 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
349 0 : return stream_info.upstreamInfo() &&
350 0 : stream_info.upstreamInfo()->upstreamSslConnection() !=
351 0 : nullptr
352 0 : ? stream_info.upstreamInfo()
353 0 : ->upstreamSslConnection()
354 0 : ->validFromPeerCertificate()
355 0 : : absl::optional<SystemTime>();
356 0 : })) {}
357 : UpstreamPeerCertVEndFormatter::UpstreamPeerCertVEndFormatter(const std::string& format)
358 : : SystemTimeFormatter(
359 : format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
360 0 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
361 0 : return stream_info.upstreamInfo() &&
362 0 : stream_info.upstreamInfo()->upstreamSslConnection() !=
363 0 : nullptr
364 0 : ? stream_info.upstreamInfo()
365 0 : ->upstreamSslConnection()
366 0 : ->expirationPeerCertificate()
367 0 : : absl::optional<SystemTime>();
368 0 : })) {}
369 :
370 : SystemTimeFormatter::SystemTimeFormatter(const std::string& format, TimeFieldExtractorPtr f)
371 676 : : date_formatter_(format), time_field_extractor_(std::move(f)) {
372 : // Validate the input specifier here. The formatted string may be destined for a header, and
373 : // should not contain invalid characters {NUL, LR, CF}.
374 676 : if (std::regex_search(format, getSystemTimeFormatNewlinePattern())) {
375 14 : throwEnvoyExceptionOrPanic("Invalid header configuration. Format string contains newline.");
376 14 : }
377 676 : }
378 :
379 : absl::optional<std::string>
380 1093 : SystemTimeFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
381 1093 : const auto time_field = (*time_field_extractor_)(stream_info);
382 1093 : if (!time_field.has_value()) {
383 4 : return absl::nullopt;
384 4 : }
385 1089 : if (date_formatter_.formatString().empty()) {
386 616 : return AccessLogDateTimeFormatter::fromTime(time_field.value());
387 616 : }
388 473 : return date_formatter_.fromTime(time_field.value());
389 1089 : }
390 :
391 : ProtobufWkt::Value
392 0 : SystemTimeFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
393 0 : return ValueUtil::optionalStringValue(format(stream_info));
394 0 : }
395 :
396 : EnvironmentFormatter::EnvironmentFormatter(const std::string& key,
397 0 : absl::optional<size_t> max_length) {
398 0 : ASSERT(!key.empty());
399 :
400 0 : const char* env_value = std::getenv(key.c_str());
401 0 : if (env_value != nullptr) {
402 0 : std::string env_string = env_value;
403 0 : SubstitutionFormatUtils::truncate(env_string, max_length);
404 0 : str_.set_string_value(env_string);
405 0 : return;
406 0 : }
407 0 : str_.set_string_value(DefaultUnspecifiedValueString);
408 0 : }
409 :
410 0 : absl::optional<std::string> EnvironmentFormatter::format(const StreamInfo::StreamInfo&) const {
411 0 : return str_.string_value();
412 0 : }
413 0 : ProtobufWkt::Value EnvironmentFormatter::formatValue(const StreamInfo::StreamInfo&) const {
414 0 : return str_;
415 0 : }
416 :
417 : // StreamInfo std::string formatter provider.
418 : class StreamInfoStringFormatterProvider : public StreamInfoFormatterProvider {
419 : public:
420 : using FieldExtractor = std::function<absl::optional<std::string>(const StreamInfo::StreamInfo&)>;
421 :
422 343 : StreamInfoStringFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
423 :
424 : // StreamInfoFormatterProvider
425 1225 : absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
426 1225 : return field_extractor_(stream_info);
427 1225 : }
428 0 : ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
429 0 : return ValueUtil::optionalStringValue(field_extractor_(stream_info));
430 0 : }
431 :
432 : private:
433 : FieldExtractor field_extractor_;
434 : };
435 :
436 : // StreamInfo std::chrono_nanoseconds field extractor.
437 : class StreamInfoDurationFormatterProvider : public StreamInfoFormatterProvider {
438 : public:
439 : using FieldExtractor =
440 : std::function<absl::optional<std::chrono::nanoseconds>(const StreamInfo::StreamInfo&)>;
441 :
442 174 : StreamInfoDurationFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
443 :
444 : // StreamInfoFormatterProvider
445 615 : absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
446 615 : const auto millis = extractMillis(stream_info);
447 615 : if (!millis) {
448 3 : return absl::nullopt;
449 3 : }
450 :
451 612 : return fmt::format_int(millis.value()).str();
452 615 : }
453 0 : ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
454 0 : const auto millis = extractMillis(stream_info);
455 0 : if (!millis) {
456 0 : return SubstitutionFormatUtils::unspecifiedValue();
457 0 : }
458 :
459 0 : return ValueUtil::numberValue(millis.value());
460 0 : }
461 :
462 : private:
463 615 : absl::optional<int64_t> extractMillis(const StreamInfo::StreamInfo& stream_info) const {
464 615 : const auto time = field_extractor_(stream_info);
465 615 : if (time) {
466 612 : return std::chrono::duration_cast<std::chrono::milliseconds>(time.value()).count();
467 612 : }
468 3 : return absl::nullopt;
469 615 : }
470 :
471 : FieldExtractor field_extractor_;
472 : };
473 :
474 : // StreamInfo uint64_t field extractor.
475 : class StreamInfoUInt64FormatterProvider : public StreamInfoFormatterProvider {
476 : public:
477 : using FieldExtractor = std::function<uint64_t(const StreamInfo::StreamInfo&)>;
478 :
479 520 : StreamInfoUInt64FormatterProvider(FieldExtractor f) : field_extractor_(f) {}
480 :
481 : // StreamInfoFormatterProvider
482 1843 : absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
483 1843 : return fmt::format_int(field_extractor_(stream_info)).str();
484 1843 : }
485 0 : ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
486 0 : return ValueUtil::numberValue(field_extractor_(stream_info));
487 0 : }
488 :
489 : private:
490 : FieldExtractor field_extractor_;
491 : };
492 :
493 : // StreamInfo Envoy::Network::Address::InstanceConstSharedPtr field extractor.
494 : class StreamInfoAddressFormatterProvider : public StreamInfoFormatterProvider {
495 : public:
496 : using FieldExtractor =
497 : std::function<Network::Address::InstanceConstSharedPtr(const StreamInfo::StreamInfo&)>;
498 :
499 187 : static std::unique_ptr<StreamInfoAddressFormatterProvider> withPort(FieldExtractor f) {
500 187 : return std::make_unique<StreamInfoAddressFormatterProvider>(
501 187 : f, StreamInfoAddressFieldExtractionType::WithPort);
502 187 : }
503 :
504 64 : static std::unique_ptr<StreamInfoAddressFormatterProvider> withoutPort(FieldExtractor f) {
505 64 : return std::make_unique<StreamInfoAddressFormatterProvider>(
506 64 : f, StreamInfoAddressFieldExtractionType::WithoutPort);
507 64 : }
508 :
509 0 : static std::unique_ptr<StreamInfoAddressFormatterProvider> justPort(FieldExtractor f) {
510 0 : return std::make_unique<StreamInfoAddressFormatterProvider>(
511 0 : f, StreamInfoAddressFieldExtractionType::JustPort);
512 0 : }
513 :
514 : StreamInfoAddressFormatterProvider(FieldExtractor f,
515 : StreamInfoAddressFieldExtractionType extraction_type)
516 251 : : field_extractor_(f), extraction_type_(extraction_type) {}
517 :
518 : // StreamInfoFormatterProvider
519 684 : absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
520 684 : Network::Address::InstanceConstSharedPtr address = field_extractor_(stream_info);
521 684 : if (!address) {
522 472 : return absl::nullopt;
523 472 : }
524 :
525 212 : return toString(*address);
526 684 : }
527 0 : ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
528 0 : Network::Address::InstanceConstSharedPtr address = field_extractor_(stream_info);
529 0 : if (!address) {
530 0 : return SubstitutionFormatUtils::unspecifiedValue();
531 0 : }
532 :
533 0 : if (extraction_type_ == StreamInfoAddressFieldExtractionType::JustPort) {
534 0 : const auto port = StreamInfo::Utility::extractDownstreamAddressJustPort(*address);
535 0 : if (port) {
536 0 : return ValueUtil::numberValue(*port);
537 0 : }
538 0 : return SubstitutionFormatUtils::unspecifiedValue();
539 0 : }
540 :
541 0 : return ValueUtil::stringValue(toString(*address));
542 0 : }
543 :
544 : private:
545 212 : std::string toString(const Network::Address::Instance& address) const {
546 212 : switch (extraction_type_) {
547 56 : case StreamInfoAddressFieldExtractionType::WithoutPort:
548 56 : return StreamInfo::Utility::formatDownstreamAddressNoPort(address);
549 0 : case StreamInfoAddressFieldExtractionType::JustPort:
550 0 : return StreamInfo::Utility::formatDownstreamAddressJustPort(address);
551 156 : case StreamInfoAddressFieldExtractionType::WithPort:
552 156 : default:
553 156 : return address.asString();
554 212 : }
555 212 : }
556 :
557 : FieldExtractor field_extractor_;
558 : const StreamInfoAddressFieldExtractionType extraction_type_;
559 : };
560 :
561 : // Ssl::ConnectionInfo std::string field extractor.
562 : class StreamInfoSslConnectionInfoFormatterProvider : public StreamInfoFormatterProvider {
563 : public:
564 : using FieldExtractor =
565 : std::function<absl::optional<std::string>(const Ssl::ConnectionInfo& connection_info)>;
566 :
567 1 : StreamInfoSslConnectionInfoFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
568 :
569 1 : absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
570 1 : if (stream_info.downstreamAddressProvider().sslConnection() == nullptr) {
571 0 : return absl::nullopt;
572 0 : }
573 :
574 1 : const auto value = field_extractor_(*stream_info.downstreamAddressProvider().sslConnection());
575 1 : if (value && value->empty()) {
576 0 : return absl::nullopt;
577 0 : }
578 :
579 1 : return value;
580 1 : }
581 :
582 0 : ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
583 0 : if (stream_info.downstreamAddressProvider().sslConnection() == nullptr) {
584 0 : return SubstitutionFormatUtils::unspecifiedValue();
585 0 : }
586 :
587 0 : const auto value = field_extractor_(*stream_info.downstreamAddressProvider().sslConnection());
588 0 : if (value && value->empty()) {
589 0 : return SubstitutionFormatUtils::unspecifiedValue();
590 0 : }
591 :
592 0 : return ValueUtil::optionalStringValue(value);
593 0 : }
594 :
595 : private:
596 : FieldExtractor field_extractor_;
597 : };
598 :
599 : class StreamInfoUpstreamSslConnectionInfoFormatterProvider : public StreamInfoFormatterProvider {
600 : public:
601 : using FieldExtractor =
602 : std::function<absl::optional<std::string>(const Ssl::ConnectionInfo& connection_info)>;
603 :
604 8 : StreamInfoUpstreamSslConnectionInfoFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
605 :
606 8 : absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
607 8 : if (!stream_info.upstreamInfo() ||
608 8 : stream_info.upstreamInfo()->upstreamSslConnection() == nullptr) {
609 8 : return absl::nullopt;
610 8 : }
611 :
612 0 : const auto value = field_extractor_(*(stream_info.upstreamInfo()->upstreamSslConnection()));
613 0 : if (value && value->empty()) {
614 0 : return absl::nullopt;
615 0 : }
616 :
617 0 : return value;
618 0 : }
619 :
620 0 : ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
621 0 : if (!stream_info.upstreamInfo() ||
622 0 : stream_info.upstreamInfo()->upstreamSslConnection() == nullptr) {
623 0 : return SubstitutionFormatUtils::unspecifiedValue();
624 0 : }
625 :
626 0 : const auto value = field_extractor_(*(stream_info.upstreamInfo()->upstreamSslConnection()));
627 0 : if (value && value->empty()) {
628 0 : return SubstitutionFormatUtils::unspecifiedValue();
629 0 : }
630 :
631 0 : return ValueUtil::optionalStringValue(value);
632 0 : }
633 :
634 : private:
635 : FieldExtractor field_extractor_;
636 : };
637 :
638 2050 : const StreamInfoFormatterProviderLookupTable& getKnownStreamInfoFormatterProviders() {
639 2050 : CONSTRUCT_ON_FIRST_USE(
640 2050 : StreamInfoFormatterProviderLookupTable,
641 2050 : {
642 2050 : {"REQUEST_DURATION",
643 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
644 2050 : [](const std::string&, absl::optional<size_t>) {
645 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
646 2050 : [](const StreamInfo::StreamInfo& stream_info) {
647 2050 : StreamInfo::TimingUtility timing(stream_info);
648 2050 : return timing.lastDownstreamRxByteReceived();
649 2050 : });
650 2050 : }}},
651 2050 : {"REQUEST_TX_DURATION",
652 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
653 2050 : [](const std::string&, absl::optional<size_t>) {
654 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
655 2050 : [](const StreamInfo::StreamInfo& stream_info) {
656 2050 : StreamInfo::TimingUtility timing(stream_info);
657 2050 : return timing.lastUpstreamTxByteSent();
658 2050 : });
659 2050 : }}},
660 2050 : {"RESPONSE_DURATION",
661 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
662 2050 : [](const std::string&, absl::optional<size_t>) {
663 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
664 2050 : [](const StreamInfo::StreamInfo& stream_info) {
665 2050 : StreamInfo::TimingUtility timing(stream_info);
666 2050 : return timing.firstUpstreamRxByteReceived();
667 2050 : });
668 2050 : }}},
669 2050 : {"RESPONSE_TX_DURATION",
670 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
671 2050 : [](const std::string&, absl::optional<size_t>) {
672 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
673 2050 : [](const StreamInfo::StreamInfo& stream_info) {
674 2050 : StreamInfo::TimingUtility timing(stream_info);
675 2050 : auto downstream = timing.lastDownstreamTxByteSent();
676 2050 : auto upstream = timing.firstUpstreamRxByteReceived();
677 :
678 2050 : absl::optional<std::chrono::nanoseconds> result;
679 2050 : if (downstream && upstream) {
680 2050 : result = downstream.value() - upstream.value();
681 2050 : }
682 :
683 2050 : return result;
684 2050 : });
685 2050 : }}},
686 2050 : {"DOWNSTREAM_HANDSHAKE_DURATION",
687 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
688 2050 : [](const std::string&, absl::optional<size_t>) {
689 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
690 2050 : [](const StreamInfo::StreamInfo& stream_info) {
691 2050 : StreamInfo::TimingUtility timing(stream_info);
692 2050 : return timing.downstreamHandshakeComplete();
693 2050 : });
694 2050 : }}},
695 2050 : {"ROUNDTRIP_DURATION",
696 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
697 2050 : [](const std::string&, absl::optional<size_t>) {
698 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
699 2050 : [](const StreamInfo::StreamInfo& stream_info) {
700 2050 : StreamInfo::TimingUtility timing(stream_info);
701 2050 : return timing.lastDownstreamAckReceived();
702 2050 : });
703 2050 : }}},
704 2050 : {"BYTES_RECEIVED",
705 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
706 2050 : [](const std::string&, absl::optional<size_t>) {
707 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
708 2050 : [](const StreamInfo::StreamInfo& stream_info) {
709 2050 : return stream_info.bytesReceived();
710 2050 : });
711 2050 : }}},
712 2050 : {"BYTES_RETRANSMITTED",
713 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
714 2050 : [](const std::string&, absl::optional<size_t>) {
715 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
716 2050 : [](const StreamInfo::StreamInfo& stream_info) {
717 2050 : return stream_info.bytesRetransmitted();
718 2050 : });
719 2050 : }}},
720 2050 : {"PACKETS_RETRANSMITTED",
721 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
722 2050 : [](const std::string&, absl::optional<size_t>) {
723 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
724 2050 : [](const StreamInfo::StreamInfo& stream_info) {
725 2050 : return stream_info.packetsRetransmitted();
726 2050 : });
727 2050 : }}},
728 2050 : {"UPSTREAM_WIRE_BYTES_RECEIVED",
729 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
730 2050 : [](const std::string&, absl::optional<size_t>) {
731 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
732 2050 : [](const StreamInfo::StreamInfo& stream_info) {
733 2050 : const auto& bytes_meter = stream_info.getUpstreamBytesMeter();
734 2050 : return bytes_meter ? bytes_meter->wireBytesReceived() : 0;
735 2050 : });
736 2050 : }}},
737 2050 : {"UPSTREAM_HEADER_BYTES_RECEIVED",
738 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
739 2050 : [](const std::string&, absl::optional<size_t>) {
740 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
741 2050 : [](const StreamInfo::StreamInfo& stream_info) {
742 2050 : const auto& bytes_meter = stream_info.getUpstreamBytesMeter();
743 2050 : return bytes_meter ? bytes_meter->headerBytesReceived() : 0;
744 2050 : });
745 2050 : }}},
746 2050 : {"DOWNSTREAM_WIRE_BYTES_RECEIVED",
747 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
748 2050 : [](const std::string&, absl::optional<size_t>) {
749 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
750 2050 : [](const StreamInfo::StreamInfo& stream_info) {
751 2050 : const auto& bytes_meter = stream_info.getDownstreamBytesMeter();
752 2050 : return bytes_meter ? bytes_meter->wireBytesReceived() : 0;
753 2050 : });
754 2050 : }}},
755 2050 : {"DOWNSTREAM_HEADER_BYTES_RECEIVED",
756 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
757 2050 : [](const std::string&, absl::optional<size_t>) {
758 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
759 2050 : [](const StreamInfo::StreamInfo& stream_info) {
760 2050 : const auto& bytes_meter = stream_info.getDownstreamBytesMeter();
761 2050 : return bytes_meter ? bytes_meter->headerBytesReceived() : 0;
762 2050 : });
763 2050 : }}},
764 2050 : {"PROTOCOL",
765 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
766 2050 : [](const std::string&, absl::optional<size_t>) {
767 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
768 2050 : [](const StreamInfo::StreamInfo& stream_info) {
769 2050 : return SubstitutionFormatUtils::protocolToString(stream_info.protocol());
770 2050 : });
771 2050 : }}},
772 2050 : {"UPSTREAM_PROTOCOL",
773 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
774 2050 : [](const std::string&, absl::optional<size_t>) {
775 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
776 2050 : [](const StreamInfo::StreamInfo& stream_info) {
777 2050 : return stream_info.upstreamInfo()
778 2050 : ? SubstitutionFormatUtils::protocolToString(
779 2050 : stream_info.upstreamInfo()->upstreamProtocol())
780 2050 : : absl::nullopt;
781 2050 : });
782 2050 : }}},
783 2050 : {"RESPONSE_CODE",
784 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
785 2050 : [](const std::string&, absl::optional<size_t>) {
786 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
787 2050 : [](const StreamInfo::StreamInfo& stream_info) {
788 2050 : return stream_info.responseCode().value_or(0);
789 2050 : });
790 2050 : }}},
791 2050 : {"RESPONSE_CODE_DETAILS",
792 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
793 2050 : [](const std::string&, absl::optional<size_t>) {
794 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
795 2050 : [](const StreamInfo::StreamInfo& stream_info) {
796 2050 : return stream_info.responseCodeDetails();
797 2050 : });
798 2050 : }}},
799 2050 : {"CONNECTION_TERMINATION_DETAILS",
800 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
801 2050 : [](const std::string&, absl::optional<size_t>) {
802 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
803 2050 : [](const StreamInfo::StreamInfo& stream_info) {
804 2050 : return stream_info.connectionTerminationDetails();
805 2050 : });
806 2050 : }}},
807 2050 : {"BYTES_SENT",
808 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
809 2050 : [](const std::string&, absl::optional<size_t>) {
810 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
811 2050 : [](const StreamInfo::StreamInfo& stream_info) {
812 2050 : return stream_info.bytesSent();
813 2050 : });
814 2050 : }}},
815 2050 : {"UPSTREAM_WIRE_BYTES_SENT",
816 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
817 2050 : [](const std::string&, absl::optional<size_t>) {
818 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
819 2050 : [](const StreamInfo::StreamInfo& stream_info) {
820 2050 : const auto& bytes_meter = stream_info.getUpstreamBytesMeter();
821 2050 : return bytes_meter ? bytes_meter->wireBytesSent() : 0;
822 2050 : });
823 2050 : }}},
824 2050 : {"UPSTREAM_HEADER_BYTES_SENT",
825 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
826 2050 : [](const std::string&, absl::optional<size_t>) {
827 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
828 2050 : [](const StreamInfo::StreamInfo& stream_info) {
829 2050 : const auto& bytes_meter = stream_info.getUpstreamBytesMeter();
830 2050 : return bytes_meter ? bytes_meter->headerBytesSent() : 0;
831 2050 : });
832 2050 : }}},
833 2050 : {"DOWNSTREAM_WIRE_BYTES_SENT",
834 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
835 2050 : [](const std::string&, absl::optional<size_t>) {
836 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
837 2050 : [](const StreamInfo::StreamInfo& stream_info) {
838 2050 : const auto& bytes_meter = stream_info.getDownstreamBytesMeter();
839 2050 : return bytes_meter ? bytes_meter->wireBytesSent() : 0;
840 2050 : });
841 2050 : }}},
842 2050 : {"DOWNSTREAM_HEADER_BYTES_SENT",
843 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
844 2050 : [](const std::string&, absl::optional<size_t>) {
845 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
846 2050 : [](const StreamInfo::StreamInfo& stream_info) {
847 2050 : const auto& bytes_meter = stream_info.getDownstreamBytesMeter();
848 2050 : return bytes_meter ? bytes_meter->headerBytesSent() : 0;
849 2050 : });
850 2050 : }}},
851 2050 : {"DURATION",
852 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
853 2050 : [](const std::string&, absl::optional<size_t>) {
854 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
855 2050 : [](const StreamInfo::StreamInfo& stream_info) {
856 2050 : return stream_info.currentDuration();
857 2050 : });
858 2050 : }}},
859 2050 : {"RESPONSE_FLAGS",
860 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
861 2050 : [](const std::string&, absl::optional<size_t>) {
862 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
863 2050 : [](const StreamInfo::StreamInfo& stream_info) {
864 2050 : return StreamInfo::ResponseFlagUtils::toShortString(stream_info);
865 2050 : });
866 2050 : }}},
867 2050 : {"RESPONSE_FLAGS_LONG",
868 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
869 2050 : [](const std::string&, absl::optional<size_t>) {
870 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
871 2050 : [](const StreamInfo::StreamInfo& stream_info) {
872 2050 : return StreamInfo::ResponseFlagUtils::toString(stream_info);
873 2050 : });
874 2050 : }}},
875 2050 : {"UPSTREAM_HOST",
876 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
877 2050 : [](const std::string&, absl::optional<size_t>) {
878 2050 : return StreamInfoAddressFormatterProvider::withPort(
879 2050 : [](const StreamInfo::StreamInfo& stream_info)
880 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
881 2050 : if (stream_info.upstreamInfo() && stream_info.upstreamInfo()->upstreamHost()) {
882 2050 : return stream_info.upstreamInfo()->upstreamHost()->address();
883 2050 : }
884 2050 : return nullptr;
885 2050 : });
886 2050 : }}},
887 2050 : {"UPSTREAM_CLUSTER",
888 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
889 2050 : [](const std::string&, absl::optional<size_t>) {
890 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
891 2050 : [](const StreamInfo::StreamInfo& stream_info) {
892 2050 : std::string upstream_cluster_name;
893 2050 : if (stream_info.upstreamClusterInfo().has_value() &&
894 2050 : stream_info.upstreamClusterInfo().value() != nullptr) {
895 2050 : upstream_cluster_name =
896 2050 : stream_info.upstreamClusterInfo().value()->observabilityName();
897 2050 : }
898 :
899 2050 : return upstream_cluster_name.empty()
900 2050 : ? absl::nullopt
901 2050 : : absl::make_optional<std::string>(upstream_cluster_name);
902 2050 : });
903 2050 : }}},
904 2050 : {"UPSTREAM_LOCAL_ADDRESS",
905 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
906 2050 : [](const std::string&, absl::optional<size_t>) {
907 2050 : return StreamInfoAddressFormatterProvider::withPort(
908 2050 : [](const StreamInfo::StreamInfo& stream_info)
909 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
910 2050 : if (stream_info.upstreamInfo().has_value()) {
911 2050 : return stream_info.upstreamInfo().value().get().upstreamLocalAddress();
912 2050 : }
913 2050 : return nullptr;
914 2050 : });
915 2050 : }}},
916 2050 : {"UPSTREAM_LOCAL_ADDRESS_WITHOUT_PORT",
917 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
918 2050 : [](const std::string&, absl::optional<size_t>) {
919 2050 : return StreamInfoAddressFormatterProvider::withoutPort(
920 2050 : [](const StreamInfo::StreamInfo& stream_info)
921 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
922 2050 : if (stream_info.upstreamInfo().has_value()) {
923 2050 : return stream_info.upstreamInfo().value().get().upstreamLocalAddress();
924 2050 : }
925 2050 : return nullptr;
926 2050 : });
927 2050 : }}},
928 2050 : {"UPSTREAM_LOCAL_PORT",
929 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
930 2050 : [](const std::string&, absl::optional<size_t>) {
931 2050 : return StreamInfoAddressFormatterProvider::justPort(
932 2050 : [](const StreamInfo::StreamInfo& stream_info)
933 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
934 2050 : if (stream_info.upstreamInfo().has_value()) {
935 2050 : return stream_info.upstreamInfo().value().get().upstreamLocalAddress();
936 2050 : }
937 2050 : return nullptr;
938 2050 : });
939 2050 : }}},
940 2050 : {"UPSTREAM_REMOTE_ADDRESS",
941 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
942 2050 : [](const std::string&, absl::optional<size_t>) {
943 2050 : return StreamInfoAddressFormatterProvider::withPort(
944 2050 : [](const StreamInfo::StreamInfo& stream_info)
945 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
946 2050 : if (stream_info.upstreamInfo() && stream_info.upstreamInfo()->upstreamHost()) {
947 2050 : return stream_info.upstreamInfo()->upstreamHost()->address();
948 2050 : }
949 2050 : return nullptr;
950 2050 : });
951 2050 : }}},
952 2050 : {"UPSTREAM_REMOTE_ADDRESS_WITHOUT_PORT",
953 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
954 2050 : [](const std::string&, absl::optional<size_t>) {
955 2050 : return StreamInfoAddressFormatterProvider::withoutPort(
956 2050 : [](const StreamInfo::StreamInfo& stream_info)
957 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
958 2050 : if (stream_info.upstreamInfo() && stream_info.upstreamInfo()->upstreamHost()) {
959 2050 : return stream_info.upstreamInfo()->upstreamHost()->address();
960 2050 : }
961 2050 : return nullptr;
962 2050 : });
963 2050 : }}},
964 2050 : {"UPSTREAM_REMOTE_PORT",
965 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
966 2050 : [](const std::string&, absl::optional<size_t>) {
967 2050 : return StreamInfoAddressFormatterProvider::justPort(
968 2050 : [](const StreamInfo::StreamInfo& stream_info)
969 2050 : -> std::shared_ptr<const Envoy::Network::Address::Instance> {
970 2050 : if (stream_info.upstreamInfo() && stream_info.upstreamInfo()->upstreamHost()) {
971 2050 : return stream_info.upstreamInfo()->upstreamHost()->address();
972 2050 : }
973 2050 : return nullptr;
974 2050 : });
975 2050 : }}},
976 2050 : {"UPSTREAM_REQUEST_ATTEMPT_COUNT",
977 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
978 2050 : [](const std::string&, absl::optional<size_t>) {
979 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
980 2050 : [](const StreamInfo::StreamInfo& stream_info) {
981 2050 : return stream_info.attemptCount().value_or(0);
982 2050 : });
983 2050 : }}},
984 2050 : {"UPSTREAM_TLS_CIPHER",
985 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
986 2050 : [](const std::string&, absl::optional<size_t>) {
987 2050 : return std::make_unique<StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
988 2050 : [](const Ssl::ConnectionInfo& connection_info) {
989 2050 : return connection_info.ciphersuiteString();
990 2050 : });
991 2050 : }}},
992 2050 : {"UPSTREAM_TLS_VERSION",
993 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
994 2050 : [](const std::string&, absl::optional<size_t>) {
995 2050 : return std::make_unique<StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
996 2050 : [](const Ssl::ConnectionInfo& connection_info) {
997 2050 : return connection_info.tlsVersion();
998 2050 : });
999 2050 : }}},
1000 2050 : {"UPSTREAM_TLS_SESSION_ID",
1001 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1002 2050 : [](const std::string&, absl::optional<size_t>) {
1003 2050 : return std::make_unique<StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
1004 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1005 2050 : return connection_info.sessionId();
1006 2050 : });
1007 2050 : }}},
1008 2050 : {"UPSTREAM_PEER_ISSUER",
1009 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1010 2050 : [](const std::string&, absl::optional<size_t>) {
1011 2050 : return std::make_unique<StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
1012 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1013 2050 : return connection_info.issuerPeerCertificate();
1014 2050 : });
1015 2050 : }}},
1016 2050 : {"UPSTREAM_PEER_CERT",
1017 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1018 2050 : [](const std::string&, absl::optional<size_t>) {
1019 2050 : return std::make_unique<StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
1020 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1021 2050 : return connection_info.urlEncodedPemEncodedPeerCertificate();
1022 2050 : });
1023 2050 : }}},
1024 2050 : {"UPSTREAM_PEER_SUBJECT",
1025 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1026 2050 : [](const std::string&, absl::optional<size_t>) {
1027 2050 : return std::make_unique<StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
1028 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1029 2050 : return connection_info.subjectPeerCertificate();
1030 2050 : });
1031 2050 : }}},
1032 2050 : {"DOWNSTREAM_LOCAL_ADDRESS",
1033 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1034 2050 : [](const std::string&, absl::optional<size_t>) {
1035 2050 : return StreamInfoAddressFormatterProvider::withPort(
1036 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1037 2050 : return stream_info.downstreamAddressProvider().localAddress();
1038 2050 : });
1039 2050 : }}},
1040 2050 : {"DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT",
1041 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1042 2050 : [](const std::string&, absl::optional<size_t>) {
1043 2050 : return StreamInfoAddressFormatterProvider::withoutPort(
1044 2050 : [](const Envoy::StreamInfo::StreamInfo& stream_info) {
1045 2050 : return stream_info.downstreamAddressProvider().localAddress();
1046 2050 : });
1047 2050 : }}},
1048 2050 : {"DOWNSTREAM_LOCAL_PORT",
1049 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1050 2050 : [](const std::string&, absl::optional<size_t>) {
1051 2050 : return StreamInfoAddressFormatterProvider::justPort(
1052 2050 : [](const Envoy::StreamInfo::StreamInfo& stream_info) {
1053 2050 : return stream_info.downstreamAddressProvider().localAddress();
1054 2050 : });
1055 2050 : }}},
1056 2050 : {"DOWNSTREAM_REMOTE_ADDRESS",
1057 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1058 2050 : [](const std::string&, absl::optional<size_t>) {
1059 2050 : return StreamInfoAddressFormatterProvider::withPort(
1060 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1061 2050 : return stream_info.downstreamAddressProvider().remoteAddress();
1062 2050 : });
1063 2050 : }}},
1064 2050 : {"DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT",
1065 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1066 2050 : [](const std::string&, absl::optional<size_t>) {
1067 2050 : return StreamInfoAddressFormatterProvider::withoutPort(
1068 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1069 2050 : return stream_info.downstreamAddressProvider().remoteAddress();
1070 2050 : });
1071 2050 : }}},
1072 2050 : {"DOWNSTREAM_REMOTE_PORT",
1073 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1074 2050 : [](const std::string&, absl::optional<size_t>) {
1075 2050 : return StreamInfoAddressFormatterProvider::justPort(
1076 2050 : [](const Envoy::StreamInfo::StreamInfo& stream_info) {
1077 2050 : return stream_info.downstreamAddressProvider().remoteAddress();
1078 2050 : });
1079 2050 : }}},
1080 2050 : {"DOWNSTREAM_DIRECT_REMOTE_ADDRESS",
1081 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1082 2050 : [](const std::string&, absl::optional<size_t>) {
1083 2050 : return StreamInfoAddressFormatterProvider::withPort(
1084 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1085 2050 : return stream_info.downstreamAddressProvider().directRemoteAddress();
1086 2050 : });
1087 2050 : }}},
1088 2050 : {"DOWNSTREAM_DIRECT_REMOTE_ADDRESS_WITHOUT_PORT",
1089 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1090 2050 : [](const std::string&, absl::optional<size_t>) {
1091 2050 : return StreamInfoAddressFormatterProvider::withoutPort(
1092 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1093 2050 : return stream_info.downstreamAddressProvider().directRemoteAddress();
1094 2050 : });
1095 2050 : }}},
1096 2050 : {"DOWNSTREAM_DIRECT_REMOTE_PORT",
1097 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1098 2050 : [](const std::string&, absl::optional<size_t>) {
1099 2050 : return StreamInfoAddressFormatterProvider::justPort(
1100 2050 : [](const Envoy::StreamInfo::StreamInfo& stream_info) {
1101 2050 : return stream_info.downstreamAddressProvider().directRemoteAddress();
1102 2050 : });
1103 2050 : }}},
1104 2050 : {"CONNECTION_ID",
1105 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1106 2050 : [](const std::string&, absl::optional<size_t>) {
1107 2050 : return std::make_unique<StreamInfoUInt64FormatterProvider>(
1108 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1109 2050 : return stream_info.downstreamAddressProvider().connectionID().value_or(0);
1110 2050 : });
1111 2050 : }}},
1112 2050 : {"REQUESTED_SERVER_NAME",
1113 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1114 2050 : [](const std::string&, absl::optional<size_t>) {
1115 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1116 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1117 2050 : absl::optional<std::string> result;
1118 2050 : if (!stream_info.downstreamAddressProvider().requestedServerName().empty()) {
1119 2050 : result = std::string(
1120 2050 : stream_info.downstreamAddressProvider().requestedServerName());
1121 2050 : }
1122 2050 : return result;
1123 2050 : });
1124 2050 : }}},
1125 2050 : {"ROUTE_NAME",
1126 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1127 2050 : [](const std::string&, absl::optional<size_t>) {
1128 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1129 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1130 2050 : absl::optional<std::string> result;
1131 2050 : std::string route_name = stream_info.getRouteName();
1132 2050 : if (!route_name.empty()) {
1133 2050 : result = route_name;
1134 2050 : }
1135 2050 : return result;
1136 2050 : });
1137 2050 : }}},
1138 2050 : {"DOWNSTREAM_PEER_URI_SAN",
1139 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1140 2050 : [](const std::string&, absl::optional<size_t>) {
1141 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1142 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1143 2050 : return absl::StrJoin(connection_info.uriSanPeerCertificate(), ",");
1144 2050 : });
1145 2050 : }}},
1146 2050 : {"DOWNSTREAM_PEER_DNS_SAN",
1147 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1148 2050 : [](const std::string&, absl::optional<size_t>) {
1149 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1150 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1151 2050 : return absl::StrJoin(connection_info.dnsSansPeerCertificate(), ",");
1152 2050 : });
1153 2050 : }}},
1154 2050 : {"DOWNSTREAM_PEER_IP_SAN",
1155 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1156 2050 : [](const std::string&, absl::optional<size_t>) {
1157 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1158 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1159 2050 : return absl::StrJoin(connection_info.ipSansPeerCertificate(), ",");
1160 2050 : });
1161 2050 : }}},
1162 2050 : {"DOWNSTREAM_LOCAL_URI_SAN",
1163 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1164 2050 : [](const std::string&, absl::optional<size_t>) {
1165 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1166 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1167 2050 : return absl::StrJoin(connection_info.uriSanLocalCertificate(), ",");
1168 2050 : });
1169 2050 : }}},
1170 2050 : {"DOWNSTREAM_LOCAL_DNS_SAN",
1171 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1172 2050 : [](const std::string&, absl::optional<size_t>) {
1173 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1174 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1175 2050 : return absl::StrJoin(connection_info.dnsSansLocalCertificate(), ",");
1176 2050 : });
1177 2050 : }}},
1178 2050 : {"DOWNSTREAM_LOCAL_IP_SAN",
1179 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1180 2050 : [](const std::string&, absl::optional<size_t>) {
1181 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1182 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1183 2050 : return absl::StrJoin(connection_info.ipSansLocalCertificate(), ",");
1184 2050 : });
1185 2050 : }}},
1186 2050 : {"DOWNSTREAM_PEER_SUBJECT",
1187 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1188 2050 : [](const std::string&, absl::optional<size_t>) {
1189 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1190 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1191 2050 : return connection_info.subjectPeerCertificate();
1192 2050 : });
1193 2050 : }}},
1194 2050 : {"DOWNSTREAM_LOCAL_SUBJECT",
1195 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1196 2050 : [](const std::string&, absl::optional<size_t>) {
1197 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1198 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1199 2050 : return connection_info.subjectLocalCertificate();
1200 2050 : });
1201 2050 : }}},
1202 2050 : {"DOWNSTREAM_TLS_SESSION_ID",
1203 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1204 2050 : [](const std::string&, absl::optional<size_t>) {
1205 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1206 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1207 2050 : return connection_info.sessionId();
1208 2050 : });
1209 2050 : }}},
1210 2050 : {"DOWNSTREAM_TLS_CIPHER",
1211 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1212 2050 : [](const std::string&, absl::optional<size_t>) {
1213 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1214 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1215 2050 : return connection_info.ciphersuiteString();
1216 2050 : });
1217 2050 : }}},
1218 2050 : {"DOWNSTREAM_TLS_VERSION",
1219 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1220 2050 : [](const std::string&, absl::optional<size_t>) {
1221 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1222 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1223 2050 : return connection_info.tlsVersion();
1224 2050 : });
1225 2050 : }}},
1226 2050 : {"DOWNSTREAM_PEER_FINGERPRINT_256",
1227 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1228 2050 : [](const std::string&, absl::optional<size_t>) {
1229 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1230 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1231 2050 : return connection_info.sha256PeerCertificateDigest();
1232 2050 : });
1233 2050 : }}},
1234 2050 : {"DOWNSTREAM_PEER_FINGERPRINT_1",
1235 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1236 2050 : [](const std::string&, absl::optional<size_t>) {
1237 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1238 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1239 2050 : return connection_info.sha1PeerCertificateDigest();
1240 2050 : });
1241 2050 : }}},
1242 2050 : {"DOWNSTREAM_PEER_SERIAL",
1243 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1244 2050 : [](const std::string&, absl::optional<size_t>) {
1245 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1246 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1247 2050 : return connection_info.serialNumberPeerCertificate();
1248 2050 : });
1249 2050 : }}},
1250 2050 : {"DOWNSTREAM_PEER_ISSUER",
1251 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1252 2050 : [](const std::string&, absl::optional<size_t>) {
1253 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1254 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1255 2050 : return connection_info.issuerPeerCertificate();
1256 2050 : });
1257 2050 : }}},
1258 2050 : {"DOWNSTREAM_PEER_CERT",
1259 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1260 2050 : [](const std::string&, absl::optional<size_t>) {
1261 2050 : return std::make_unique<StreamInfoSslConnectionInfoFormatterProvider>(
1262 2050 : [](const Ssl::ConnectionInfo& connection_info) {
1263 2050 : return connection_info.urlEncodedPemEncodedPeerCertificate();
1264 2050 : });
1265 2050 : }}},
1266 2050 : {"DOWNSTREAM_TRANSPORT_FAILURE_REASON",
1267 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1268 2050 : [](const std::string&, absl::optional<size_t>) {
1269 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1270 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1271 2050 : absl::optional<std::string> result;
1272 2050 : if (!stream_info.downstreamTransportFailureReason().empty()) {
1273 2050 : result = absl::StrReplaceAll(stream_info.downstreamTransportFailureReason(),
1274 2050 : {{" ", "_"}});
1275 2050 : }
1276 2050 : return result;
1277 2050 : });
1278 2050 : }}},
1279 2050 : {"UPSTREAM_TRANSPORT_FAILURE_REASON",
1280 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1281 2050 : [](const std::string&, absl::optional<size_t>) {
1282 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1283 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1284 2050 : absl::optional<std::string> result;
1285 2050 : if (stream_info.upstreamInfo().has_value() &&
1286 2050 : !stream_info.upstreamInfo()
1287 2050 : .value()
1288 2050 : .get()
1289 2050 : .upstreamTransportFailureReason()
1290 2050 : .empty()) {
1291 2050 : result =
1292 2050 : stream_info.upstreamInfo().value().get().upstreamTransportFailureReason();
1293 2050 : }
1294 2050 : if (result) {
1295 2050 : std::replace(result->begin(), result->end(), ' ', '_');
1296 2050 : }
1297 2050 : return result;
1298 2050 : });
1299 2050 : }}},
1300 2050 : {"HOSTNAME",
1301 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1302 2050 : [](const std::string&, absl::optional<size_t>) {
1303 2050 : absl::optional<std::string> hostname = SubstitutionFormatUtils::getHostname();
1304 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1305 2050 : [hostname](const StreamInfo::StreamInfo&) { return hostname; });
1306 2050 : }}},
1307 2050 : {"FILTER_CHAIN_NAME",
1308 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1309 2050 : [](const std::string&, absl::optional<size_t>) {
1310 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1311 2050 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<std::string> {
1312 2050 : if (const auto info = stream_info.downstreamAddressProvider().filterChainInfo();
1313 2050 : info.has_value()) {
1314 2050 : if (!info->name().empty()) {
1315 2050 : return std::string(info->name());
1316 2050 : }
1317 2050 : }
1318 2050 : return absl::nullopt;
1319 2050 : });
1320 2050 : }}},
1321 2050 : {"VIRTUAL_CLUSTER_NAME",
1322 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1323 2050 : [](const std::string&, absl::optional<size_t>) {
1324 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1325 2050 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<std::string> {
1326 2050 : return stream_info.virtualClusterName();
1327 2050 : });
1328 2050 : }}},
1329 2050 : {"TLS_JA3_FINGERPRINT",
1330 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1331 2050 : [](const std::string&, absl::optional<size_t>) {
1332 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1333 2050 : [](const StreamInfo::StreamInfo& stream_info) {
1334 2050 : absl::optional<std::string> result;
1335 2050 : if (!stream_info.downstreamAddressProvider().ja3Hash().empty()) {
1336 2050 : result = std::string(stream_info.downstreamAddressProvider().ja3Hash());
1337 2050 : }
1338 2050 : return result;
1339 2050 : });
1340 2050 : }}},
1341 2050 : {"STREAM_ID",
1342 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1343 2050 : [](const std::string&, absl::optional<size_t>) {
1344 2050 : return std::make_unique<StreamInfoStringFormatterProvider>(
1345 2050 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<std::string> {
1346 2050 : auto provider = stream_info.getStreamIdProvider();
1347 2050 : if (!provider.has_value()) {
1348 2050 : return {};
1349 2050 : }
1350 2050 : auto id = provider->toStringView();
1351 2050 : if (!id.has_value()) {
1352 2050 : return {};
1353 2050 : }
1354 2050 : return absl::make_optional<std::string>(id.value());
1355 2050 : });
1356 2050 : }}},
1357 2050 : {"START_TIME",
1358 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL,
1359 2050 : [](const std::string& format, absl::optional<size_t>) {
1360 2050 : return std::make_unique<SystemTimeFormatter>(
1361 2050 : format,
1362 2050 : std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
1363 2050 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
1364 2050 : return stream_info.startTime();
1365 2050 : }));
1366 2050 : }}},
1367 2050 : {"EMIT_TIME",
1368 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL,
1369 2050 : [](const std::string& format, absl::optional<size_t>) {
1370 2050 : return std::make_unique<SystemTimeFormatter>(
1371 2050 : format,
1372 2050 : std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
1373 2050 : [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
1374 2050 : return stream_info.timeSource().systemTime();
1375 2050 : }));
1376 2050 : }}},
1377 2050 : {"DYNAMIC_METADATA",
1378 2050 : {CommandSyntaxChecker::PARAMS_REQUIRED,
1379 2050 : [](const std::string& format, absl::optional<size_t> max_length) {
1380 2050 : std::string filter_namespace;
1381 2050 : std::vector<std::string> path;
1382 :
1383 2050 : SubstitutionFormatUtils::parseSubcommand(format, ':', filter_namespace, path);
1384 2050 : return std::make_unique<DynamicMetadataFormatter>(filter_namespace, path, max_length);
1385 2050 : }}},
1386 :
1387 2050 : {"CLUSTER_METADATA",
1388 2050 : {CommandSyntaxChecker::PARAMS_REQUIRED,
1389 2050 : [](const std::string& format, absl::optional<size_t> max_length) {
1390 2050 : std::string filter_namespace;
1391 2050 : std::vector<std::string> path;
1392 :
1393 2050 : SubstitutionFormatUtils::parseSubcommand(format, ':', filter_namespace, path);
1394 2050 : return std::make_unique<ClusterMetadataFormatter>(filter_namespace, path, max_length);
1395 2050 : }}},
1396 2050 : {"UPSTREAM_METADATA",
1397 2050 : {CommandSyntaxChecker::PARAMS_REQUIRED,
1398 2050 : [](const std::string& format, absl::optional<size_t> max_length) {
1399 2050 : std::string filter_namespace;
1400 2050 : std::vector<std::string> path;
1401 :
1402 2050 : SubstitutionFormatUtils::parseSubcommand(format, ':', filter_namespace, path);
1403 2050 : return std::make_unique<UpstreamHostMetadataFormatter>(filter_namespace, path,
1404 2050 : max_length);
1405 2050 : }}},
1406 2050 : {"FILTER_STATE",
1407 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL | CommandSyntaxChecker::LENGTH_ALLOWED,
1408 2050 : [](const std::string& format, absl::optional<size_t> max_length) {
1409 2050 : return FilterStateFormatter::create(format, max_length, false);
1410 2050 : }}},
1411 2050 : {"UPSTREAM_FILTER_STATE",
1412 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL | CommandSyntaxChecker::LENGTH_ALLOWED,
1413 2050 : [](const std::string& format, absl::optional<size_t> max_length) {
1414 2050 : return FilterStateFormatter::create(format, max_length, true);
1415 2050 : }}},
1416 2050 : {"DOWNSTREAM_PEER_CERT_V_START",
1417 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL,
1418 2050 : [](const std::string& format, absl::optional<size_t>) {
1419 2050 : return std::make_unique<DownstreamPeerCertVStartFormatter>(format);
1420 2050 : }}},
1421 2050 : {"DOWNSTREAM_PEER_CERT_V_END",
1422 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL,
1423 2050 : [](const std::string& format, absl::optional<size_t>) {
1424 2050 : return std::make_unique<DownstreamPeerCertVEndFormatter>(format);
1425 2050 : }}},
1426 2050 : {"UPSTREAM_PEER_CERT_V_START",
1427 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL,
1428 2050 : [](const std::string& format, absl::optional<size_t>) {
1429 2050 : return std::make_unique<UpstreamPeerCertVStartFormatter>(format);
1430 2050 : }}},
1431 2050 : {"UPSTREAM_PEER_CERT_V_END",
1432 2050 : {CommandSyntaxChecker::PARAMS_OPTIONAL,
1433 2050 : [](const std::string& format, absl::optional<size_t>) {
1434 2050 : return std::make_unique<UpstreamPeerCertVEndFormatter>(format);
1435 2050 : }}},
1436 2050 : {"ENVIRONMENT",
1437 2050 : {CommandSyntaxChecker::PARAMS_REQUIRED | CommandSyntaxChecker::LENGTH_ALLOWED,
1438 2050 : [](const std::string& key, absl::optional<size_t> max_length) {
1439 2050 : return std::make_unique<EnvironmentFormatter>(key, max_length);
1440 2050 : }}},
1441 2050 : {"UPSTREAM_CONNECTION_POOL_READY_DURATION",
1442 2050 : {CommandSyntaxChecker::COMMAND_ONLY,
1443 2050 : [](const std::string&, const absl::optional<size_t>&) {
1444 2050 : return std::make_unique<StreamInfoDurationFormatterProvider>(
1445 2050 : [](const StreamInfo::StreamInfo& stream_info)
1446 2050 : -> absl::optional<std::chrono::nanoseconds> {
1447 2050 : if (auto upstream_info = stream_info.upstreamInfo();
1448 2050 : upstream_info.has_value()) {
1449 2050 : if (auto connection_pool_callback_latency =
1450 2050 : upstream_info.value()
1451 2050 : .get()
1452 2050 : .upstreamTiming()
1453 2050 : .connectionPoolCallbackLatency();
1454 2050 : connection_pool_callback_latency.has_value()) {
1455 2050 : return connection_pool_callback_latency;
1456 2050 : }
1457 2050 : }
1458 2050 : return absl::nullopt;
1459 2050 : });
1460 2050 : }}},
1461 2050 : });
1462 2050 : }
1463 :
1464 : } // namespace Formatter
1465 : } // namespace Envoy
|