Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OTLP proto dependencies #14471

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions api/bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def api_dependencies():
name = "com_github_apache_skywalking_data_collect_protocol",
build_file_content = SKYWALKING_DATA_COLLECT_PROTOCOL_BUILD_CONTENT,
)
external_http_archive(
name = "opentelemetry_proto",
build_file_content = OPENTELEMETRY_LOGS_BUILD_CONTENT,
)

PROMETHEUSMETRICS_BUILD_CONTENT = """
load("@envoy_api//bazel:api_build_system.bzl", "api_cc_py_proto_library")
Expand Down Expand Up @@ -132,3 +136,25 @@ go_proto_library(
visibility = ["//visibility:public"],
)
"""

OPENTELEMETRY_LOGS_BUILD_CONTENT = """
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_cc//cc:defs.bzl", "cc_proto_library")

proto_library(
name = "logs",
srcs = [
"opentelemetry/proto/collector/logs/v1/logs_service.proto",
"opentelemetry/proto/common/v1/common.proto",
"opentelemetry/proto/logs/v1/logs.proto",
"opentelemetry/proto/resource/v1/resource.proto",
],
visibility = ["//visibility:public"],
)

cc_proto_library(
name = "logs_cc_proto",
deps = [":logs"],
visibility = ["//visibility:public"],
)
"""
11 changes: 11 additions & 0 deletions api/bazel/repository_locations.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,15 @@ REPOSITORY_LOCATIONS_SPEC = dict(
release_date = "2020-07-29",
use_category = ["api"],
),
opentelemetry_proto = dict(
project_name = "OpenTelemetry Proto",
project_desc = "Language Independent Interface Types For OpenTelemetry",
project_url = "https://github.com/open-telemetry/opentelemetry-proto",
version = "0.6.0",
sha256 = "08f090570e0a112bfae276ba37e9c45bf724b64d902a7a001db33123b840ebd6",
strip_prefix = "opentelemetry-proto-{version}",
urls = ["https://github.com/open-telemetry/opentelemetry-proto/archive/v{version}.tar.gz"],
release_date = "2020-10-29",
use_category = ["api"],
),
)
26 changes: 26 additions & 0 deletions generated_api_shadow/bazel/repositories.bzl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions generated_api_shadow/bazel/repository_locations.bzl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

173 changes: 56 additions & 117 deletions source/common/formatter/substitution_formatter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const std::regex& getSystemTimeFormatNewlinePattern() {
}
const std::regex& getNewlinePattern() { CONSTRUCT_ON_FIRST_USE(std::regex, "\n"); }

template <class... Ts> struct StructFormatMapVisitor : Ts... { using Ts::operator()...; };
template <class... Ts> StructFormatMapVisitor(Ts...) -> StructFormatMapVisitor<Ts...>;

} // namespace

const std::string SubstitutionFormatUtils::DEFAULT_FORMAT =
Expand Down Expand Up @@ -145,56 +148,20 @@ std::string JsonFormatterImpl::format(const Http::RequestHeaderMap& request_head
return absl::StrCat(log_line, "\n");
}

StructFormatter::StructFormatter(const ProtobufWkt::Struct& format_mapping, bool preserve_types,
bool omit_empty_values)
: omit_empty_values_(omit_empty_values), preserve_types_(preserve_types),
empty_value_(omit_empty_values_ ? EMPTY_STRING : DefaultUnspecifiedValueString),
struct_output_format_(toFormatMapValue(format_mapping)) {}

StructFormatter::StructFormatMapWrapper
StructFormatter::toFormatMapValue(const ProtobufWkt::Struct& struct_format) const {
StructFormatter::toFormatMap(const ProtobufWkt::Struct& struct_format) const {
auto output = std::make_unique<StructFormatMap>();
for (const auto& pair : struct_format.fields()) {
switch (pair.second.kind_case()) {
case ProtobufWkt::Value::kStringValue:
output->emplace(pair.first, toFormatStringValue(pair.second.string_value()));
break;

case ProtobufWkt::Value::kStructValue:
output->emplace(pair.first, toFormatMapValue(pair.second.struct_value()));
break;

case ProtobufWkt::Value::kListValue:
output->emplace(pair.first, toFormatListValue(pair.second.list_value()));
break;

default:
throw EnvoyException("Only string values, nested structs and list values are "
"supported in structured access log format.");
}
}
return {std::move(output)};
};

StructFormatter::StructFormatListWrapper
StructFormatter::toFormatListValue(const ProtobufWkt::ListValue& list_value_format) const {
auto output = std::make_unique<StructFormatList>();
for (const auto& value : list_value_format.values()) {
switch (value.kind_case()) {
case ProtobufWkt::Value::kStringValue:
output->emplace_back(toFormatStringValue(value.string_value()));
output->emplace(pair.first, SubstitutionFormatParser::parse(pair.second.string_value()));
break;

case ProtobufWkt::Value::kStructValue:
output->emplace_back(toFormatMapValue(value.struct_value()));
break;

case ProtobufWkt::Value::kListValue:
output->emplace_back(toFormatListValue(value.list_value()));
output->emplace(pair.first, toFormatMap(pair.second.struct_value()));
break;
default:
throw EnvoyException("Only string values, nested structs and list values are "
"supported in structured access log format.");
throw EnvoyException(
"Only string values or nested structs are supported in structured access log format.");
}
}
return {std::move(output)};
Expand All @@ -205,85 +172,57 @@ StructFormatter::toFormatStringValue(const std::string& string_format) const {
return SubstitutionFormatParser::parse(string_format);
};

ProtobufWkt::Value StructFormatter::providersCallback(
const std::vector<FormatterProviderPtr>& providers,
const Http::RequestHeaderMap& request_headers, const Http::ResponseHeaderMap& response_headers,
const Http::ResponseTrailerMap& response_trailers, const StreamInfo::StreamInfo& stream_info,
absl::string_view local_reply_body) const {
ASSERT(!providers.empty());
if (providers.size() == 1) {
const auto& provider = providers.front();
if (preserve_types_) {
return provider->formatValue(request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
}

if (omit_empty_values_) {
return ValueUtil::optionalStringValue(provider->format(
request_headers, response_headers, response_trailers, stream_info, local_reply_body));
}

const auto str = provider->format(request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
return ValueUtil::stringValue(str.value_or(DefaultUnspecifiedValueString));
}
// Multiple providers forces string output.
std::string str;
for (const auto& provider : providers) {
const auto bit = provider->format(request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
str += bit.value_or(empty_value_);
}
return ValueUtil::stringValue(str);
}

ProtobufWkt::Value StructFormatter::structFormatMapCallback(
const StructFormatter::StructFormatMapWrapper& format_map,
const StructFormatter::StructFormatMapVisitor& visitor) const {
ProtobufWkt::Struct output;
auto* fields = output.mutable_fields();
for (const auto& pair : *format_map.value_) {
ProtobufWkt::Value value = absl::visit(visitor, pair.second);
if (omit_empty_values_ && value.kind_case() == ProtobufWkt::Value::kNullValue) {
continue;
}
(*fields)[pair.first] = value;
}
return ValueUtil::structValue(output);
}

ProtobufWkt::Value StructFormatter::structFormatListCallback(
const StructFormatter::StructFormatListWrapper& format_list,
const StructFormatter::StructFormatMapVisitor& visitor) const {
std::vector<ProtobufWkt::Value> output;
for (const auto& val : *format_list.value_) {
ProtobufWkt::Value value = absl::visit(visitor, val);
if (omit_empty_values_ && value.kind_case() == ProtobufWkt::Value::kNullValue) {
continue;
}
output.push_back(value);
}
return ValueUtil::listValue(output);
}

ProtobufWkt::Struct StructFormatter::format(const Http::RequestHeaderMap& request_headers,
const Http::ResponseHeaderMap& response_headers,
const Http::ResponseTrailerMap& response_trailers,
const StreamInfo::StreamInfo& stream_info,
absl::string_view local_reply_body) const {
StructFormatMapVisitor visitor{
[&](const std::vector<FormatterProviderPtr>& providers) {
return providersCallback(providers, request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
},
[&, this](const StructFormatter::StructFormatMapWrapper& format_map) {
return structFormatMapCallback(format_map, visitor);
},
[&, this](const StructFormatter::StructFormatListWrapper& format_list) {
return structFormatListCallback(format_list, visitor);
},
};
return structFormatMapCallback(struct_output_format_, visitor).struct_value();
const std::string& empty_value =
omit_empty_values_ ? EMPTY_STRING : DefaultUnspecifiedValueString;
const std::function<ProtobufWkt::Value(const std::vector<FormatterProviderPtr>&)>
providers_callback = [&](const std::vector<FormatterProviderPtr>& providers) {
ASSERT(!providers.empty());
if (providers.size() == 1) {
const auto& provider = providers.front();
if (preserve_types_) {
return provider->formatValue(request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
}

if (omit_empty_values_) {
return ValueUtil::optionalStringValue(
provider->format(request_headers, response_headers, response_trailers, stream_info,
local_reply_body));
}

const auto str = provider->format(request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
return ValueUtil::stringValue(str.value_or(DefaultUnspecifiedValueString));
}
// Multiple providers forces string output.
std::string str;
for (const auto& provider : providers) {
const auto bit = provider->format(request_headers, response_headers, response_trailers,
stream_info, local_reply_body);
str += bit.value_or(empty_value);
}
return ValueUtil::stringValue(str);
};
const std::function<ProtobufWkt::Value(const StructFormatter::StructFormatMapWrapper&)>
struct_format_map_callback = [&](const StructFormatter::StructFormatMapWrapper& format) {
ProtobufWkt::Struct output;
auto* fields = output.mutable_fields();
StructFormatMapVisitor visitor{struct_format_map_callback, providers_callback};
for (const auto& pair : *format.value_) {
ProtobufWkt::Value value = absl::visit(visitor, pair.second);
if (omit_empty_values_ && value.kind_case() == ProtobufWkt::Value::kNullValue) {
continue;
}
(*fields)[pair.first] = value;
}
return ValueUtil::structValue(output);
};
return struct_format_map_callback(struct_output_format_).struct_value();
}

void SubstitutionFormatParser::parseCommandHeader(const std::string& token, const size_t start,
Expand Down Expand Up @@ -1141,8 +1080,8 @@ MetadataFormatter::formatMetadataValue(const envoy::config::core::v3::Metadata&
return val;
}

// TODO(glicht): Consider adding support for route/listener/cluster metadata as suggested by
// @htuch. See: https://github.com/envoyproxy/envoy/issues/3006
// TODO(glicht): Consider adding support for route/listener/cluster metadata as suggested by @htuch.
// See: https://github.com/envoyproxy/envoy/issues/3006
DynamicMetadataFormatter::DynamicMetadataFormatter(const std::string& filter_namespace,
const std::vector<std::string>& path,
absl::optional<size_t> max_length)
Expand Down
Loading