1
#include "source/common/formatter/stream_info_formatter.h"
2

            
3
#include "source/common/common/random_generator.h"
4
#include "source/common/config/metadata.h"
5
#include "source/common/http/header_utility.h"
6
#include "source/common/http/headers.h"
7
#include "source/common/http/utility.h"
8
#include "source/common/json/json_utility.h"
9
#include "source/common/runtime/runtime_features.h"
10
#include "source/common/stream_info/utility.h"
11

            
12
#include "absl/strings/str_format.h"
13
#include "absl/strings/str_replace.h"
14
#include "re2/re2.h"
15

            
16
namespace Envoy {
17
namespace Formatter {
18

            
19
namespace {
20

            
21
static const std::string DefaultUnspecifiedValueString = "-";
22

            
23
// Helper function to format a list of attempted upstream hosts.
24
// The extractor function converts each host to a string representation.
25
using HostStringExtractor =
26
    std::function<absl::optional<std::string>(const Upstream::HostDescriptionConstSharedPtr&)>;
27

            
28
absl::optional<std::string> formatUpstreamHostsAttempted(const StreamInfo::StreamInfo& stream_info,
29
38
                                                         const HostStringExtractor& extractor) {
30
38
  const auto opt_ref = stream_info.upstreamInfo();
31
38
  if (!opt_ref.has_value()) {
32
    return absl::nullopt;
33
  }
34
38
  const auto& attempted_hosts = opt_ref->upstreamHostsAttempted();
35
38
  if (attempted_hosts.empty()) {
36
    return absl::nullopt;
37
  }
38
38
  std::vector<std::string> results;
39
38
  results.reserve(attempted_hosts.size());
40
62
  for (const auto& host : attempted_hosts) {
41
62
    auto result = extractor(host);
42
62
    if (result.has_value() && !result->empty()) {
43
54
      results.push_back(std::move(*result));
44
54
    }
45
62
  }
46
38
  if (results.empty()) {
47
8
    return absl::nullopt;
48
8
  }
49
30
  return absl::StrJoin(results, ",");
50
38
}
51

            
52
19056
const re2::RE2& getSystemTimeFormatNewlinePattern() {
53
19056
  CONSTRUCT_ON_FIRST_USE(re2::RE2, "%[-_0^#]*[1-9]*(E|O)?n");
54
19056
}
55

            
56
16
std::string detectedCloseTypeToString(StreamInfo::DetectedCloseType type) {
57
16
  switch (type) {
58
3
  case StreamInfo::DetectedCloseType::LocalReset:
59
3
    return "LocalReset";
60
4
  case StreamInfo::DetectedCloseType::RemoteReset:
61
4
    return "RemoteReset";
62
9
  case StreamInfo::DetectedCloseType::Normal:
63
9
    return "Normal";
64
16
  }
65
  return "";
66
16
}
67

            
68
Network::Address::InstanceConstSharedPtr
69
2560
getUpstreamRemoteAddress(const StreamInfo::StreamInfo& stream_info) {
70
2560
  auto opt_ref = stream_info.upstreamInfo();
71
2560
  if (!opt_ref.has_value()) {
72
5
    return nullptr;
73
5
  }
74

            
75
2555
  if (auto addr = opt_ref->upstreamRemoteAddress(); addr != nullptr) {
76
2549
    return addr;
77
2549
  }
78
6
  return nullptr;
79
2555
}
80

            
81
} // namespace
82

            
83
MetadataFormatter::MetadataFormatter(absl::string_view filter_namespace,
84
                                     const std::vector<absl::string_view>& path,
85
                                     absl::optional<size_t> max_length,
86
                                     MetadataFormatter::GetMetadataFunction get_func)
87
737
    : filter_namespace_(filter_namespace), path_(path.begin(), path.end()), max_length_(max_length),
88
737
      get_func_(get_func) {}
89

            
90
absl::optional<std::string>
91
2166
MetadataFormatter::formatMetadata(const envoy::config::core::v3::Metadata& metadata) const {
92
2166
  Protobuf::Value value = formatMetadataValue(metadata);
93
2166
  if (value.kind_case() == Protobuf::Value::kNullValue) {
94
110
    return absl::nullopt;
95
110
  }
96

            
97
2056
  std::string str;
98
2056
  str.reserve(256);
99
2056
  if (value.kind_case() == Protobuf::Value::kStringValue) {
100
1986
    str = value.string_value();
101
2041
  } else {
102
70
    Json::Utility::appendValueToString(value, str);
103
70
  }
104
2056
  SubstitutionFormatUtils::truncate(str, max_length_);
105
2056
  return str;
106
2166
}
107

            
108
Protobuf::Value
109
2191
MetadataFormatter::formatMetadataValue(const envoy::config::core::v3::Metadata& metadata) const {
110
2191
  if (path_.empty()) {
111
32
    const auto filter_it = metadata.filter_metadata().find(filter_namespace_);
112
32
    if (filter_it == metadata.filter_metadata().end()) {
113
2
      return SubstitutionFormatUtils::unspecifiedValue();
114
2
    }
115
30
    Protobuf::Value output;
116
30
    output.mutable_struct_value()->CopyFrom(filter_it->second);
117
30
    return output;
118
32
  }
119

            
120
2159
  const Protobuf::Value& val = Config::Metadata::metadataValue(&metadata, filter_namespace_, path_);
121
2159
  if (val.kind_case() == Protobuf::Value::KindCase::KIND_NOT_SET) {
122
117
    return SubstitutionFormatUtils::unspecifiedValue();
123
117
  }
124

            
125
2042
  if (max_length_.has_value() && val.kind_case() != Protobuf::Value::kStructValue &&
126
2042
      val.kind_case() != Protobuf::Value::kListValue) {
127
8
    std::string str;
128
8
    if (val.kind_case() == Protobuf::Value::kStringValue) {
129
8
      str = val.string_value();
130
8
    } else {
131
      Json::Utility::appendValueToString(val, str);
132
    }
133
8
    if (SubstitutionFormatUtils::truncate(str, max_length_)) {
134
8
      Protobuf::Value output;
135
8
      output.set_string_value(str);
136
8
      return output;
137
8
    }
138
8
  }
139

            
140
2034
  return val;
141
2042
}
142

            
143
absl::optional<std::string>
144
3677
MetadataFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
145
3677
  auto metadata = get_func_(stream_info);
146
3677
  return (metadata != nullptr) ? formatMetadata(*metadata) : absl::nullopt;
147
3677
}
148

            
149
25
Protobuf::Value MetadataFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
150
25
  auto metadata = get_func_(stream_info);
151
25
  return formatMetadataValue((metadata != nullptr) ? *metadata
152
25
                                                   : envoy::config::core::v3::Metadata());
153
25
}
154

            
155
// TODO(glicht): Consider adding support for route/listener/cluster metadata as suggested by
156
// @htuch. See: https://github.com/envoyproxy/envoy/issues/3006
157
DynamicMetadataFormatter::DynamicMetadataFormatter(absl::string_view filter_namespace,
158
                                                   const std::vector<absl::string_view>& path,
159
                                                   absl::optional<size_t> max_length)
160
631
    : MetadataFormatter(filter_namespace, path, max_length,
161
1116
                        [](const StreamInfo::StreamInfo& stream_info) {
162
1114
                          return &stream_info.dynamicMetadata();
163
1116
                        }) {}
164

            
165
ClusterMetadataFormatter::ClusterMetadataFormatter(absl::string_view filter_namespace,
166
                                                   const std::vector<absl::string_view>& path,
167
                                                   absl::optional<size_t> max_length)
168
11
    : MetadataFormatter(filter_namespace, path, max_length,
169
11
                        [](const StreamInfo::StreamInfo& stream_info)
170
13
                            -> const envoy::config::core::v3::Metadata* {
171
13
                          auto cluster_info = stream_info.upstreamClusterInfo();
172
13
                          if (!cluster_info.has_value() || cluster_info.value() == nullptr) {
173
4
                            return nullptr;
174
4
                          }
175
9
                          return &cluster_info.value()->metadata();
176
13
                        }) {}
177

            
178
UpstreamHostMetadataFormatter::UpstreamHostMetadataFormatter(
179
    absl::string_view filter_namespace, const std::vector<absl::string_view>& path,
180
    absl::optional<size_t> max_length)
181
81
    : MetadataFormatter(filter_namespace, path, max_length,
182
81
                        [](const StreamInfo::StreamInfo& stream_info)
183
2589
                            -> const envoy::config::core::v3::Metadata* {
184
2561
                          if (!stream_info.upstreamInfo().has_value()) {
185
6
                            return nullptr;
186
6
                          }
187
2555
                          Upstream::HostDescriptionConstSharedPtr host =
188
2555
                              stream_info.upstreamInfo()->upstreamHost();
189
2555
                          if (host == nullptr) {
190
1
                            return nullptr;
191
1
                          }
192
2554
                          return host->metadata().get();
193
2583
                        }) {}
194

            
195
std::unique_ptr<FilterStateFormatter>
196
FilterStateFormatter::create(absl::string_view format, absl::optional<size_t> max_length,
197
924
                             bool is_upstream) {
198
924
  absl::string_view key, serialize_type, field_name;
199
924
  static constexpr absl::string_view PLAIN_SERIALIZATION{"PLAIN"};
200
924
  static constexpr absl::string_view TYPED_SERIALIZATION{"TYPED"};
201
924
  static constexpr absl::string_view FIELD_SERIALIZATION{"FIELD"};
202

            
203
924
  SubstitutionFormatUtils::parseSubcommand(format, ':', key, serialize_type, field_name);
204
924
  if (key.empty()) {
205
1
    throw EnvoyException("Invalid filter state configuration, key cannot be empty.");
206
1
  }
207

            
208
923
  if (serialize_type.empty()) {
209
37
    serialize_type = TYPED_SERIALIZATION;
210
37
  }
211
923
  if (serialize_type != PLAIN_SERIALIZATION && serialize_type != TYPED_SERIALIZATION &&
212
923
      serialize_type != FIELD_SERIALIZATION) {
213
3
    throw EnvoyException("Invalid filter state serialize type, only "
214
3
                         "support PLAIN/TYPED/FIELD.");
215
3
  }
216
920
  if ((serialize_type == FIELD_SERIALIZATION) ^ !field_name.empty()) {
217
2
    throw EnvoyException("Invalid filter state serialize type, FIELD "
218
2
                         "should be used with the field name.");
219
2
  }
220

            
221
918
  const bool serialize_as_string = serialize_type == PLAIN_SERIALIZATION;
222

            
223
918
  return std::make_unique<FilterStateFormatter>(key, max_length, serialize_as_string, is_upstream,
224
918
                                                field_name);
225
920
}
226

            
227
FilterStateFormatter::FilterStateFormatter(absl::string_view key, absl::optional<size_t> max_length,
228
                                           bool serialize_as_string, bool is_upstream,
229
                                           absl::string_view field_name)
230
932
    : key_(key), max_length_(max_length), is_upstream_(is_upstream) {
231
932
  if (!field_name.empty()) {
232
595
    format_ = FilterStateFormat::Field;
233
595
    field_name_ = std::string(field_name);
234
881
  } else if (serialize_as_string) {
235
135
    format_ = FilterStateFormat::String;
236
308
  } else {
237
202
    format_ = FilterStateFormat::Proto;
238
202
  }
239
932
}
240

            
241
const Envoy::StreamInfo::FilterState::Object*
242
946
FilterStateFormatter::filterState(const StreamInfo::StreamInfo& stream_info) const {
243
946
  const StreamInfo::FilterState* filter_state = nullptr;
244
946
  if (is_upstream_) {
245
9
    const OptRef<const StreamInfo::UpstreamInfo> upstream_info = stream_info.upstreamInfo();
246
9
    if (upstream_info) {
247
9
      filter_state = upstream_info->upstreamFilterState().get();
248
9
    }
249
939
  } else {
250
937
    filter_state = &stream_info.filterState();
251
937
  }
252

            
253
946
  if (filter_state) {
254
946
    return filter_state->getDataReadOnly<StreamInfo::FilterState::Object>(key_);
255
946
  }
256

            
257
  return nullptr;
258
946
}
259

            
260
struct StringFieldVisitor {
261
353
  absl::optional<std::string> operator()(int64_t val) { return absl::StrCat(val); }
262
6
  absl::optional<std::string> operator()(absl::string_view val) { return std::string(val); }
263
239
  absl::optional<std::string> operator()(absl::monostate) { return {}; }
264
};
265

            
266
absl::optional<std::string>
267
292
FilterStateFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
268
292
  const Envoy::StreamInfo::FilterState::Object* state = filterState(stream_info);
269
292
  if (!state) {
270
112
    return absl::nullopt;
271
112
  }
272

            
273
180
  switch (format_) {
274
54
  case FilterStateFormat::String: {
275
54
    absl::optional<std::string> plain_value = state->serializeAsString();
276
54
    if (plain_value.has_value()) {
277
53
      SubstitutionFormatUtils::truncate(plain_value.value(), max_length_);
278
53
      return plain_value.value();
279
53
    }
280
1
    return absl::nullopt;
281
54
  }
282
122
  case FilterStateFormat::Proto: {
283
122
    ProtobufTypes::MessagePtr proto = state->serializeAsProto();
284
122
    if (proto == nullptr) {
285
1
      return absl::nullopt;
286
1
    }
287

            
288
121
#if defined(ENVOY_ENABLE_FULL_PROTOS)
289
121
    std::string value;
290
121
    const auto status = Protobuf::util::MessageToJsonString(*proto, &value);
291
121
    if (!status.ok()) {
292
      // If the message contains an unknown Any (from WASM or Lua), MessageToJsonString will fail.
293
      // TODO(lizan): add support of unknown Any.
294
2
      return absl::nullopt;
295
2
    }
296

            
297
119
    SubstitutionFormatUtils::truncate(value, max_length_);
298
119
    return value;
299
#else
300
    PANIC("FilterStateFormatter::format requires full proto support");
301
    return absl::nullopt;
302
#endif
303
121
  }
304
4
  case FilterStateFormat::Field: {
305
4
    auto field_value = state->getField(field_name_);
306
4
    auto string_value = absl::visit(StringFieldVisitor(), field_value);
307
4
    if (!string_value) {
308
1
      return absl::nullopt;
309
1
    }
310
3
    SubstitutionFormatUtils::truncate(string_value.value(), max_length_);
311
3
    return string_value;
312
4
  }
313
  default:
314
    return absl::nullopt;
315
180
  }
316
180
}
317

            
318
654
Protobuf::Value FilterStateFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
319
654
  const Envoy::StreamInfo::FilterState::Object* state = filterState(stream_info);
320
654
  if (!state) {
321
3
    return SubstitutionFormatUtils::unspecifiedValue();
322
3
  }
323

            
324
651
  switch (format_) {
325
24
  case FilterStateFormat::String: {
326
24
    absl::optional<std::string> plain_value = state->serializeAsString();
327
24
    if (plain_value.has_value()) {
328
23
      SubstitutionFormatUtils::truncate(plain_value.value(), max_length_);
329
23
      return ValueUtil::stringValue(plain_value.value());
330
23
    }
331
1
    return SubstitutionFormatUtils::unspecifiedValue();
332
24
  }
333
33
  case FilterStateFormat::Proto: {
334
33
    ProtobufTypes::MessagePtr proto = state->serializeAsProto();
335
33
    if (!proto) {
336
1
      return SubstitutionFormatUtils::unspecifiedValue();
337
1
    }
338

            
339
32
#ifdef ENVOY_ENABLE_YAML
340
32
    Protobuf::Value val;
341
32
    if (MessageUtil::jsonConvertValue(*proto, val)) {
342
31
      return val;
343
31
    }
344
1
#endif
345
1
    return SubstitutionFormatUtils::unspecifiedValue();
346
32
  }
347
594
  case FilterStateFormat::Field: {
348
594
    auto field_value = state->getField(field_name_);
349
594
    auto string_value = absl::visit(StringFieldVisitor(), field_value);
350
594
    if (!string_value) {
351
238
      return SubstitutionFormatUtils::unspecifiedValue();
352
238
    }
353
356
    SubstitutionFormatUtils::truncate(string_value.value(), max_length_);
354
356
    return ValueUtil::stringValue(string_value.value());
355
594
  }
356
  default:
357
    return SubstitutionFormatUtils::unspecifiedValue();
358
651
  }
359
651
}
360

            
361
const absl::flat_hash_map<absl::string_view, CommonDurationFormatter::TimePointGetter>
362
    CommonDurationFormatter::KnownTimePointGetters{
363
        {FirstDownstreamRxByteReceived,
364
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
365
288
           return stream_info.startTimeMonotonic();
366
288
         }},
367
        {LastDownstreamRxByteReceived,
368
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
369
288
           const auto downstream_timing = stream_info.downstreamTiming();
370
288
           if (downstream_timing.has_value()) {
371
288
             return downstream_timing->lastDownstreamRxByteReceived();
372
288
           }
373
           return {};
374
288
         }},
375
        {UpstreamConnectStart,
376
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
377
288
           const auto upstream_info = stream_info.upstreamInfo();
378
288
           if (upstream_info.has_value()) {
379
288
             return upstream_info->upstreamTiming().upstream_connect_start_;
380
288
           }
381
           return {};
382
288
         }},
383
        {UpstreamConnectEnd,
384
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
385
288
           const auto upstream_info = stream_info.upstreamInfo();
386
288
           if (upstream_info.has_value()) {
387
288
             return upstream_info->upstreamTiming().upstream_connect_complete_;
388
288
           }
389
           return {};
390
288
         }},
391
        {UpstreamTLSConnectEnd,
392
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
393
288
           const auto upstream_info = stream_info.upstreamInfo();
394
288
           if (upstream_info.has_value()) {
395
288
             return upstream_info->upstreamTiming().upstream_handshake_complete_;
396
288
           }
397
           return {};
398
288
         }},
399
        {FirstUpstreamTxByteSent,
400
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
401
288
           const auto upstream_info = stream_info.upstreamInfo();
402
288
           if (upstream_info.has_value()) {
403
288
             return upstream_info->upstreamTiming().first_upstream_tx_byte_sent_;
404
288
           }
405
           return {};
406
288
         }},
407
        {LastUpstreamTxByteSent,
408
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
409
288
           const auto upstream_info = stream_info.upstreamInfo();
410
288
           if (upstream_info.has_value()) {
411
288
             return upstream_info->upstreamTiming().last_upstream_tx_byte_sent_;
412
288
           }
413
           return {};
414
288
         }},
415
        {FirstUpstreamRxByteReceived,
416
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
417
288
           const auto upstream_info = stream_info.upstreamInfo();
418
288
           if (upstream_info.has_value()) {
419
288
             return upstream_info->upstreamTiming().first_upstream_rx_byte_received_;
420
288
           }
421
           return {};
422
288
         }},
423
        {FirstUpstreamRxBodyReceived,
424
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
425
           const auto upstream_info = stream_info.upstreamInfo();
426
           if (upstream_info.has_value()) {
427
             return upstream_info->upstreamTiming().first_upstream_rx_body_byte_received_;
428
           }
429
           return {};
430
         }},
431
        {LastUpstreamRxByteReceived,
432
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
433
288
           const auto upstream_info = stream_info.upstreamInfo();
434
288
           if (upstream_info.has_value()) {
435
288
             return upstream_info->upstreamTiming().last_upstream_rx_byte_received_;
436
288
           }
437
           return {};
438
288
         }},
439
        {FirstDownstreamTxByteSent,
440
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
441
288
           const auto downstream_timing = stream_info.downstreamTiming();
442
288
           if (downstream_timing.has_value()) {
443
288
             return downstream_timing->firstDownstreamTxByteSent();
444
288
           }
445
           return {};
446
288
         }},
447
        {LastDownstreamTxByteSent,
448
288
         [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<MonotonicTime> {
449
288
           const auto downstream_timing = stream_info.downstreamTiming();
450
288
           if (downstream_timing.has_value()) {
451
288
             return downstream_timing->lastDownstreamTxByteSent();
452
288
           }
453
           return {};
454
288
         }},
455
    };
456

            
457
CommonDurationFormatter::TimePointGetter
458
1728
CommonDurationFormatter::getTimePointGetterByName(absl::string_view name) {
459
1728
  auto it = KnownTimePointGetters.find(name);
460
1728
  if (it != KnownTimePointGetters.end()) {
461
1584
    return it->second;
462
1584
  }
463

            
464
288
  return [key = std::string(name)](const StreamInfo::StreamInfo& info) {
465
288
    const auto downstream_timing = info.downstreamTiming();
466
288
    if (downstream_timing.has_value()) {
467
288
      return downstream_timing->getValue(key);
468
288
    }
469
    return absl::optional<MonotonicTime>{};
470
288
  };
471
1728
}
472

            
473
std::unique_ptr<CommonDurationFormatter>
474
867
CommonDurationFormatter::create(absl::string_view sub_command) {
475
  // Split the sub_command by ':'.
476
867
  absl::InlinedVector<absl::string_view, 3> parsed_sub_commands = absl::StrSplit(sub_command, ':');
477

            
478
867
  if (parsed_sub_commands.size() < 2 || parsed_sub_commands.size() > 3) {
479
2
    throw EnvoyException(fmt::format("Invalid common duration configuration: {}.", sub_command));
480
2
  }
481

            
482
865
  absl::string_view start = parsed_sub_commands[0];
483
865
  absl::string_view end = parsed_sub_commands[1];
484

            
485
  // Milliseconds is the default precision.
486
865
  DurationPrecision precision = DurationPrecision::Milliseconds;
487

            
488
865
  if (parsed_sub_commands.size() == 3) {
489
865
    absl::string_view precision_str = parsed_sub_commands[2];
490
865
    if (precision_str == MillisecondsPrecision) {
491
288
      precision = DurationPrecision::Milliseconds;
492
577
    } else if (precision_str == MicrosecondsPrecision) {
493
288
      precision = DurationPrecision::Microseconds;
494
289
    } else if (precision_str == NanosecondsPrecision) {
495
288
      precision = DurationPrecision::Nanoseconds;
496
288
    } else {
497
1
      throw EnvoyException(fmt::format("Invalid common duration precision: {}.", precision_str));
498
1
    }
499
865
  }
500

            
501
864
  TimePointGetter start_getter = getTimePointGetterByName(start);
502
864
  TimePointGetter end_getter = getTimePointGetterByName(end);
503

            
504
864
  return std::make_unique<CommonDurationFormatter>(std::move(start_getter), std::move(end_getter),
505
864
                                                   precision);
506
865
}
507

            
508
absl::optional<uint64_t>
509
1728
CommonDurationFormatter::getDurationCount(const StreamInfo::StreamInfo& info) const {
510
1728
  auto time_point_beg = time_point_beg_(info);
511
1728
  auto time_point_end = time_point_end_(info);
512

            
513
1728
  if (!time_point_beg.has_value() || !time_point_end.has_value()) {
514
858
    return absl::nullopt;
515
858
  }
516

            
517
870
  if (time_point_end.value() < time_point_beg.value()) {
518
396
    return absl::nullopt;
519
396
  }
520

            
521
474
  auto duration = time_point_end.value() - time_point_beg.value();
522

            
523
474
  switch (duration_precision_) {
524
158
  case DurationPrecision::Milliseconds:
525
158
    return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
526
158
  case DurationPrecision::Microseconds:
527
158
    return std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
528
158
  case DurationPrecision::Nanoseconds:
529
158
    return std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
530
474
  }
531
  PANIC("Invalid duration precision");
532
}
533

            
534
absl::optional<std::string>
535
864
CommonDurationFormatter::format(const StreamInfo::StreamInfo& info) const {
536
864
  auto duration = getDurationCount(info);
537
864
  if (!duration.has_value()) {
538
627
    return absl::nullopt;
539
627
  }
540
237
  return fmt::format_int(duration.value()).str();
541
864
}
542
864
Protobuf::Value CommonDurationFormatter::formatValue(const StreamInfo::StreamInfo& info) const {
543
864
  auto duration = getDurationCount(info);
544
864
  if (!duration.has_value()) {
545
627
    return SubstitutionFormatUtils::unspecifiedValue();
546
627
  }
547
237
  return ValueUtil::numberValue(duration.value());
548
864
}
549

            
550
// A SystemTime formatter that extracts the startTime from StreamInfo. Must be provided
551
// an access log command that starts with `START_TIME`.
552
StartTimeFormatter::StartTimeFormatter(absl::string_view format)
553
2
    : SystemTimeFormatter(
554
2
          format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
555
4
                      [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
556
4
                        return stream_info.startTime();
557
4
                      })) {}
558

            
559
DownstreamPeerCertVStartFormatter::DownstreamPeerCertVStartFormatter(absl::string_view format)
560
11
    : SystemTimeFormatter(
561
11
          format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
562
15
                      [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
563
15
                        const auto connection_info =
564
15
                            stream_info.downstreamAddressProvider().sslConnection();
565
15
                        return connection_info != nullptr
566
15
                                   ? connection_info->validFromPeerCertificate()
567
15
                                   : absl::optional<SystemTime>();
568
15
                      })) {}
569
DownstreamPeerCertVEndFormatter::DownstreamPeerCertVEndFormatter(absl::string_view format)
570
9
    : SystemTimeFormatter(
571
9
          format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
572
11
                      [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
573
11
                        const auto connection_info =
574
11
                            stream_info.downstreamAddressProvider().sslConnection();
575
11
                        return connection_info != nullptr
576
11
                                   ? connection_info->expirationPeerCertificate()
577
11
                                   : absl::optional<SystemTime>();
578
11
                      })) {}
579
UpstreamPeerCertVStartFormatter::UpstreamPeerCertVStartFormatter(absl::string_view format)
580
3
    : SystemTimeFormatter(
581
3
          format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
582
4
                      [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
583
4
                        return stream_info.upstreamInfo() &&
584
4
                                       stream_info.upstreamInfo()->upstreamSslConnection() !=
585
4
                                           nullptr
586
4
                                   ? stream_info.upstreamInfo()
587
2
                                         ->upstreamSslConnection()
588
2
                                         ->validFromPeerCertificate()
589
4
                                   : absl::optional<SystemTime>();
590
4
                      })) {}
591
UpstreamPeerCertVEndFormatter::UpstreamPeerCertVEndFormatter(absl::string_view format)
592
5
    : SystemTimeFormatter(
593
5
          format, std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
594
8
                      [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<SystemTime> {
595
8
                        return stream_info.upstreamInfo() &&
596
8
                                       stream_info.upstreamInfo()->upstreamSslConnection() !=
597
8
                                           nullptr
598
8
                                   ? stream_info.upstreamInfo()
599
4
                                         ->upstreamSslConnection()
600
4
                                         ->expirationPeerCertificate()
601
8
                                   : absl::optional<SystemTime>();
602
8
                      })) {}
603

            
604
SystemTimeFormatter::SystemTimeFormatter(absl::string_view format, TimeFieldExtractorPtr f,
605
                                         bool local_time)
606
19056
    : date_formatter_(format, local_time), time_field_extractor_(std::move(f)),
607
19056
      local_time_(local_time) {
608
  // Validate the input specifier here. The formatted string may be destined for a header, and
609
  // should not contain invalid characters {NUL, LR, CF}.
610
19056
  if (re2::RE2::PartialMatch(format, getSystemTimeFormatNewlinePattern())) {
611
6
    throw EnvoyException("Invalid header configuration. Format string contains newline.");
612
6
  }
613
19056
}
614

            
615
absl::optional<std::string>
616
72283
SystemTimeFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
617
72283
  const auto time_field = (*time_field_extractor_)(stream_info);
618
72283
  if (!time_field.has_value()) {
619
20
    return absl::nullopt;
620
20
  }
621
72263
  if (date_formatter_.formatString().empty()) {
622
72215
    return AccessLogDateTimeFormatter::fromTime(time_field.value(), local_time_);
623
72215
  }
624
48
  return date_formatter_.fromTime(time_field.value());
625
72263
}
626

            
627
19
Protobuf::Value SystemTimeFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
628
19
  return ValueUtil::optionalStringValue(format(stream_info));
629
19
}
630

            
631
EnvironmentFormatter::EnvironmentFormatter(absl::string_view key,
632
6
                                           absl::optional<size_t> max_length) {
633
6
  ASSERT(!key.empty());
634

            
635
6
  const std::string key_str = std::string(key);
636
6
  const char* env_value = std::getenv(key_str.c_str());
637
6
  if (env_value != nullptr) {
638
5
    std::string env_string = env_value;
639
5
    SubstitutionFormatUtils::truncate(env_string, max_length);
640
5
    str_.set_string_value(env_string);
641
5
    return;
642
5
  }
643
1
  str_.set_string_value(DefaultUnspecifiedValueString);
644
1
}
645

            
646
3
absl::optional<std::string> EnvironmentFormatter::format(const StreamInfo::StreamInfo&) const {
647
3
  return str_.string_value();
648
3
}
649
3
Protobuf::Value EnvironmentFormatter::formatValue(const StreamInfo::StreamInfo&) const {
650
3
  return str_;
651
3
}
652

            
653
RequestedServerNameFormatter::RequestedServerNameFormatter(absl::string_view source,
654
27
                                                           absl::string_view option) {
655

            
656
27
  HostFormatterSource host_source = SNI;
657
27
  HostFormatterOption option_enum = OriginalHostOrHost;
658

            
659
27
  if (source == "SNI_ONLY") {
660
1
    host_source = SNI;
661
26
  } else if (source == "SNI_FIRST") {
662
3
    host_source = SNIFirst;
663
23
  } else if (source == "HOST_FIRST") {
664
2
    host_source = HostFirst;
665
21
  } else if (source.empty()) {
666
21
    host_source = SNI;
667
21
  } else {
668
    throw EnvoyException(fmt::format("Invalid REQUESTED_SERVER_NAME option: '{}', only "
669
                                     "'SNI_ONLY'/'SNI_FIRST'/'HOST_FIRST' are allowed",
670
                                     source));
671
  }
672

            
673
27
  if (option == "ORIG_OR_HOST") {
674
1
    option_enum = OriginalHostOrHost;
675
26
  } else if (option == "HOST") {
676
2
    option_enum = HostOnly;
677
24
  } else if (option == "ORIG") {
678
    option_enum = OriginalHostOnly;
679
24
  } else if (option.empty()) {
680
24
    option_enum = OriginalHostOrHost;
681
24
  } else {
682
    throw EnvoyException(fmt::format("Invalid REQUESTED_SERVER_NAME option: '{}', only "
683
                                     "'ORIG_OR_HOST'/'HOST'/'ORIG' are allowed",
684
                                     option));
685
  }
686
27
  source_ = host_source;
687
27
  option_ = option_enum;
688
27
}
689

            
690
absl::optional<std::string>
691
40
RequestedServerNameFormatter::format(const StreamInfo::StreamInfo& stream_info) const {
692
40
  absl::optional<std::string> result;
693
40
  switch (source_) {
694
30
  case SNI:
695
30
    result = getSNIFromStreamInfo(stream_info);
696
30
    break;
697
6
  case SNIFirst:
698
6
    result = getSNIFromStreamInfo(stream_info);
699
6
    if (!result.has_value()) {
700
3
      result = getHostFromHeaders(stream_info);
701
3
    }
702
6
    break;
703
4
  case HostFirst:
704
4
    result = getHostFromHeaders(stream_info);
705
4
    if (!result.has_value()) {
706
      result = getSNIFromStreamInfo(stream_info);
707
    }
708
4
    break;
709
40
  }
710
40
  return result;
711
40
}
712

            
713
absl::optional<std::string> RequestedServerNameFormatter::getSNIFromStreamInfo(
714
36
    const StreamInfo::StreamInfo& stream_info) const {
715
36
  absl::optional<std::string> result;
716
36
  if (!stream_info.downstreamAddressProvider().requestedServerName().empty()) {
717
23
    result = StringUtil::sanitizeInvalidHostname(
718
23
        stream_info.downstreamAddressProvider().requestedServerName());
719
23
  }
720
36
  return result;
721
36
}
722

            
723
absl::optional<std::string>
724
7
RequestedServerNameFormatter::getHostFromHeaders(const StreamInfo::StreamInfo& stream_info) const {
725
7
  absl::optional<std::string> result;
726
7
  const auto& headers = stream_info.getRequestHeaders();
727
7
  if (headers != nullptr) {
728
7
    switch (option_) {
729
3
    case HostOnly:
730
3
      result = headers->Host()->value().getStringView();
731
3
      break;
732
    case OriginalHostOnly:
733
      result = headers->EnvoyOriginalHost()->value().getStringView();
734
      break;
735
4
    case OriginalHostOrHost:
736
4
      result = headers->EnvoyOriginalHost() != nullptr
737
4
                   ? headers->EnvoyOriginalHost()->value().getStringView()
738
4
                   : headers->Host()->value().getStringView();
739
4
      break;
740
7
    }
741
7
  }
742
7
  return result;
743
7
}
744

            
745
Protobuf::Value
746
7
RequestedServerNameFormatter::formatValue(const StreamInfo::StreamInfo& stream_info) const {
747
7
  return ValueUtil::optionalStringValue(format(stream_info));
748
7
}
749

            
750
// StreamInfo std::string formatter provider.
751
class StreamInfoStringFormatterProvider : public StreamInfoFormatterProvider {
752
public:
753
  using FieldExtractor = std::function<absl::optional<std::string>(const StreamInfo::StreamInfo&)>;
754

            
755
39598
  StreamInfoStringFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
756

            
757
  // StreamInfoFormatterProvider
758
  // Don't hide the other structure of format and formatValue.
759
  using StreamInfoFormatterProvider::format;
760
  using StreamInfoFormatterProvider::formatValue;
761
146590
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
762
146590
    return field_extractor_(stream_info);
763
146590
  }
764
91
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
765
91
    return ValueUtil::optionalStringValue(field_extractor_(stream_info));
766
91
  }
767

            
768
private:
769
  FieldExtractor field_extractor_;
770
};
771

            
772
// StreamInfo std::chrono_nanoseconds field extractor.
773
class StreamInfoDurationFormatterProvider : public StreamInfoFormatterProvider {
774
public:
775
  using FieldExtractor =
776
      std::function<absl::optional<std::chrono::nanoseconds>(const StreamInfo::StreamInfo&)>;
777

            
778
19143
  StreamInfoDurationFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
779

            
780
  // StreamInfoFormatterProvider
781
  // Don't hide the other structure of format and formatValue.
782
  using StreamInfoFormatterProvider::format;
783
  using StreamInfoFormatterProvider::formatValue;
784
72413
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
785
72413
    const auto millis = extractMillis(stream_info);
786
72413
    if (!millis) {
787
46
      return absl::nullopt;
788
46
    }
789

            
790
72367
    return fmt::format_int(millis.value()).str();
791
72413
  }
792
18
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
793
18
    const auto millis = extractMillis(stream_info);
794
18
    if (!millis) {
795
7
      return SubstitutionFormatUtils::unspecifiedValue();
796
7
    }
797

            
798
11
    return ValueUtil::numberValue(millis.value());
799
18
  }
800

            
801
private:
802
72431
  absl::optional<int64_t> extractMillis(const StreamInfo::StreamInfo& stream_info) const {
803
72431
    const auto time = field_extractor_(stream_info);
804
72431
    if (time) {
805
72378
      return std::chrono::duration_cast<std::chrono::milliseconds>(time.value()).count();
806
72378
    }
807
53
    return absl::nullopt;
808
72431
  }
809

            
810
  FieldExtractor field_extractor_;
811
};
812

            
813
// StreamInfo uint64_t field extractor.
814
class StreamInfoUInt64FormatterProvider : public StreamInfoFormatterProvider {
815
public:
816
  using FieldExtractor = std::function<uint64_t(const StreamInfo::StreamInfo&)>;
817

            
818
58289
  StreamInfoUInt64FormatterProvider(FieldExtractor f) : field_extractor_(f) {}
819

            
820
  // StreamInfoFormatterProvider
821
  // Don't hide the other structure of format and formatValue.
822
  using StreamInfoFormatterProvider::format;
823
  using StreamInfoFormatterProvider::formatValue;
824
219449
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
825
219449
    return fmt::format_int(field_extractor_(stream_info)).str();
826
219449
  }
827
146
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
828
146
    return ValueUtil::numberValue(field_extractor_(stream_info));
829
146
  }
830

            
831
private:
832
  FieldExtractor field_extractor_;
833
};
834

            
835
// StreamInfo Network::Address::InstanceConstSharedPtr field extractor.
836
class StreamInfoAddressFormatterProvider : public StreamInfoFormatterProvider {
837
public:
838
  using FieldExtractor =
839
      std::function<Network::Address::InstanceConstSharedPtr(const StreamInfo::StreamInfo&)>;
840

            
841
19089
  static std::unique_ptr<StreamInfoAddressFormatterProvider> withPort(FieldExtractor f) {
842
19089
    return std::make_unique<StreamInfoAddressFormatterProvider>(
843
19089
        f, StreamInfoAddressFieldExtractionType::WithPort);
844
19089
  }
845

            
846
  static std::unique_ptr<StreamInfoAddressFormatterProvider>
847
153
  withoutPort(FieldExtractor f, absl::optional<int> mask_prefix_len = absl::nullopt) {
848
153
    return std::make_unique<StreamInfoAddressFormatterProvider>(
849
153
        f, StreamInfoAddressFieldExtractionType::WithoutPort, mask_prefix_len);
850
153
  }
851

            
852
25
  static std::unique_ptr<StreamInfoAddressFormatterProvider> justPort(FieldExtractor f) {
853
25
    return std::make_unique<StreamInfoAddressFormatterProvider>(
854
25
        f, StreamInfoAddressFieldExtractionType::JustPort);
855
25
  }
856

            
857
8
  static std::unique_ptr<StreamInfoAddressFormatterProvider> justEndpointId(FieldExtractor f) {
858
8
    return std::make_unique<StreamInfoAddressFormatterProvider>(
859
8
        f, StreamInfoAddressFieldExtractionType::JustEndpointId);
860
8
  }
861

            
862
  StreamInfoAddressFormatterProvider(FieldExtractor f,
863
                                     StreamInfoAddressFieldExtractionType extraction_type,
864
                                     absl::optional<int> mask_prefix_len = absl::nullopt)
865
19275
      : field_extractor_(f), extraction_type_(extraction_type), mask_prefix_len_(mask_prefix_len) {}
866

            
867
  // StreamInfoFormatterProvider
868
  // Don't hide the other structure of format and formatValue.
869
  using StreamInfoFormatterProvider::format;
870
  using StreamInfoFormatterProvider::formatValue;
871
75010
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
872
75010
    Network::Address::InstanceConstSharedPtr address = field_extractor_(stream_info);
873
75010
    if (!address) {
874
49910
      return absl::nullopt;
875
49910
    }
876

            
877
25100
    return toString(*address);
878
75010
  }
879
49
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
880
49
    Network::Address::InstanceConstSharedPtr address = field_extractor_(stream_info);
881
49
    if (!address) {
882
4
      return SubstitutionFormatUtils::unspecifiedValue();
883
4
    }
884

            
885
45
    if (extraction_type_ == StreamInfoAddressFieldExtractionType::JustPort) {
886
13
      const auto port = StreamInfo::Utility::extractDownstreamAddressJustPort(*address);
887
13
      if (port) {
888
11
        return ValueUtil::numberValue(*port);
889
11
      }
890
2
      return SubstitutionFormatUtils::unspecifiedValue();
891
13
    }
892

            
893
32
    return ValueUtil::stringValue(toString(*address));
894
45
  }
895

            
896
private:
897
25132
  std::string toString(const Network::Address::Instance& address) const {
898
25132
    switch (extraction_type_) {
899
106
    case StreamInfoAddressFieldExtractionType::WithoutPort:
900
106
      return StreamInfo::Utility::formatDownstreamAddressNoPort(address, mask_prefix_len_);
901
23
    case StreamInfoAddressFieldExtractionType::JustPort:
902
23
      return StreamInfo::Utility::formatDownstreamAddressJustPort(address);
903
17
    case StreamInfoAddressFieldExtractionType::JustEndpointId:
904
17
      return StreamInfo::Utility::formatDownstreamAddressJustEndpointId(address);
905
24986
    case StreamInfoAddressFieldExtractionType::WithPort:
906
24986
    default:
907
24986
      return address.asString();
908
25132
    }
909
25132
  }
910

            
911
  FieldExtractor field_extractor_;
912
  const StreamInfoAddressFieldExtractionType extraction_type_;
913
  const absl::optional<int> mask_prefix_len_;
914
};
915

            
916
// Ssl::ConnectionInfo std::string field extractor.
917
class StreamInfoSslConnectionInfoFormatterProvider : public StreamInfoFormatterProvider {
918
public:
919
  using FieldExtractor =
920
      std::function<absl::optional<std::string>(const Ssl::ConnectionInfo& connection_info)>;
921

            
922
105
  StreamInfoSslConnectionInfoFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
923

            
924
  // StreamInfoFormatterProvider
925
  // Don't hide the other structure of format and formatValue.
926
  using StreamInfoFormatterProvider::format;
927
  using StreamInfoFormatterProvider::formatValue;
928
106
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
929
106
    if (stream_info.downstreamAddressProvider().sslConnection() == nullptr) {
930
24
      return absl::nullopt;
931
24
    }
932

            
933
82
    const auto value = field_extractor_(*stream_info.downstreamAddressProvider().sslConnection());
934
82
    if (value && value->empty()) {
935
37
      return absl::nullopt;
936
37
    }
937

            
938
45
    return value;
939
82
  }
940

            
941
69
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
942
69
    if (stream_info.downstreamAddressProvider().sslConnection() == nullptr) {
943
24
      return SubstitutionFormatUtils::unspecifiedValue();
944
24
    }
945

            
946
45
    const auto value = field_extractor_(*stream_info.downstreamAddressProvider().sslConnection());
947
45
    if (value && value->empty()) {
948
24
      return SubstitutionFormatUtils::unspecifiedValue();
949
24
    }
950

            
951
21
    return ValueUtil::optionalStringValue(value);
952
45
  }
953

            
954
private:
955
  FieldExtractor field_extractor_;
956
};
957

            
958
class StreamInfoUpstreamSslConnectionInfoFormatterProvider : public StreamInfoFormatterProvider {
959
public:
960
  using FieldExtractor =
961
      std::function<absl::optional<std::string>(const Ssl::ConnectionInfo& connection_info)>;
962

            
963
48
  StreamInfoUpstreamSslConnectionInfoFormatterProvider(FieldExtractor f) : field_extractor_(f) {}
964

            
965
  // StreamInfoFormatterProvider
966
  // Don't hide the other structure of format and formatValue.
967
  using StreamInfoFormatterProvider::format;
968
  using StreamInfoFormatterProvider::formatValue;
969
42
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override {
970
42
    if (!stream_info.upstreamInfo() ||
971
42
        stream_info.upstreamInfo()->upstreamSslConnection() == nullptr) {
972
18
      return absl::nullopt;
973
18
    }
974

            
975
24
    const auto value = field_extractor_(*(stream_info.upstreamInfo()->upstreamSslConnection()));
976
24
    if (value && value->empty()) {
977
12
      return absl::nullopt;
978
12
    }
979

            
980
12
    return value;
981
24
  }
982

            
983
47
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override {
984
47
    if (!stream_info.upstreamInfo() ||
985
47
        stream_info.upstreamInfo()->upstreamSslConnection() == nullptr) {
986
18
      return SubstitutionFormatUtils::unspecifiedValue();
987
18
    }
988

            
989
29
    const auto value = field_extractor_(*(stream_info.upstreamInfo()->upstreamSslConnection()));
990
29
    if (value && value->empty()) {
991
12
      return SubstitutionFormatUtils::unspecifiedValue();
992
12
    }
993

            
994
17
    return ValueUtil::optionalStringValue(value);
995
29
  }
996

            
997
private:
998
  FieldExtractor field_extractor_;
999
};
using StreamInfoFormatterProviderLookupTable =
    absl::flat_hash_map<absl::string_view, std::pair<CommandSyntaxChecker::CommandSyntaxFlags,
                                                     StreamInfoFormatterProviderCreateFunc>>;
494560
const StreamInfoFormatterProviderLookupTable& getKnownStreamInfoFormatterProviders() {
494560
  CONSTRUCT_ON_FIRST_USE(StreamInfoFormatterProviderLookupTable,
494560
                         {
494560
                             {"REQUEST_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       StreamInfo::TimingUtility timing(stream_info);
494560
                                       return timing.lastDownstreamRxByteReceived();
494560
                                     });
494560
                               }}},
494560
                             {"REQUEST_TX_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       StreamInfo::TimingUtility timing(stream_info);
494560
                                       return timing.lastUpstreamTxByteSent();
494560
                                     });
494560
                               }}},
494560
                             {"RESPONSE_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       StreamInfo::TimingUtility timing(stream_info);
494560
                                       return timing.firstUpstreamRxByteReceived();
494560
                                     });
494560
                               }}},
494560
                             {"RESPONSE_TX_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       StreamInfo::TimingUtility timing(stream_info);
494560
                                       auto downstream = timing.lastDownstreamTxByteSent();
494560
                                       auto upstream = timing.firstUpstreamRxByteReceived();
494560
                                       absl::optional<std::chrono::nanoseconds> result;
494560
                                       if (downstream && upstream) {
494560
                                         result = downstream.value() - upstream.value();
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_HANDSHAKE_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       StreamInfo::TimingUtility timing(stream_info);
494560
                                       return timing.downstreamHandshakeComplete();
494560
                                     });
494560
                               }}},
494560
                             {"ROUNDTRIP_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       StreamInfo::TimingUtility timing(stream_info);
494560
                                       return timing.lastDownstreamAckReceived();
494560
                                     });
494560
                               }}},
494560
                             {"BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.bytesReceived();
494560
                                     });
494560
                               }}},
494560
                             {"BYTES_RETRANSMITTED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.bytesRetransmitted();
494560
                                     });
494560
                               }}},
494560
                             {"PACKETS_RETRANSMITTED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.packetsRetransmitted();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_WIRE_BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getUpstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->wireBytesReceived() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HEADER_BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getUpstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->headerBytesReceived() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_DECOMPRESSED_HEADER_BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getUpstreamBytesMeter();
494560
                                       return bytes_meter
494560
                                                  ? bytes_meter->decompressedHeaderBytesReceived()
494560
                                                  : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_WIRE_BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getDownstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->wireBytesReceived() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_HEADER_BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getDownstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->headerBytesReceived() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DECOMPRESSED_HEADER_BYTES_RECEIVED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getDownstreamBytesMeter();
494560
                                       return bytes_meter
494560
                                                  ? bytes_meter->decompressedHeaderBytesReceived()
494560
                                                  : 0;
494560
                                     });
494560
                               }}},
494560
                             {"PROTOCOL",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return SubstitutionFormatUtils::protocolToString(
494560
                                           stream_info.protocol());
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PROTOCOL",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.upstreamInfo()
494560
                                                  ? SubstitutionFormatUtils::protocolToString(
494560
                                                        stream_info.upstreamInfo()
494560
                                                            ->upstreamProtocol())
494560
                                                  : absl::nullopt;
494560
                                     });
494560
                               }}},
494560
                             {"RESPONSE_CODE",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.responseCode().value_or(0);
494560
                                     });
494560
                               }}},
494560
                             {"RESPONSE_CODE_DETAILS",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 bool allow_whitespaces = (format == "ALLOW_WHITESPACES");
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [allow_whitespaces](
494560
                                         const StreamInfo::StreamInfo& stream_info) {
494560
                                       if (allow_whitespaces ||
494560
                                           !stream_info.responseCodeDetails().has_value()) {
494560
                                         return stream_info.responseCodeDetails();
494560
                                       }
494560
                                       return absl::optional<std::string>(
494560
                                           StringUtil::replaceAllEmptySpace(
494560
                                               stream_info.responseCodeDetails().value()));
494560
                                     });
494560
                               }}},
494560
                             {"CONNECTION_TERMINATION_DETAILS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.connectionTerminationDetails();
494560
                                     });
494560
                               }}},
494560
                             {"BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.bytesSent();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_WIRE_BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getUpstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->wireBytesSent() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HEADER_BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getUpstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->headerBytesSent() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_DECOMPRESSED_HEADER_BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getUpstreamBytesMeter();
494560
                                       return bytes_meter
494560
                                                  ? bytes_meter->decompressedHeaderBytesSent()
494560
                                                  : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_WIRE_BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getDownstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->wireBytesSent() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_HEADER_BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getDownstreamBytesMeter();
494560
                                       return bytes_meter ? bytes_meter->headerBytesSent() : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DECOMPRESSED_HEADER_BYTES_SENT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       const auto& bytes_meter =
494560
                                           stream_info.getDownstreamBytesMeter();
494560
                                       return bytes_meter
494560
                                                  ? bytes_meter->decompressedHeaderBytesSent()
494560
                                                  : 0;
494560
                                     });
494560
                               }}},
494560
                             {"DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.currentDuration();
494560
                                     });
494560
                               }}},
494560
                             {"COMMON_DURATION",
494560
                              {CommandSyntaxChecker::PARAMS_REQUIRED,
494560
                               [](absl::string_view sub_command, absl::optional<size_t>) {
494560
                                 return CommonDurationFormatter::create(sub_command);
494560
                               }}},
494560
                             {"CUSTOM_FLAGS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return std::string(stream_info.customFlags());
494560
                                     });
494560
                               }}},
494560
                             {"RESPONSE_FLAGS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return StreamInfo::ResponseFlagUtils::toShortString(
494560
                                           stream_info);
494560
                                     });
494560
                               }}},
494560
                             {"RESPONSE_FLAGS_LONG",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return StreamInfo::ResponseFlagUtils::toString(stream_info);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOST_NAME",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       const auto opt_ref = stream_info.upstreamInfo();
494560
                                       if (!opt_ref.has_value()) {
494560
                                         return absl::nullopt;
494560
                                       }
494560
                                       const auto host = opt_ref->upstreamHost();
494560
                                       if (host == nullptr) {
494560
                                         return absl::nullopt;
494560
                                       }
494560
                                       std::string host_name = host->hostname();
494560
                                       if (host_name.empty()) {
                                         // If no hostname is available, the main address is used.
494560
                                         return host->address()->asString();
494560
                                       }
494560
                                       return absl::make_optional<std::string>(
494560
                                           std::move(host_name));
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOST_NAME_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       const auto opt_ref = stream_info.upstreamInfo();
494560
                                       if (!opt_ref.has_value()) {
494560
                                         return absl::nullopt;
494560
                                       }
494560
                                       const auto host = opt_ref->upstreamHost();
494560
                                       if (host == nullptr) {
494560
                                         return absl::nullopt;
494560
                                       }
494560
                                       std::string host_name = host->hostname();
494560
                                       if (host_name.empty()) {
                                         // If no hostname is available, the main address is used.
494560
                                         host_name = host->address()->asString();
494560
                                       }
494560
                                       Envoy::Http::HeaderUtility::stripPortFromHost(host_name);
494560
                                       return absl::make_optional<std::string>(
494560
                                           std::move(host_name));
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOST",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       const auto opt_ref = stream_info.upstreamInfo();
494560
                                       if (!opt_ref.has_value()) {
494560
                                         return nullptr;
494560
                                       }
494560
                                       const auto host = opt_ref->upstreamHost();
494560
                                       if (host == nullptr) {
494560
                                         return nullptr;
494560
                                       }
494560
                                       return host->address();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOSTS_ATTEMPTED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return formatUpstreamHostsAttempted(
494560
                                           stream_info,
494560
                                           [](const Upstream::HostDescriptionConstSharedPtr& host)
494560
                                               -> absl::optional<std::string> {
494560
                                             if (host == nullptr || host->address() == nullptr) {
494560
                                               return absl::nullopt;
494560
                                             }
494560
                                             return host->address()->asString();
494560
                                           });
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOSTS_ATTEMPTED_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return formatUpstreamHostsAttempted(
494560
                                           stream_info,
494560
                                           [](const Upstream::HostDescriptionConstSharedPtr& host)
494560
                                               -> absl::optional<std::string> {
494560
                                             if (host == nullptr || host->address() == nullptr) {
494560
                                               return absl::nullopt;
494560
                                             }
494560
                                             return StreamInfo::Utility::
494560
                                                 formatDownstreamAddressNoPort(*host->address());
494560
                                           });
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOST_NAMES_ATTEMPTED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return formatUpstreamHostsAttempted(
494560
                                           stream_info,
494560
                                           [](const Upstream::HostDescriptionConstSharedPtr& host)
494560
                                               -> absl::optional<std::string> {
494560
                                             if (host == nullptr) {
494560
                                               return absl::nullopt;
494560
                                             }
494560
                                             std::string host_name = host->hostname();
494560
                                             if (host_name.empty() && host->address() != nullptr) {
494560
                                               host_name = host->address()->asString();
494560
                                             }
494560
                                             return host_name.empty()
494560
                                                        ? absl::nullopt
494560
                                                        : absl::make_optional(host_name);
494560
                                           });
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_HOST_NAMES_ATTEMPTED_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return formatUpstreamHostsAttempted(
494560
                                           stream_info,
494560
                                           [](const Upstream::HostDescriptionConstSharedPtr& host)
494560
                                               -> absl::optional<std::string> {
494560
                                             if (host == nullptr) {
494560
                                               return absl::nullopt;
494560
                                             }
494560
                                             std::string host_name = host->hostname();
494560
                                             if (host_name.empty() && host->address() != nullptr) {
494560
                                               host_name = host->address()->asString();
494560
                                             }
494560
                                             Envoy::Http::HeaderUtility::stripPortFromHost(
494560
                                                 host_name);
494560
                                             return host_name.empty()
494560
                                                        ? absl::nullopt
494560
                                                        : absl::make_optional(host_name);
494560
                                           });
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_CONNECTION_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       uint64_t upstream_connection_id = 0;
494560
                                       if (stream_info.upstreamInfo().has_value()) {
494560
                                         upstream_connection_id = stream_info.upstreamInfo()
494560
                                                                      ->upstreamConnectionId()
494560
                                                                      .value_or(0);
494560
                                       }
494560
                                       return upstream_connection_id;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_CONNECTION_IDS_ATTEMPTED",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       const auto opt_ref = stream_info.upstreamInfo();
494560
                                       if (!opt_ref.has_value()) {
494560
                                         return absl::nullopt;
494560
                                       }
494560
                                       const auto& attempted_ids =
494560
                                           opt_ref->upstreamConnectionIdsAttempted();
494560
                                       if (attempted_ids.empty()) {
494560
                                         return absl::nullopt;
494560
                                       }
494560
                                       std::vector<std::string> ids;
494560
                                       ids.reserve(attempted_ids.size());
494560
                                       for (const auto& id : attempted_ids) {
494560
                                         ids.push_back(std::to_string(id));
494560
                                       }
494560
                                       return absl::StrJoin(ids, ",");
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_CLUSTER",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       std::string upstream_cluster_name;
494560
                                       if (stream_info.upstreamClusterInfo().has_value() &&
494560
                                           stream_info.upstreamClusterInfo().value() != nullptr) {
494560
                                         upstream_cluster_name = stream_info.upstreamClusterInfo()
494560
                                                                     .value()
494560
                                                                     ->observabilityName();
494560
                                       }
494560
                                       return upstream_cluster_name.empty()
494560
                                                  ? absl::nullopt
494560
                                                  : absl::make_optional<std::string>(
494560
                                                        upstream_cluster_name);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_CLUSTER_RAW",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       std::string upstream_cluster_name;
494560
                                       if (stream_info.upstreamClusterInfo().has_value() &&
494560
                                           stream_info.upstreamClusterInfo().value() != nullptr) {
494560
                                         upstream_cluster_name =
494560
                                             stream_info.upstreamClusterInfo().value()->name();
494560
                                       }
494560
                                       return upstream_cluster_name.empty()
494560
                                                  ? absl::nullopt
494560
                                                  : absl::make_optional<std::string>(
494560
                                                        upstream_cluster_name);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_ADDRESS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       if (stream_info.upstreamInfo().has_value()) {
494560
                                         return stream_info.upstreamInfo()
494560
                                             .value()
494560
                                             .get()
494560
                                             .upstreamLocalAddress();
494560
                                       }
494560
                                       return nullptr;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_ADDRESS_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::optional<int> mask_prefix_len;
494560
                                 if (!format.empty()) {
494560
                                   int len;
494560
                                   if (absl::SimpleAtoi(format, &len)) {
494560
                                     mask_prefix_len = len;
494560
                                   }
494560
                                 }
494560
                                 return StreamInfoAddressFormatterProvider::withoutPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       if (stream_info.upstreamInfo().has_value()) {
494560
                                         return stream_info.upstreamInfo()
494560
                                             .value()
494560
                                             .get()
494560
                                             .upstreamLocalAddress();
494560
                                       }
494560
                                       return nullptr;
494560
                                     },
494560
                                     mask_prefix_len);
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       if (stream_info.upstreamInfo().has_value()) {
494560
                                         return stream_info.upstreamInfo()
494560
                                             .value()
494560
                                             .get()
494560
                                             .upstreamLocalAddress();
494560
                                       }
494560
                                       return nullptr;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_REMOTE_ADDRESS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       return getUpstreamRemoteAddress(stream_info);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_REMOTE_ADDRESS_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::optional<int> mask_prefix_len;
494560
                                 if (!format.empty()) {
494560
                                   int len;
494560
                                   if (absl::SimpleAtoi(format, &len)) {
494560
                                     mask_prefix_len = len;
494560
                                   }
494560
                                 }
494560
                                 return StreamInfoAddressFormatterProvider::withoutPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       return getUpstreamRemoteAddress(stream_info);
494560
                                     },
494560
                                     mask_prefix_len);
494560
                               }}},
494560
                             {"UPSTREAM_REMOTE_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       return getUpstreamRemoteAddress(stream_info);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_REMOTE_ADDRESS_ENDPOINT_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justEndpointId(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> Network::Address::InstanceConstSharedPtr {
494560
                                       return getUpstreamRemoteAddress(stream_info);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_REQUEST_ATTEMPT_COUNT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.attemptCount().value_or(0);
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_TLS_CIPHER",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.ciphersuiteString();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_TLS_VERSION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.tlsVersion();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_TLS_SESSION_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.sessionId();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PEER_ISSUER",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.issuerPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PEER_CERT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.urlEncodedPemEncodedPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PEER_SUBJECT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.subjectPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_ADDRESS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .localAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DETECTED_CLOSE_TYPE",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       return detectedCloseTypeToString(
494560
                                           stream_info.downstreamDetectedCloseType());
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_LOCAL_ADDRESS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directLocalAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::optional<int> mask_prefix_len;
494560
                                 if (!format.empty()) {
494560
                                   int len;
494560
                                   if (absl::SimpleAtoi(format, &len)) {
494560
                                     mask_prefix_len = len;
494560
                                   }
494560
                                 }
494560
                                 return StreamInfoAddressFormatterProvider::withoutPort(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .localAddress();
494560
                                     },
494560
                                     mask_prefix_len);
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_LOCAL_ADDRESS_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::optional<int> mask_prefix_len;
494560
                                 if (!format.empty()) {
494560
                                   int len;
494560
                                   if (absl::SimpleAtoi(format, &len)) {
494560
                                     mask_prefix_len = len;
494560
                                   }
494560
                                 }
494560
                                 return StreamInfoAddressFormatterProvider::withoutPort(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directLocalAddress();
494560
                                     },
494560
                                     mask_prefix_len);
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justPort(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .localAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_LOCAL_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justPort(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directLocalAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_ADDRESS_ENDPOINT_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justEndpointId(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .localAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_LOCAL_ADDRESS_ENDPOINT_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justEndpointId(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directLocalAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_REMOTE_ADDRESS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .remoteAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::optional<int> mask_prefix_len;
494560
                                 if (!format.empty()) {
494560
                                   int len;
494560
                                   if (absl::SimpleAtoi(format, &len)) {
494560
                                     mask_prefix_len = len;
494560
                                   }
494560
                                 }
494560
                                 return StreamInfoAddressFormatterProvider::withoutPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .remoteAddress();
494560
                                     },
494560
                                     mask_prefix_len);
494560
                               }}},
494560
                             {"DOWNSTREAM_REMOTE_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justPort(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .remoteAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_REMOTE_ADDRESS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::withPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directRemoteAddress();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_REMOTE_ADDRESS_WITHOUT_PORT",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::optional<int> mask_prefix_len;
494560
                                 if (!format.empty()) {
494560
                                   int len;
494560
                                   if (absl::SimpleAtoi(format, &len)) {
494560
                                     mask_prefix_len = len;
494560
                                   }
494560
                                 }
494560
                                 return StreamInfoAddressFormatterProvider::withoutPort(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directRemoteAddress();
494560
                                     },
494560
                                     mask_prefix_len);
494560
                               }}},
494560
                             {"DOWNSTREAM_DIRECT_REMOTE_PORT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return StreamInfoAddressFormatterProvider::justPort(
494560
                                     [](const Envoy::StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .directRemoteAddress();
494560
                                     });
494560
                               }}},
494560
                             {"CONNECTION_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoUInt64FormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       return stream_info.downstreamAddressProvider()
494560
                                           .connectionID()
494560
                                           .value_or(0);
494560
                                     });
494560
                               }}},
494560
                             {"REQUESTED_SERVER_NAME",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 absl::string_view fallback;
494560
                                 absl::string_view option;
494560
                                 SubstitutionFormatUtils::parseSubcommand(format, ':', fallback,
494560
                                                                          option);
494560
                                 return std::make_unique<RequestedServerNameFormatter>(fallback,
494560
                                                                                       option);
494560
                               }}},
494560
                             {"ROUTE_NAME",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       std::string route_name = stream_info.getRouteName();
494560
                                       if (!route_name.empty()) {
494560
                                         result = route_name;
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PEER_URI_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(connection_info.uriSanPeerCertificate(),
494560
                                                            ",");
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PEER_DNS_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.dnsSansPeerCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_PEER_IP_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(connection_info.ipSansPeerCertificate(),
494560
                                                            ",");
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_URI_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.uriSanLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_DNS_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.dnsSansLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_IP_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoUpstreamSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.ipSansLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_URI_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(connection_info.uriSanPeerCertificate(),
494560
                                                            ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_DNS_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.dnsSansPeerCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_IP_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(connection_info.ipSansPeerCertificate(),
494560
                                                            ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_EMAIL_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.emailSansPeerCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_OTHERNAME_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.othernameSansPeerCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_URI_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.uriSanLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_DNS_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.dnsSansLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_IP_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.ipSansLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_EMAIL_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.emailSansLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_OTHERNAME_SAN",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.othernameSansLocalCertificate(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_SUBJECT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.subjectPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_SUBJECT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.subjectLocalCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_TLS_SESSION_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.sessionId();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_TLS_CIPHER",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.ciphersuiteString();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_TLS_VERSION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.tlsVersion();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_FINGERPRINT_256",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.sha256PeerCertificateDigest();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_FINGERPRINT_1",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.sha1PeerCertificateDigest();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_SERIAL",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.serialNumberPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_CHAIN_FINGERPRINTS_256",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](const absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.sha256PeerCertificateChainDigests(),
494560
                                           ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_CHAIN_FINGERPRINTS_1",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](const absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.sha1PeerCertificateChainDigests(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_CHAIN_SERIALS",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](const absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return absl::StrJoin(
494560
                                           connection_info.serialNumbersPeerCertificates(), ",");
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_ISSUER",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.issuerPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_CERT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<
494560
                                     StreamInfoSslConnectionInfoFormatterProvider>(
494560
                                     [](const Ssl::ConnectionInfo& connection_info) {
494560
                                       return connection_info.urlEncodedPemEncodedPeerCertificate();
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_TRANSPORT_FAILURE_REASON",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       if (!stream_info.downstreamTransportFailureReason()
494560
                                                .empty()) {
494560
                                         result = absl::StrReplaceAll(
494560
                                             stream_info.downstreamTransportFailureReason(),
494560
                                             {{" ", "_"}});
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"DOWNSTREAM_LOCAL_CLOSE_REASON",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       if (!stream_info.downstreamLocalCloseReason().empty()) {
494560
                                         result = absl::StrReplaceAll(
494560
                                             stream_info.downstreamLocalCloseReason(),
494560
                                             {{" ", "_"}});
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_TRANSPORT_FAILURE_REASON",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       if (stream_info.upstreamInfo().has_value() &&
494560
                                           !stream_info.upstreamInfo()
494560
                                                .value()
494560
                                                .get()
494560
                                                .upstreamTransportFailureReason()
494560
                                                .empty()) {
494560
                                         result = stream_info.upstreamInfo()
494560
                                                      .value()
494560
                                                      .get()
494560
                                                      .upstreamTransportFailureReason();
494560
                                       }
494560
                                       if (result) {
494560
                                         std::replace(result->begin(), result->end(), ' ', '_');
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_DETECTED_CLOSE_TYPE",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       if (stream_info.upstreamInfo().has_value()) {
494560
                                         return detectedCloseTypeToString(
494560
                                             stream_info.upstreamInfo()
494560
                                                 ->upstreamDetectedCloseType());
494560
                                       }
494560
                                       return absl::nullopt;
494560
                                     });
494560
                               }}},
494560
                             {"UPSTREAM_LOCAL_CLOSE_REASON",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       if (stream_info.upstreamInfo().has_value() &&
494560
                                           !stream_info.upstreamInfo()
494560
                                                .value()
494560
                                                .get()
494560
                                                .upstreamLocalCloseReason()
494560
                                                .empty()) {
494560
                                         result = std::string(stream_info.upstreamInfo()
494560
                                                                  .value()
494560
                                                                  .get()
494560
                                                                  .upstreamLocalCloseReason());
494560
                                       }
494560
                                       if (result) {
494560
                                         std::replace(result->begin(), result->end(), ' ', '_');
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"HOSTNAME",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 absl::optional<std::string> hostname =
494560
                                     SubstitutionFormatUtils::getHostname();
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [hostname](const StreamInfo::StreamInfo&) {
494560
                                       return hostname;
494560
                                     });
494560
                               }}},
494560
                             {"FILTER_CHAIN_NAME",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       if (const auto info = stream_info.downstreamAddressProvider()
494560
                                                                 .filterChainInfo();
494560
                                           info.has_value()) {
494560
                                         if (!info->name().empty()) {
494560
                                           return std::string(info->name());
494560
                                         }
494560
                                       }
494560
                                       return absl::nullopt;
494560
                                     });
494560
                               }}},
494560
                             {"VIRTUAL_CLUSTER_NAME",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       return stream_info.virtualClusterName();
494560
                                     });
494560
                               }}},
494560
                             {"TLS_JA3_FINGERPRINT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       if (!stream_info.downstreamAddressProvider()
494560
                                                .ja3Hash()
494560
                                                .empty()) {
494560
                                         result = std::string(
494560
                                             stream_info.downstreamAddressProvider().ja3Hash());
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"TLS_JA4_FINGERPRINT",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info) {
494560
                                       absl::optional<std::string> result;
494560
                                       if (!stream_info.downstreamAddressProvider()
494560
                                                .ja4Hash()
494560
                                                .empty()) {
494560
                                         result = std::string(
494560
                                             stream_info.downstreamAddressProvider().ja4Hash());
494560
                                       }
494560
                                       return result;
494560
                                     });
494560
                               }}},
494560
                             {"UNIQUE_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, const absl::optional<size_t>&) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo&)
494560
                                         -> absl::optional<std::string> {
494560
                                       return absl::make_optional<std::string>(
494560
                                           Random::RandomUtility::uuid());
494560
                                     });
494560
                               }}},
494560
                             {"STREAM_ID",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, absl::optional<size_t>) {
494560
                                 return std::make_unique<StreamInfoStringFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::string> {
494560
                                       auto provider = stream_info.getStreamIdProvider();
494560
                                       if (!provider.has_value()) {
494560
                                         return {};
494560
                                       }
494560
                                       auto id = provider->toStringView();
494560
                                       if (!id.has_value()) {
494560
                                         return {};
494560
                                       }
494560
                                       return absl::make_optional<std::string>(id.value());
494560
                                     });
494560
                               }}},
494560
                             {"START_TIME",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<SystemTimeFormatter>(
494560
                                     format,
494560
                                     std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
494560
                                         [](const StreamInfo::StreamInfo& stream_info)
494560
                                             -> absl::optional<SystemTime> {
494560
                                           return stream_info.startTime();
494560
                                         }));
494560
                               }}},
494560
                             {"START_TIME_LOCAL",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<SystemTimeFormatter>(
494560
                                     format,
494560
                                     std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
494560
                                         [](const StreamInfo::StreamInfo& stream_info)
494560
                                             -> absl::optional<SystemTime> {
494560
                                           return stream_info.startTime();
494560
                                         }),
494560
                                     true);
494560
                               }}},
494560
                             {"EMIT_TIME",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<SystemTimeFormatter>(
494560
                                     format,
494560
                                     std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
494560
                                         [](const StreamInfo::StreamInfo& stream_info)
494560
                                             -> absl::optional<SystemTime> {
494560
                                           return stream_info.timeSource().systemTime();
494560
                                         }));
494560
                               }}},
494560
                             {"EMIT_TIME_LOCAL",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<SystemTimeFormatter>(
494560
                                     format,
494560
                                     std::make_unique<SystemTimeFormatter::TimeFieldExtractor>(
494560
                                         [](const StreamInfo::StreamInfo& stream_info)
494560
                                             -> absl::optional<SystemTime> {
494560
                                           return stream_info.timeSource().systemTime();
494560
                                         }),
494560
                                     true);
494560
                               }}},
494560
                             {"DYNAMIC_METADATA",
494560
                              {CommandSyntaxChecker::PARAMS_REQUIRED |
494560
                                   CommandSyntaxChecker::LENGTH_ALLOWED,
494560
                               [](absl::string_view format, absl::optional<size_t> max_length) {
494560
                                 absl::string_view filter_namespace;
494560
                                 std::vector<absl::string_view> path;
494560
                                 SubstitutionFormatUtils::parseSubcommand(format, ':',
494560
                                                                          filter_namespace, path);
494560
                                 return std::make_unique<DynamicMetadataFormatter>(
494560
                                     filter_namespace, path, max_length);
494560
                               }}},
494560
                             {"CLUSTER_METADATA",
494560
                              {CommandSyntaxChecker::PARAMS_REQUIRED,
494560
                               [](absl::string_view format, absl::optional<size_t> max_length) {
494560
                                 absl::string_view filter_namespace;
494560
                                 std::vector<absl::string_view> path;
494560
                                 SubstitutionFormatUtils::parseSubcommand(format, ':',
494560
                                                                          filter_namespace, path);
494560
                                 return std::make_unique<ClusterMetadataFormatter>(
494560
                                     filter_namespace, path, max_length);
494560
                               }}},
494560
                             {"UPSTREAM_METADATA",
494560
                              {CommandSyntaxChecker::PARAMS_REQUIRED,
494560
                               [](absl::string_view format, absl::optional<size_t> max_length) {
494560
                                 absl::string_view filter_namespace;
494560
                                 std::vector<absl::string_view> path;
494560
                                 SubstitutionFormatUtils::parseSubcommand(format, ':',
494560
                                                                          filter_namespace, path);
494560
                                 return std::make_unique<UpstreamHostMetadataFormatter>(
494560
                                     filter_namespace, path, max_length);
494560
                               }}},
494560
                             {"FILTER_STATE",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL |
494560
                                   CommandSyntaxChecker::LENGTH_ALLOWED,
494560
                               [](absl::string_view format, absl::optional<size_t> max_length) {
494560
                                 return FilterStateFormatter::create(format, max_length, false);
494560
                               }}},
494560
                             {"UPSTREAM_FILTER_STATE",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL |
494560
                                   CommandSyntaxChecker::LENGTH_ALLOWED,
494560
                               [](absl::string_view format, absl::optional<size_t> max_length) {
494560
                                 return FilterStateFormatter::create(format, max_length, true);
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_CERT_V_START",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<DownstreamPeerCertVStartFormatter>(format);
494560
                               }}},
494560
                             {"DOWNSTREAM_PEER_CERT_V_END",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<DownstreamPeerCertVEndFormatter>(format);
494560
                               }}},
494560
                             {"UPSTREAM_PEER_CERT_V_START",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<UpstreamPeerCertVStartFormatter>(format);
494560
                               }}},
494560
                             {"UPSTREAM_PEER_CERT_V_END",
494560
                              {CommandSyntaxChecker::PARAMS_OPTIONAL,
494560
                               [](absl::string_view format, absl::optional<size_t>) {
494560
                                 return std::make_unique<UpstreamPeerCertVEndFormatter>(format);
494560
                               }}},
494560
                             {"ENVIRONMENT",
494560
                              {CommandSyntaxChecker::PARAMS_REQUIRED |
494560
                                   CommandSyntaxChecker::LENGTH_ALLOWED,
494560
                               [](absl::string_view key, absl::optional<size_t> max_length) {
494560
                                 return std::make_unique<EnvironmentFormatter>(key, max_length);
494560
                               }}},
494560
                             {"UPSTREAM_CONNECTION_POOL_READY_DURATION",
494560
                              {CommandSyntaxChecker::COMMAND_ONLY,
494560
                               [](absl::string_view, const absl::optional<size_t>&) {
494560
                                 return std::make_unique<StreamInfoDurationFormatterProvider>(
494560
                                     [](const StreamInfo::StreamInfo& stream_info)
494560
                                         -> absl::optional<std::chrono::nanoseconds> {
494560
                                       if (auto upstream_info = stream_info.upstreamInfo();
494560
                                           upstream_info.has_value()) {
494560
                                         if (auto connection_pool_callback_latency =
494560
                                                 upstream_info.value()
494560
                                                     .get()
494560
                                                     .upstreamTiming()
494560
                                                     .connectionPoolCallbackLatency();
494560
                                             connection_pool_callback_latency.has_value()) {
494560
                                           return connection_pool_callback_latency;
494560
                                         }
494560
                                       }
494560
                                       return absl::nullopt;
494560
                                     });
494560
                               }}},
494560
                         });
494560
}
class BuiltInStreamInfoCommandParser : public CommandParser {
public:
1665
  BuiltInStreamInfoCommandParser() = default;
  // CommandParser
  FormatterProviderPtr parse(absl::string_view command, absl::string_view sub_command,
247280
                             absl::optional<size_t> max_length) const override {
247280
    auto it = getKnownStreamInfoFormatterProviders().find(command);
    // No throw because the stream info command parser may not be the last parser and other
    // formatter parsers may be tried.
247280
    if (it == getKnownStreamInfoFormatterProviders().end()) {
89250
      return nullptr;
89250
    }
    // Check flags for the command.
158030
    THROW_IF_NOT_OK(Envoy::Formatter::CommandSyntaxChecker::verifySyntax(
158030
        (*it).second.first, command, sub_command, max_length));
158024
    return (*it).second.second(sub_command, max_length);
158030
  }
};
579
std::string DefaultBuiltInStreamInfoCommandParserFactory::name() const {
579
  return "envoy.built_in_formatters.stream_info.default";
579
}
1665
CommandParserPtr DefaultBuiltInStreamInfoCommandParserFactory::createCommandParser() const {
1665
  return std::make_unique<BuiltInStreamInfoCommandParser>();
1665
}
REGISTER_FACTORY(DefaultBuiltInStreamInfoCommandParserFactory, BuiltInCommandParserFactory);
} // namespace Formatter
} // namespace Envoy