1
#pragma once
2

            
3
#include <bitset>
4
#include <functional>
5
#include <list>
6
#include <regex>
7
#include <string>
8
#include <vector>
9

            
10
#include "envoy/formatter/substitution_formatter.h"
11
#include "envoy/stream_info/stream_info.h"
12

            
13
#include "source/common/common/utility.h"
14
#include "source/common/formatter/substitution_format_utility.h"
15

            
16
#include "absl/container/flat_hash_map.h"
17
#include "absl/types/optional.h"
18

            
19
namespace Envoy {
20
namespace Formatter {
21

            
22
class StreamInfoFormatterProvider : public FormatterProvider {
23
public:
24
  // FormatterProvider
25
  absl::optional<std::string> format(const Context&,
26
590699
                                     const StreamInfo::StreamInfo& stream_info) const override {
27
590699
    return format(stream_info);
28
590699
  }
29
  Protobuf::Value formatValue(const Context&,
30
1958
                              const StreamInfo::StreamInfo& stream_info) const override {
31
1958
    return formatValue(stream_info);
32
1958
  }
33

            
34
  /**
35
   * Format the value with the given stream info.
36
   * @param stream_info supplies the stream info.
37
   * @return absl::optional<std::string> optional string containing a single value extracted from
38
   *         the given stream info.
39
   */
40
  virtual absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const PURE;
41

            
42
  /**
43
   * Format the value with the given stream info.
44
   * @param stream_info supplies the stream info.
45
   * @return Protobuf::Value containing a single value extracted from the given stream info.
46
   */
47
  virtual Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const PURE;
48
};
49

            
50
using StreamInfoFormatterProviderPtr = std::unique_ptr<StreamInfoFormatterProvider>;
51

            
52
using StreamInfoFormatterProviderCreateFunc =
53
    std::function<StreamInfoFormatterProviderPtr(absl::string_view, absl::optional<size_t>)>;
54

            
55
enum class DurationPrecision { Milliseconds, Microseconds, Nanoseconds };
56

            
57
enum class StreamInfoAddressFieldExtractionType { WithPort, WithoutPort, JustPort, JustEndpointId };
58

            
59
/**
60
 * Base formatter for formatting Metadata objects
61
 */
62
class MetadataFormatter : public StreamInfoFormatterProvider {
63
public:
64
  using GetMetadataFunction =
65
      std::function<const envoy::config::core::v3::Metadata*(const StreamInfo::StreamInfo&)>;
66
  MetadataFormatter(absl::string_view filter_namespace, const std::vector<absl::string_view>& path,
67
                    absl::optional<size_t> max_length, GetMetadataFunction get);
68

            
69
  // StreamInfoFormatterProvider
70
  // Don't hide the other structure of format and formatValue.
71
  using StreamInfoFormatterProvider::format;
72
  using StreamInfoFormatterProvider::formatValue;
73
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override;
74
  Protobuf::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override;
75

            
76
protected:
77
  absl::optional<std::string>
78
  formatMetadata(const envoy::config::core::v3::Metadata& metadata) const;
79
  Protobuf::Value formatMetadataValue(const envoy::config::core::v3::Metadata& metadata) const;
80

            
81
private:
82
  std::string filter_namespace_;
83
  std::vector<std::string> path_;
84
  absl::optional<size_t> max_length_;
85
  GetMetadataFunction get_func_;
86
};
87

            
88
/**
89
 * FormatterProvider for DynamicMetadata from StreamInfo.
90
 */
91
class DynamicMetadataFormatter : public MetadataFormatter {
92
public:
93
  DynamicMetadataFormatter(absl::string_view filter_namespace,
94
                           const std::vector<absl::string_view>& path,
95
                           absl::optional<size_t> max_length);
96
};
97

            
98
/**
99
 * FormatterProvider for ClusterMetadata from StreamInfo.
100
 */
101
class ClusterMetadataFormatter : public MetadataFormatter {
102
public:
103
  ClusterMetadataFormatter(absl::string_view filter_namespace,
104
                           const std::vector<absl::string_view>& path,
105
                           absl::optional<size_t> max_length);
106
};
107

            
108
/**
109
 * FormatterProvider for UpstreamHostMetadata from StreamInfo.
110
 */
111
class UpstreamHostMetadataFormatter : public MetadataFormatter {
112
public:
113
  UpstreamHostMetadataFormatter(absl::string_view filter_namespace,
114
                                const std::vector<absl::string_view>& path,
115
                                absl::optional<size_t> max_length);
116
};
117

            
118
enum class FilterStateFormat { String, Proto, Field };
119

            
120
/**
121
 * StreamInfoFormatterProvider for FilterState from StreamInfo.
122
 */
123
class FilterStateFormatter : public StreamInfoFormatterProvider {
124
public:
125
  static std::unique_ptr<FilterStateFormatter>
126
  create(absl::string_view format, absl::optional<size_t> max_length, bool is_upstream);
127

            
128
  FilterStateFormatter(absl::string_view key, absl::optional<size_t> max_length,
129
                       bool serialize_as_string, bool is_upstream = false,
130
                       absl::string_view field_name = {});
131

            
132
  // StreamInfoFormatterProvider
133
  // Don't hide the other structure of format and formatValue.
134
  using StreamInfoFormatterProvider::format;
135
  using StreamInfoFormatterProvider::formatValue;
136
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
137
  Protobuf::Value formatValue(const StreamInfo::StreamInfo&) const override;
138

            
139
private:
140
  const Envoy::StreamInfo::FilterState::Object*
141
  filterState(const StreamInfo::StreamInfo& stream_info) const;
142

            
143
  std::string key_;
144
  absl::optional<size_t> max_length_;
145

            
146
  const bool is_upstream_;
147
  FilterStateFormat format_;
148
  std::string field_name_;
149
};
150

            
151
class CommonDurationFormatter : public StreamInfoFormatterProvider {
152
public:
153
  using TimePointGetter =
154
      std::function<absl::optional<MonotonicTime>(const StreamInfo::StreamInfo&)>;
155

            
156
  static std::unique_ptr<CommonDurationFormatter> create(absl::string_view sub_command);
157

            
158
  CommonDurationFormatter(TimePointGetter beg, TimePointGetter end,
159
                          DurationPrecision duration_precision)
160
864
      : time_point_beg_(std::move(beg)), time_point_end_(std::move(end)),
161
864
        duration_precision_(duration_precision) {}
162

            
163
  // StreamInfoFormatterProvider
164
  // Don't hide the other structure of format and formatValue.
165
  using StreamInfoFormatterProvider::format;
166
  using StreamInfoFormatterProvider::formatValue;
167
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
168
  Protobuf::Value formatValue(const StreamInfo::StreamInfo&) const override;
169

            
170
  static const absl::flat_hash_map<absl::string_view, TimePointGetter> KnownTimePointGetters;
171

            
172
private:
173
  absl::optional<uint64_t> getDurationCount(const StreamInfo::StreamInfo& info) const;
174

            
175
  static TimePointGetter getTimePointGetterByName(absl::string_view name);
176

            
177
  static constexpr absl::string_view MillisecondsPrecision = "ms";
178
  static constexpr absl::string_view MicrosecondsPrecision = "us";
179
  static constexpr absl::string_view NanosecondsPrecision = "ns";
180

            
181
  static constexpr absl::string_view FirstDownstreamRxByteReceived =
182
      "DS_RX_BEG"; // Downstream request receiving begin.
183
  static constexpr absl::string_view LastDownstreamRxByteReceived =
184
      "DS_RX_END"; // Downstream request receiving end.
185
  static constexpr absl::string_view UpstreamConnectStart =
186
      "US_CX_BEG"; // Upstream TCP connection establishment start.
187
  static constexpr absl::string_view UpstreamConnectEnd =
188
      "US_CX_END"; // Upstream TCP connection establishment start.
189
  static constexpr absl::string_view UpstreamTLSConnectEnd =
190
      "US_HS_END"; // Upstream TLS connection establishment start.
191
  static constexpr absl::string_view FirstUpstreamTxByteSent =
192
      "US_TX_BEG"; // Upstream request sending begin.
193
  static constexpr absl::string_view LastUpstreamTxByteSent =
194
      "US_TX_END"; // Upstream request sending end.
195
  static constexpr absl::string_view FirstUpstreamRxByteReceived =
196
      "US_RX_BEG"; // Upstream response receiving begin.
197
  static constexpr absl::string_view FirstUpstreamRxBodyReceived =
198
      "US_RX_BODY_BEG"; // Upstream response body receiving begin.
199
  static constexpr absl::string_view LastUpstreamRxByteReceived =
200
      "US_RX_END"; // Upstream response receiving end.
201
  static constexpr absl::string_view FirstDownstreamTxByteSent =
202
      "DS_TX_BEG"; // Downstream response sending begin.
203
  static constexpr absl::string_view LastDownstreamTxByteSent =
204
      "DS_TX_END"; // Downstream response sending end.
205

            
206
  TimePointGetter time_point_beg_;
207
  TimePointGetter time_point_end_;
208
  DurationPrecision duration_precision_;
209
};
210

            
211
/**
212
 * Base StreamInfoFormatterProvider for system times from StreamInfo.
213
 */
214
class SystemTimeFormatter : public StreamInfoFormatterProvider {
215
public:
216
  using TimeFieldExtractor =
217
      std::function<absl::optional<SystemTime>(const StreamInfo::StreamInfo& stream_info)>;
218
  using TimeFieldExtractorPtr = std::unique_ptr<TimeFieldExtractor>;
219

            
220
  SystemTimeFormatter(absl::string_view format, TimeFieldExtractorPtr f, bool local_time = false);
221

            
222
  // StreamInfoFormatterProvider
223
  // Don't hide the other structure of format and formatValue.
224
  using StreamInfoFormatterProvider::format;
225
  using StreamInfoFormatterProvider::formatValue;
226
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
227
  Protobuf::Value formatValue(const StreamInfo::StreamInfo&) const override;
228

            
229
private:
230
  const Envoy::DateFormatter date_formatter_;
231
  const TimeFieldExtractorPtr time_field_extractor_;
232
  // Whether use local time zone.
233
  const bool local_time_;
234
};
235

            
236
/**
237
 * SystemTimeFormatter (FormatterProvider) for request start time from StreamInfo.
238
 */
239
class StartTimeFormatter : public SystemTimeFormatter {
240
public:
241
  StartTimeFormatter(absl::string_view format);
242
};
243

            
244
/**
245
 * SystemTimeFormatter (FormatterProvider) for downstream cert start time from the StreamInfo's
246
 * ConnectionInfo.
247
 */
248
class DownstreamPeerCertVStartFormatter : public SystemTimeFormatter {
249
public:
250
  DownstreamPeerCertVStartFormatter(absl::string_view format);
251
};
252

            
253
/**
254
 * SystemTimeFormatter (FormatterProvider) for downstream cert end time from the StreamInfo's
255
 * ConnectionInfo.
256
 */
257
class DownstreamPeerCertVEndFormatter : public SystemTimeFormatter {
258
public:
259
  DownstreamPeerCertVEndFormatter(absl::string_view format);
260
};
261

            
262
/**
263
 * SystemTimeFormatter (FormatterProvider) for upstream cert start time from the StreamInfo's
264
 * upstreamInfo.
265
 */
266
class UpstreamPeerCertVStartFormatter : public SystemTimeFormatter {
267
public:
268
  UpstreamPeerCertVStartFormatter(absl::string_view format);
269
};
270

            
271
/**
272
 * SystemTimeFormatter (FormatterProvider) for upstream cert end time from the StreamInfo's
273
 * upstreamInfo.
274
 */
275
class UpstreamPeerCertVEndFormatter : public SystemTimeFormatter {
276
public:
277
  UpstreamPeerCertVEndFormatter(absl::string_view format);
278
};
279

            
280
/**
281
 * FormatterProvider for environment. If no valid environment value then
282
 */
283
class EnvironmentFormatter : public StreamInfoFormatterProvider {
284
public:
285
  EnvironmentFormatter(absl::string_view key, absl::optional<size_t> max_length);
286

            
287
  // StreamInfoFormatterProvider
288
  // Don't hide the other structure of format and formatValue.
289
  using StreamInfoFormatterProvider::format;
290
  using StreamInfoFormatterProvider::formatValue;
291
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
292
  Protobuf::Value formatValue(const StreamInfo::StreamInfo&) const override;
293

            
294
private:
295
  Protobuf::Value str_;
296
};
297

            
298
/**
299
 * FormatterProvider for requested server name from StreamInfo.
300
 */
301
class RequestedServerNameFormatter : public StreamInfoFormatterProvider {
302
public:
303
  enum HostFormatterSource {
304
    SNI,
305
    SNIFirst,
306
    HostFirst,
307
  };
308
  enum HostFormatterOption {
309
    OriginalHostOrHost,
310
    HostOnly,
311
    OriginalHostOnly,
312
  };
313

            
314
  RequestedServerNameFormatter(absl::string_view fallback, absl::string_view option);
315

            
316
  // StreamInfoFormatterProvider
317
  // Don't hide the other structure of format and formatValue.
318
  using StreamInfoFormatterProvider::format;
319
  using StreamInfoFormatterProvider::formatValue;
320
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
321
  Protobuf::Value formatValue(const StreamInfo::StreamInfo&) const override;
322

            
323
  absl::optional<std::string> getHostFromHeaders(const StreamInfo::StreamInfo& stream_info) const;
324
  absl::optional<std::string> getSNIFromStreamInfo(const StreamInfo::StreamInfo& stream_info) const;
325

            
326
private:
327
  HostFormatterSource source_;
328
  HostFormatterOption option_;
329
};
330

            
331
class DefaultBuiltInStreamInfoCommandParserFactory : public BuiltInCommandParserFactory {
332
public:
333
  std::string name() const override;
334
  CommandParserPtr createCommandParser() const override;
335
};
336

            
337
DECLARE_FACTORY(DefaultBuiltInStreamInfoCommandParserFactory);
338

            
339
} // namespace Formatter
340
} // namespace Envoy