LCOV - code coverage report
Current view: top level - source/common/formatter - stream_info_formatter.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 988 1234 80.1 %
Date: 2024-01-05 06:35:25 Functions: 34 60 56.7 %

          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

Generated by: LCOV version 1.15