1
#pragma once
2

            
3
#include <memory>
4
#include <string>
5

            
6
#include "envoy/access_log/access_log.h"
7
#include "envoy/common/pure.h"
8
#include "envoy/config/typed_config.h"
9
#include "envoy/formatter/http_formatter_context.h"
10
#include "envoy/registry/registry.h"
11
#include "envoy/server/factory_context.h"
12
#include "envoy/stream_info/stream_info.h"
13

            
14
namespace Envoy {
15
namespace Formatter {
16

            
17
/**
18
 * Interface for multiple protocols/modules formatters.
19
 */
20
class Formatter {
21
public:
22
25433
  virtual ~Formatter() = default;
23

            
24
  /**
25
   * Return a formatted substitution line.
26
   * @param context supplies the formatter context.
27
   * @param stream_info supplies the stream info.
28
   * @return std::string string containing the complete formatted substitution line.
29
   */
30
  virtual std::string format(const Context& context,
31
                             const StreamInfo::StreamInfo& stream_info) const PURE;
32
};
33

            
34
using FormatterPtr = std::unique_ptr<Formatter>;
35
using FormatterConstSharedPtr = std::shared_ptr<const Formatter>;
36

            
37
/**
38
 * Interface for multiple protocols/modules formatter providers.
39
 */
40
class FormatterProvider {
41
public:
42
604980
  virtual ~FormatterProvider() = default;
43

            
44
  /**
45
   * Format the value with the given context and stream info.
46
   * @param context supplies the formatter context.
47
   * @param stream_info supplies the stream info.
48
   * @return absl::optional<std::string> optional string containing a single value extracted from
49
   *         the given context and stream info.
50
   */
51
  virtual absl::optional<std::string> format(const Context& context,
52
                                             const StreamInfo::StreamInfo& stream_info) const PURE;
53

            
54
  /**
55
   * Format the value with the given context and stream info.
56
   * @param context supplies the formatter context.
57
   * @param stream_info supplies the stream info.
58
   * @return Protobuf::Value containing a single value extracted from the given
59
   *         context and stream info.
60
   */
61
  virtual Protobuf::Value formatValue(const Context& context,
62
                                      const StreamInfo::StreamInfo& stream_info) const PURE;
63
};
64

            
65
using FormatterProviderPtr = std::unique_ptr<FormatterProvider>;
66

            
67
class CommandParser {
68
public:
69
1234
  virtual ~CommandParser() = default;
70

            
71
  /**
72
   * Return a FormatterProviderBasePtr if command arg and max_length are correct for the formatter
73
   * provider associated with command.
74
   * @param command command name.
75
   * @param command_arg command specific argument. Empty if no argument is provided.
76
   * @param max_length length to which the output produced by FormatterProvider
77
   *                   should be truncated to (optional).
78
   *
79
   * @return FormattterProviderPtr substitution provider for the parsed command.
80
   */
81
  virtual FormatterProviderPtr parse(absl::string_view command, absl::string_view command_arg,
82
                                     absl::optional<size_t> max_length) const PURE;
83
};
84

            
85
using CommandParserPtr = std::unique_ptr<CommandParser>;
86
using CommandParserPtrVector = std::vector<CommandParserPtr>;
87

            
88
class CommandParserFactory : public Config::TypedFactory {
89
public:
90
  /**
91
   * Creates a particular CommandParser implementation.
92
   *
93
   * @param config supplies the configuration for the command parser.
94
   * @param context supplies the factory context.
95
   * @return CommandParserPtr the CommandParser which will be used in
96
   * SubstitutionFormatParser::parse() when evaluating an access log format string.
97
   */
98
  virtual CommandParserPtr
99
  createCommandParserFromProto(const Protobuf::Message& config,
100
                               Server::Configuration::GenericFactoryContext& context) PURE;
101

            
102
42
  std::string category() const override { return "envoy.formatter"; }
103
};
104

            
105
class BuiltInCommandParserFactory : public Config::UntypedFactory {
106
public:
107
1756
  std::string category() const override { return "envoy.built_in_formatters"; }
108

            
109
  /**
110
   * Creates a particular CommandParser implementation.
111
   */
112
  virtual CommandParserPtr createCommandParser() const PURE;
113
};
114

            
115
/**
116
 * Helper class to get all built-in command parsers for a given formatter context.
117
 */
118
class BuiltInCommandParserFactoryHelper {
119
public:
120
  using Factory = BuiltInCommandParserFactory;
121
  using Parsers = std::vector<CommandParserPtr>;
122

            
123
  /**
124
   * Get all built-in command parsers for a given formatter context.
125
   * @return Parsers all built-in command parsers for a given formatter context.
126
   */
127
290789
  static const Parsers& commandParsers() {
128
290789
    CONSTRUCT_ON_FIRST_USE(Parsers, []() {
129
290789
      Parsers parsers;
130
290789
      for (const auto& factory : Envoy::Registry::FactoryRegistry<Factory>::factories()) {
131
290789
        if (auto parser = factory.second->createCommandParser(); parser == nullptr) {
132
290789
          ENVOY_BUG(false, fmt::format("Null built-in command parser: {}", factory.first));
133
290789
          continue;
134
290789
        } else {
135
290789
          parsers.push_back(std::move(parser));
136
290789
        }
137
290789
      }
138
290789
      return parsers;
139
290789
    }());
140
290789
  }
141
};
142

            
143
} // namespace Formatter
144
} // namespace Envoy