Skip to content

Commit 51c4f8e

Browse files
committed
runtime: remove runtime envoy.reloadable_features.logging_with_fast_json_formatter
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
1 parent 62d1e86 commit 51c4f8e

File tree

11 files changed

+163
-611
lines changed

11 files changed

+163
-611
lines changed

changelogs/current.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ removed_config_or_runtime:
6666
- area: runtime
6767
change: |
6868
Removed runtime guard ``envoy_reloadable_features_boolean_to_string_fix`` and legacy code paths.
69+
- area: logging
70+
change: |
71+
Removed runtime guard ``envoy.reloadable_features.logging_with_fast_json_formatter`` and legacy code paths.
6972
- area: sni
7073
change: |
7174
Removed runtime guard ``envoy.reloadable_features.use_route_host_mutation_for_auto_sni_san`` and legacy code paths.

source/common/formatter/substitution_format_string.cc

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@ absl::StatusOr<FormatterPtr> SubstitutionFormatStringUtils::fromProtoConfig(
3737
case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kTextFormat:
3838
return FormatterImpl::create(config.text_format(), config.omit_empty_values(), *commands);
3939
case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kJsonFormat:
40-
return createJsonFormatter(
41-
config.json_format(), true, config.omit_empty_values(),
42-
config.has_json_format_options() ? config.json_format_options().sort_properties() : false,
43-
*commands);
40+
return createJsonFormatter(config.json_format(), config.omit_empty_values(), *commands);
4441
case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kTextFormatSource: {
4542
auto data_source_or_error = Config::DataSource::read(config.text_format_source(), true,
4643
context.serverFactoryContext().api());
@@ -54,23 +51,10 @@ absl::StatusOr<FormatterPtr> SubstitutionFormatStringUtils::fromProtoConfig(
5451
return nullptr;
5552
}
5653

57-
FormatterPtr SubstitutionFormatStringUtils::createJsonFormatter(
58-
const ProtobufWkt::Struct& struct_format, bool preserve_types, bool omit_empty_values,
59-
bool sort_properties, const std::vector<CommandParserPtr>& commands) {
60-
61-
// TODO(alyssawilk, wbpcode) when deprecating logging_with_fast_json_formatter
62-
// remove LegacyJsonFormatterImpl and StructFormatterBase
63-
#ifndef ENVOY_DISABLE_EXCEPTIONS
64-
if (!Runtime::runtimeFeatureEnabled(
65-
"envoy.reloadable_features.logging_with_fast_json_formatter")) {
66-
return std::make_unique<LegacyJsonFormatterImpl>(struct_format, preserve_types,
67-
omit_empty_values, sort_properties, commands);
68-
}
69-
#else
70-
UNREFERENCED_PARAMETER(preserve_types);
71-
UNREFERENCED_PARAMETER(sort_properties);
72-
#endif
73-
54+
FormatterPtr
55+
SubstitutionFormatStringUtils::createJsonFormatter(const ProtobufWkt::Struct& struct_format,
56+
bool omit_empty_values,
57+
const std::vector<CommandParserPtr>& commands) {
7458
return std::make_unique<JsonFormatterImpl>(struct_format, omit_empty_values, commands);
7559
}
7660

source/common/formatter/substitution_format_string.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ class SubstitutionFormatStringUtils {
4545
* Generate a Json formatter object from proto::Struct config
4646
*/
4747
static FormatterPtr createJsonFormatter(const ProtobufWkt::Struct& struct_format,
48-
bool preserve_types, bool omit_empty_values,
49-
bool sort_properties,
48+
bool omit_empty_values,
5049
const std::vector<CommandParserPtr>& commands = {});
5150
};
5251

source/common/formatter/substitution_formatter.h

Lines changed: 0 additions & 253 deletions
Original file line numberDiff line numberDiff line change
@@ -127,258 +127,5 @@ class JsonFormatterImpl : public Formatter {
127127
std::vector<ParsedFormatElement> parsed_elements_;
128128
};
129129

130-
// Helper classes for StructFormatter::StructFormatMapVisitor.
131-
template <class... Ts> struct StructFormatMapVisitorHelper : Ts... {
132-
using Ts::operator()...;
133-
};
134-
template <class... Ts> StructFormatMapVisitorHelper(Ts...) -> StructFormatMapVisitorHelper<Ts...>;
135-
136-
#ifndef ENVOY_DISABLE_EXCEPTIONS
137-
/**
138-
* An formatter for structured log formats, which returns a Struct proto that
139-
* can be converted easily into multiple formats.
140-
*/
141-
class StructFormatter {
142-
public:
143-
using CommandParsers = std::vector<CommandParserPtr>;
144-
using PlainNumber = PlainNumberFormatter;
145-
using PlainString = PlainStringFormatter;
146-
147-
StructFormatter(const ProtobufWkt::Struct& format_mapping, bool preserve_types,
148-
bool omit_empty_values, const CommandParsers& commands = {})
149-
: omit_empty_values_(omit_empty_values), preserve_types_(preserve_types),
150-
struct_output_format_(FormatBuilder(commands).toFormatMapValue(format_mapping)) {}
151-
152-
ProtobufWkt::Struct formatWithContext(const Context& context,
153-
const StreamInfo::StreamInfo& info) const {
154-
StructFormatMapVisitor visitor{
155-
[&](const std::vector<FormatterProviderPtr>& providers) {
156-
return providersCallback(providers, context, info);
157-
},
158-
[&, this](const StructFormatter::StructFormatMapWrapper& format_map) {
159-
return structFormatMapCallback(format_map, visitor);
160-
},
161-
[&, this](const StructFormatter::StructFormatListWrapper& format_list) {
162-
return structFormatListCallback(format_list, visitor);
163-
},
164-
};
165-
return structFormatMapCallback(struct_output_format_, visitor).struct_value();
166-
}
167-
168-
private:
169-
struct StructFormatMapWrapper;
170-
struct StructFormatListWrapper;
171-
using StructFormatValue =
172-
absl::variant<const std::vector<FormatterProviderPtr>, const StructFormatMapWrapper,
173-
const StructFormatListWrapper>;
174-
// Although not required for Struct/JSON, it is nice to have the order of
175-
// properties preserved between the format and the log entry, thus std::map.
176-
using StructFormatMap = std::map<std::string, StructFormatValue>;
177-
using StructFormatMapPtr = std::unique_ptr<StructFormatMap>;
178-
struct StructFormatMapWrapper {
179-
StructFormatMapPtr value_;
180-
};
181-
182-
using StructFormatList = std::list<StructFormatValue>;
183-
using StructFormatListPtr = std::unique_ptr<StructFormatList>;
184-
struct StructFormatListWrapper {
185-
StructFormatListPtr value_;
186-
};
187-
188-
using StructFormatMapVisitor = StructFormatMapVisitorHelper<
189-
const std::function<ProtobufWkt::Value(const std::vector<FormatterProviderPtr>&)>,
190-
const std::function<ProtobufWkt::Value(const StructFormatter::StructFormatMapWrapper&)>,
191-
const std::function<ProtobufWkt::Value(const StructFormatter::StructFormatListWrapper&)>>;
192-
193-
// Methods for building the format map.
194-
class FormatBuilder {
195-
public:
196-
explicit FormatBuilder(const CommandParsers& commands) : commands_(commands) {}
197-
absl::StatusOr<std::vector<FormatterProviderPtr>>
198-
toFormatStringValue(const std::string& string_format) const {
199-
return SubstitutionFormatParser::parse(string_format, commands_);
200-
}
201-
std::vector<FormatterProviderPtr> toFormatNumberValue(double value) const {
202-
std::vector<FormatterProviderPtr> formatters;
203-
formatters.emplace_back(FormatterProviderPtr{new PlainNumber(value)});
204-
return formatters;
205-
}
206-
StructFormatMapWrapper toFormatMapValue(const ProtobufWkt::Struct& struct_format) const {
207-
auto output = std::make_unique<StructFormatMap>();
208-
for (const auto& pair : struct_format.fields()) {
209-
switch (pair.second.kind_case()) {
210-
case ProtobufWkt::Value::kStringValue:
211-
output->emplace(pair.first,
212-
THROW_OR_RETURN_VALUE(toFormatStringValue(pair.second.string_value()),
213-
std::vector<FormatterProviderPtr>));
214-
break;
215-
216-
case ProtobufWkt::Value::kStructValue:
217-
output->emplace(pair.first, toFormatMapValue(pair.second.struct_value()));
218-
break;
219-
220-
case ProtobufWkt::Value::kListValue:
221-
output->emplace(pair.first, toFormatListValue(pair.second.list_value()));
222-
break;
223-
224-
case ProtobufWkt::Value::kNumberValue:
225-
output->emplace(pair.first, toFormatNumberValue(pair.second.number_value()));
226-
break;
227-
default:
228-
throw EnvoyException(
229-
"Only string values, nested structs, list values and number values are "
230-
"supported in structured access log format.");
231-
}
232-
}
233-
return {std::move(output)};
234-
}
235-
StructFormatListWrapper
236-
toFormatListValue(const ProtobufWkt::ListValue& list_value_format) const {
237-
auto output = std::make_unique<StructFormatList>();
238-
for (const auto& value : list_value_format.values()) {
239-
switch (value.kind_case()) {
240-
case ProtobufWkt::Value::kStringValue:
241-
output->emplace_back(THROW_OR_RETURN_VALUE(toFormatStringValue(value.string_value()),
242-
std::vector<FormatterProviderPtr>));
243-
break;
244-
245-
case ProtobufWkt::Value::kStructValue:
246-
output->emplace_back(toFormatMapValue(value.struct_value()));
247-
break;
248-
249-
case ProtobufWkt::Value::kListValue:
250-
output->emplace_back(toFormatListValue(value.list_value()));
251-
break;
252-
253-
case ProtobufWkt::Value::kNumberValue:
254-
output->emplace_back(toFormatNumberValue(value.number_value()));
255-
break;
256-
257-
default:
258-
throw EnvoyException(
259-
"Only string values, nested structs, list values and number values are "
260-
"supported in structured access log format.");
261-
}
262-
}
263-
return {std::move(output)};
264-
}
265-
266-
private:
267-
const CommandParsers& commands_;
268-
};
269-
270-
// Methods for doing the actual formatting.
271-
ProtobufWkt::Value providersCallback(const std::vector<FormatterProviderPtr>& providers,
272-
const Context& context,
273-
const StreamInfo::StreamInfo& stream_info) const {
274-
ASSERT(!providers.empty());
275-
if (providers.size() == 1) {
276-
const auto& provider = providers.front();
277-
if (preserve_types_) {
278-
return provider->formatValueWithContext(context, stream_info);
279-
}
280-
281-
if (omit_empty_values_) {
282-
return ValueUtil::optionalStringValue(provider->formatWithContext(context, stream_info));
283-
}
284-
285-
const auto str = provider->formatWithContext(context, stream_info);
286-
if (str.has_value()) {
287-
return ValueUtil::stringValue(*str);
288-
}
289-
// Returning an "empty string" (depending on omit_empty_values_) in case
290-
// of a formatting error.
291-
return ValueUtil::stringValue(omit_empty_values_ ? EMPTY_STRING
292-
: DefaultUnspecifiedValueStringView);
293-
}
294-
// Multiple providers forces string output.
295-
std::string str;
296-
for (const auto& provider : providers) {
297-
const auto bit = provider->formatWithContext(context, stream_info);
298-
// Add the formatted value if there is one. Otherwise add a default value
299-
// of "-" if omit_empty_values_ is not set.
300-
if (bit.has_value()) {
301-
str += bit.value();
302-
} else if (!omit_empty_values_) {
303-
str += DefaultUnspecifiedValueStringView;
304-
}
305-
}
306-
return ValueUtil::stringValue(str);
307-
}
308-
ProtobufWkt::Value
309-
structFormatMapCallback(const StructFormatter::StructFormatMapWrapper& format_map,
310-
const StructFormatMapVisitor& visitor) const {
311-
ProtobufWkt::Struct output;
312-
auto* fields = output.mutable_fields();
313-
for (const auto& pair : *format_map.value_) {
314-
ProtobufWkt::Value value = absl::visit(visitor, pair.second);
315-
if (omit_empty_values_ && value.kind_case() == ProtobufWkt::Value::kNullValue) {
316-
continue;
317-
}
318-
(*fields)[pair.first] = value;
319-
}
320-
if (omit_empty_values_ && output.fields().empty()) {
321-
return ValueUtil::nullValue();
322-
}
323-
return ValueUtil::structValue(output);
324-
}
325-
ProtobufWkt::Value
326-
structFormatListCallback(const StructFormatter::StructFormatListWrapper& format_list,
327-
const StructFormatMapVisitor& visitor) const {
328-
std::vector<ProtobufWkt::Value> output;
329-
for (const auto& val : *format_list.value_) {
330-
ProtobufWkt::Value value = absl::visit(visitor, val);
331-
if (omit_empty_values_ && value.kind_case() == ProtobufWkt::Value::kNullValue) {
332-
continue;
333-
}
334-
output.push_back(value);
335-
}
336-
return ValueUtil::listValue(output);
337-
}
338-
339-
const bool omit_empty_values_;
340-
const bool preserve_types_;
341-
342-
const StructFormatMapWrapper struct_output_format_;
343-
};
344-
345-
using StructFormatterPtr = std::unique_ptr<StructFormatter>;
346-
347-
class LegacyJsonFormatterImpl : public Formatter {
348-
public:
349-
using CommandParsers = std::vector<CommandParserPtr>;
350-
351-
LegacyJsonFormatterImpl(const ProtobufWkt::Struct& format_mapping, bool preserve_types,
352-
bool omit_empty_values, bool sort_properties,
353-
const CommandParsers& commands = {})
354-
: struct_formatter_(format_mapping, preserve_types, omit_empty_values, commands),
355-
sort_properties_(sort_properties) {}
356-
357-
// Formatter
358-
std::string formatWithContext(const Context& context,
359-
const StreamInfo::StreamInfo& info) const override {
360-
const ProtobufWkt::Struct output_struct = struct_formatter_.formatWithContext(context, info);
361-
362-
std::string log_line = "";
363-
#ifdef ENVOY_ENABLE_YAML
364-
if (sort_properties_) {
365-
log_line = Json::Factory::loadFromProtobufStruct(output_struct)->asJsonString();
366-
} else {
367-
log_line = MessageUtil::getJsonStringFromMessageOrError(output_struct, false, true);
368-
}
369-
#else
370-
UNREFERENCED_PARAMETER(sort_properties_);
371-
IS_ENVOY_BUG("Json support compiled out");
372-
#endif
373-
return absl::StrCat(log_line, "\n");
374-
}
375-
376-
private:
377-
const StructFormatter struct_formatter_;
378-
const bool sort_properties_;
379-
};
380-
381-
#endif // ENVOY_DISABLE_EXCEPTIONS
382-
383130
} // namespace Formatter
384131
} // namespace Envoy

source/common/runtime/runtime_features.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_remove_jwt_from_query_params);
6262
RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_validate_uri);
6363
RUNTIME_GUARD(envoy_reloadable_features_jwt_fetcher_use_scheme_from_uri);
6464
RUNTIME_GUARD(envoy_reloadable_features_local_reply_traverses_filter_chain_after_1xx);
65-
RUNTIME_GUARD(envoy_reloadable_features_logging_with_fast_json_formatter);
6665
RUNTIME_GUARD(envoy_reloadable_features_mmdb_files_reload_enabled);
6766
RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name);
6867
RUNTIME_GUARD(envoy_reloadable_features_normalize_rds_provider_config);

source/extensions/access_loggers/file/config.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ AccessLog::InstanceSharedPtr FileAccessLogFactory::createAccessLogInstance(
4444
break;
4545
case envoy::extensions::access_loggers::file::v3::FileAccessLog::AccessLogFormatCase::kJsonFormat:
4646
formatter = Formatter::SubstitutionFormatStringUtils::createJsonFormatter(
47-
fal_config.json_format(), false, false, false, command_parsers);
47+
fal_config.json_format(), false, command_parsers);
4848
break;
4949
case envoy::extensions::access_loggers::file::v3::FileAccessLog::AccessLogFormatCase::
5050
kTypedJsonFormat: {

source/extensions/access_loggers/fluentd/config.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ AccessLog::InstanceSharedPtr FluentdAccessLogFactory::createAccessLogInstance(
6666
std::vector<Formatter::CommandParserPtr>);
6767

6868
Formatter::FormatterPtr json_formatter =
69-
Formatter::SubstitutionFormatStringUtils::createJsonFormatter(proto_config.record(), true,
70-
false, false, commands);
69+
Formatter::SubstitutionFormatStringUtils::createJsonFormatter(proto_config.record(), false,
70+
commands);
7171
FluentdFormatterPtr fluentd_formatter =
7272
std::make_unique<FluentdFormatterImpl>(std::move(json_formatter));
7373

test/common/formatter/substitution_format_string_test.cc

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,26 +78,6 @@ TEST_F(SubstitutionFormatStringUtilsTest, TestFromProtoConfigJson) {
7878
EXPECT_TRUE(TestUtility::jsonStringEqual(out_json, expected));
7979
}
8080

81-
TEST_F(SubstitutionFormatStringUtilsTest, TestInvalidConfigs) {
82-
TestScopedRuntime runtime;
83-
runtime.mergeValues({{"envoy.reloadable_features.logging_with_fast_json_formatter", "false"}});
84-
85-
const std::vector<std::string> invalid_configs = {
86-
R"(
87-
json_format:
88-
field: true
89-
)",
90-
};
91-
for (const auto& yaml : invalid_configs) {
92-
TestUtility::loadFromYaml(yaml, config_);
93-
EXPECT_THROW_WITH_MESSAGE(
94-
SubstitutionFormatStringUtils::fromProtoConfig(config_, context_).IgnoreError(),
95-
EnvoyException,
96-
"Only string values, nested structs, list values and number values "
97-
"are supported in structured access log format.");
98-
}
99-
}
100-
10181
TEST_F(SubstitutionFormatStringUtilsTest, TestFromProtoConfigFormatterExtension) {
10282
TestCommandFactory factory;
10383
Registry::InjectFactory<CommandParserFactory> command_register(factory);

0 commit comments

Comments
 (0)