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

stat_sinks: add OpenTelemetry stats sink #26620

Merged
merged 43 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7d32f1a
Initial OTLP stats sink implementation
ohadvano Apr 9, 2023
3910f2c
fix format
ohadvano Apr 9, 2023
d1f7e44
fix format
ohadvano Apr 9, 2023
331e52c
fix format
ohadvano Apr 9, 2023
0cf839a
fix format
ohadvano Apr 9, 2023
4ae2466
add docs
ohadvano Apr 9, 2023
d583486
fix doc
ohadvano Apr 9, 2023
468dd57
fix format
ohadvano Apr 9, 2023
1d21a5d
add proto to docs
ohadvano Apr 9, 2023
79bcbf4
update proto with not implemented fields
ohadvano Apr 11, 2023
97b9d7f
add config tests
ohadvano Apr 11, 2023
d248d78
refactor configs and add config tests
ohadvano Apr 11, 2023
0b2b96d
initial unit tests
ohadvano Apr 11, 2023
4c7da6a
unit test class
ohadvano Apr 11, 2023
c9617a9
add unit test
ohadvano Apr 11, 2023
07125c7
add unit tests
ohadvano Apr 12, 2023
70c8d7b
finish unit tests
ohadvano Apr 12, 2023
c7c2f86
initial integration tests
ohadvano Apr 12, 2023
78cf33b
add integration tests
ohadvano Apr 12, 2023
6cf36a9
fix format
ohadvano Apr 12, 2023
bbb2fba
Merge branch 'envoyproxy:main' into ohadvano/otel_stats_sink
ohadvano Apr 12, 2023
8311c94
update tests
ohadvano Apr 13, 2023
8827a09
update tests
ohadvano Apr 13, 2023
81324ad
fix integration tests
ohadvano Apr 14, 2023
37ad5b4
fake update
ohadvano Apr 14, 2023
6ef7cde
fake update
ohadvano Apr 14, 2023
694004f
Merge branch 'envoyproxy:main' into ohadvano/otel_stats_sink
ohadvano Apr 18, 2023
61e7b9a
Update current.yaml
ohadvano Apr 18, 2023
513bb80
Update open_telemetry.proto
ohadvano Apr 19, 2023
cdeaa9a
Merge branch 'envoyproxy:main' into ohadvano/otel_stats_sink
ohadvano Apr 19, 2023
9f202ba
Update open_telemetry.proto
ohadvano Apr 19, 2023
0ae3463
Update open_telemetry.proto
ohadvano Apr 19, 2023
2423a72
Update open_telemetry.proto
ohadvano Apr 19, 2023
2cfa2b2
Merge branch 'main' into ohadvano/otel_stats_sink
ohadvano Apr 20, 2023
0ed59eb
Update open_telemetry.proto
ohadvano Apr 20, 2023
b460280
Merge branch 'envoyproxy:main' into ohadvano/otel_stats_sink
ohadvano Apr 23, 2023
4bced1c
Remove unimplemented API fields, update doc
ohadvano Apr 24, 2023
e061b66
Merge branch 'main' into ohadvano/otel_stats_sink
ohadvano Apr 24, 2023
a19df57
fix typo
ohadvano Apr 24, 2023
5c8743e
fix link
ohadvano Apr 24, 2023
d947205
fix doc
ohadvano Apr 24, 2023
e944ad4
fix test
ohadvano Apr 24, 2023
290efca
address comments
ohadvano Apr 25, 2023
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
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ extensions/filters/common/original_src @snowp @klarose
/*/extensions/stat_sinks/graphite_statsd @vaccarium @mattklein123
/*/extensions/stat_sinks/hystrix @trabetti @jmarantz
/*/extensions/stat_sinks/metrics_service @ramaraochavali @jmarantz
/*/extensions/stat_sinks/open_telemetry @ohadvano @mattklein123
# webassembly stat-sink extensions
/*/extensions/stat_sinks/wasm @mpwarres @mathetake @lizan
/*/extensions/resource_monitors/injected_resource @eziskind @htuch
Expand Down
1 change: 1 addition & 0 deletions api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ proto_library(
"//envoy/extensions/retry/host/previous_hosts/v3:pkg",
"//envoy/extensions/retry/priority/previous_priorities/v3:pkg",
"//envoy/extensions/stat_sinks/graphite_statsd/v3:pkg",
"//envoy/extensions/stat_sinks/open_telemetry/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
"//envoy/extensions/transport_sockets/alts/v3:pkg",
"//envoy/extensions/transport_sockets/http_11_proxy/v3:pkg",
Expand Down
3 changes: 3 additions & 0 deletions api/bazel/external_proto_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ EXTERNAL_PROTO_GO_BAZEL_DEP_MAP = {
"@opencensus_proto//opencensus/proto/trace/v1:trace_config_proto": "@opencensus_proto//opencensus/proto/trace/v1:trace_and_config_proto_go",
"@opentelemetry_proto//:trace": "@opentelemetry_proto//:trace_go_proto",
"@opentelemetry_proto//:logs": "@opentelemetry_proto//:logs_go_proto",
"@opentelemetry_proto//:metrics": "@opentelemetry_proto//:metrics_go_proto",
"@opentelemetry_proto//:common": "@opentelemetry_proto//:common_go_proto",
}

Expand All @@ -45,6 +46,7 @@ EXTERNAL_PROTO_CC_BAZEL_DEP_MAP = {
"@opencensus_proto//opencensus/proto/trace/v1:trace_config_proto": "@opencensus_proto//opencensus/proto/trace/v1:trace_config_proto_cc",
"@opentelemetry_proto//:trace": "@opentelemetry_proto//:trace_cc_proto",
"@opentelemetry_proto//:logs": "@opentelemetry_proto//:logs_cc_proto",
"@opentelemetry_proto//:metrics": "@opentelemetry_proto//:metrics_cc_proto",
"@opentelemetry_proto//:common": "@opentelemetry_proto//:common_cc_proto",
}

Expand All @@ -56,5 +58,6 @@ EXTERNAL_PROTO_PY_BAZEL_DEP_MAP = {
"@opencensus_proto//opencensus/proto/trace/v1:trace_config_proto": "@opencensus_proto//opencensus/proto/trace/v1:trace_config_proto_py",
"@opentelemetry_proto//:trace": "@opentelemetry_proto//:trace_py_proto",
"@opentelemetry_proto//:logs": "@opentelemetry_proto//:logs_py_proto",
"@opentelemetry_proto//:metrics": "@opentelemetry_proto//:metrics_py_proto",
"@opentelemetry_proto//:common": "@opentelemetry_proto//:common_py_proto",
}
20 changes: 20 additions & 0 deletions api/bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,26 @@ go_proto_library(
visibility = ["//visibility:public"],
)

api_cc_py_proto_library(
name = "metrics",
srcs = [
"opentelemetry/proto/collector/metrics/v1/metrics_service.proto",
"opentelemetry/proto/metrics/v1/metrics.proto",
],
deps = [
"//:common",
"//:resource",
],
visibility = ["//visibility:public"],
)

go_proto_library(
name = "metrics_go_proto",
importpath = "go.opentelemetry.io/proto/otlp/metrics/v1",
proto = ":metrics",
visibility = ["//visibility:public"],
)

api_cc_py_proto_library(
name = "trace",
srcs = [
Expand Down
12 changes: 12 additions & 0 deletions api/envoy/extensions/stat_sinks/open_telemetry/v3/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.

load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

licenses(["notice"]) # Apache 2

api_proto_package(
deps = [
"//envoy/config/core/v3:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
syntax = "proto3";

package envoy.extensions.stat_sinks.open_telemetry.v3;

import "envoy/config/core/v3/grpc_service.proto";

import "google/protobuf/wrappers.proto";

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.stat_sinks.open_telemetry.v3";
option java_outer_classname = "OpenTelemetryProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/stat_sinks/open_telemetry/v3;open_telemetryv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Open Telemetry Stats Sink]
// Stats configuration proto schema for ``envoy.stat_sinks.open_telemetry`` sink.
// [#extension: envoy.stat_sinks.open_telemetry]

// [#next-free-field: 6]
message SinkConfig {
oneof protocol_specifier {
option (validate.required) = true;

// The upstream gRPC cluster that implements the OTLP/gRPC collector.
config.core.v3.GrpcService grpc_service = 1 [(validate.rules).message = {required: true}];
}

// If set to true, counters will be emitted as deltas, and the OTLP message will have
// ``AGGREGATION_TEMPORALITY_DELTA`` set as AggregationTemporality.
bool report_counters_as_deltas = 2;

// If set to true, histograms will be emitted as deltas, and the OTLP message will have
// ``AGGREGATION_TEMPORALITY_DELTA`` set as AggregationTemporality.
bool report_histograms_as_deltas = 3;

// If set to true, metrics will have their tags emitted as OTLP attributes, which may
// contain values used by the tag extractor or additional tags added during stats creation.
// Otherwise, no attributes will be associated with the export message. Default value is true.
google.protobuf.BoolValue emit_tags_as_attributes = 4;

// If set to true, metric names will be represented as the tag extracted name instead
// of the full metric name. Default value is true.
google.protobuf.BoolValue use_tag_extracted_name = 5;
}
1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ proto_library(
"//envoy/extensions/retry/host/previous_hosts/v3:pkg",
"//envoy/extensions/retry/priority/previous_priorities/v3:pkg",
"//envoy/extensions/stat_sinks/graphite_statsd/v3:pkg",
"//envoy/extensions/stat_sinks/open_telemetry/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
"//envoy/extensions/transport_sockets/alts/v3:pkg",
"//envoy/extensions/transport_sockets/http_11_proxy/v3:pkg",
Expand Down
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ new_features:
added Runtime feature ``envoy.reloadable_features.max_request_headers_size_kb`` to override the default value of
:ref:`max request headers size
<envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.max_request_headers_kb>`.
- area: stat_sinks
change: |
Added ``envoy.stat_sinks.open_telemetry`` stats_sink, that supports flushing metrics by the OTLP protocol,
for supported Open Telemetry collectors.
- area: redis_proxy
change: |
added new configuration field :ref:`key_formatter
<envoy_v3_api_field_extensions.filters.network.redis_proxy.v3.RedisProxy.PrefixRoutes.Route.key_formatter>` to format redis key.
The field supports using %KEY% as a formatter command for substituting the redis key as part of the substitution formatter expression.

deprecated:
1 change: 1 addition & 0 deletions docs/root/api-v3/config/stat_sinks/stat_sinks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ Stat sinks
:maxdepth: 2

../../extensions/stat_sinks/graphite_statsd/v3/*
../../extensions/stat_sinks/open_telemetry/v3/*
../../extensions/stat_sinks/wasm/v3/*
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.. _config_stat_sinks_open_telemetry:

OpenTelemetry Stat Sink
=========================

The :ref:`OpenTelemetryStatsSink <envoy_v3_api_msg_extensions.stat_sinks.open_telemetry.v3.SinkConfig>` configuration specifies a
stat sink that emits stats according to `OpenTelemetry Protocol Specification <https://opentelemetry.io/docs/reference/specification/protocol/otlp/>`_.
The export requests of this sink are sent to the collector service according to the Protobuf defined in
`MetricService/Export <https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/metrics/v1/metrics_service.proto>`_.
The metric resources exported are defined in `metrics.proto <https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto>`_.
Any export request that this sink sends, will contain a single ``ResourceMetrics`` message, a single ``ScopeMetrics`` and repeated ``MetricRecord``,
according to the number of metrics collected during the proccess run.
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ Stat sinks
:maxdepth: 2

graphite_statsd_stat_sink
open_telemetry_stat_sink
wasm_stat_sink
1 change: 1 addition & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ EXTENSIONS = {
"envoy.stat_sinks.graphite_statsd": "//source/extensions/stat_sinks/graphite_statsd:config",
"envoy.stat_sinks.hystrix": "//source/extensions/stat_sinks/hystrix:config",
"envoy.stat_sinks.metrics_service": "//source/extensions/stat_sinks/metrics_service:config",
"envoy.stat_sinks.open_telemetry": "//source/extensions/stat_sinks/open_telemetry:config",
"envoy.stat_sinks.statsd": "//source/extensions/stat_sinks/statsd:config",
"envoy.stat_sinks.wasm": "//source/extensions/stat_sinks/wasm:config",

Expand Down
7 changes: 7 additions & 0 deletions source/extensions/extensions_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,13 @@ envoy.stat_sinks.metrics_service:
status: stable
type_urls:
- envoy.config.metrics.v3.MetricsServiceConfig
envoy.stat_sinks.open_telemetry:
categories:
- envoy.stats_sinks
security_posture: data_plane_agnostic
status: alpha
type_urls:
- envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig
envoy.stat_sinks.statsd:
categories:
- envoy.stats_sinks
Expand Down
45 changes: 45 additions & 0 deletions source/extensions/stat_sinks/open_telemetry/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_cc_library",
"envoy_extension_package",
)

licenses(["notice"]) # Apache 2

envoy_extension_package()

envoy_cc_library(
name = "open_telemetry_lib",
srcs = ["open_telemetry_impl.cc"],
hdrs = ["open_telemetry_impl.h"],
deps = [
"//envoy/grpc:async_client_interface",
"//envoy/singleton:instance_interface",
"//source/common/grpc:async_client_lib",
"@envoy_api//envoy/extensions/stat_sinks/open_telemetry/v3:pkg_cc_proto",
"@opentelemetry_proto//:metrics_cc_proto",
],
)

envoy_cc_library(
name = "open_telemetry_proto_descriptors_lib",
srcs = ["open_telemetry_proto_descriptors.cc"],
hdrs = ["open_telemetry_proto_descriptors.h"],
deps = [
"//source/common/common:assert_lib",
"//source/common/protobuf",
],
)

envoy_cc_extension(
name = "config",
srcs = ["config.cc"],
hdrs = ["config.h"],
deps = [
":open_telemetry_lib",
":open_telemetry_proto_descriptors_lib",
"//envoy/registry",
"//source/server:configuration_lib",
],
)
60 changes: 60 additions & 0 deletions source/extensions/stat_sinks/open_telemetry/config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "source/extensions/stat_sinks/open_telemetry/config.h"

#include "envoy/registry/registry.h"

#include "source/extensions/stat_sinks/open_telemetry/open_telemetry_impl.h"
#include "source/extensions/stat_sinks/open_telemetry/open_telemetry_proto_descriptors.h"

namespace Envoy {
namespace Extensions {
namespace StatSinks {
namespace OpenTelemetry {

Stats::SinkPtr
OpenTelemetrySinkFactory::createStatsSink(const Protobuf::Message& config,
Server::Configuration::ServerFactoryContext& server) {
validateProtoDescriptors();

const auto& sink_config = MessageUtil::downcastAndValidate<const SinkConfig&>(
config, server.messageValidationContext().staticValidationVisitor());

auto otlp_options = std::make_shared<OtlpOptions>(sink_config);
std::shared_ptr<OtlpMetricsFlusher> otlp_metrics_flusher =
std::make_shared<OtlpMetricsFlusherImpl>(otlp_options);

switch (sink_config.protocol_specifier_case()) {
case SinkConfig::ProtocolSpecifierCase::kGrpcService: {
const auto& grpc_service = sink_config.grpc_service();

std::shared_ptr<OpenTelemetryGrpcMetricsExporter> grpc_metrics_exporter =
std::make_shared<OpenTelemetryGrpcMetricsExporterImpl>(
otlp_options,
server.clusterManager().grpcAsyncClientManager().getOrCreateRawAsyncClient(
grpc_service, server.scope(), false));

return std::make_unique<OpenTelemetryGrpcSink>(otlp_metrics_flusher, grpc_metrics_exporter);
}

default:
break;
}

throw EnvoyException("unexpected Open Telemetry protocol case num");
}

ProtobufTypes::MessagePtr OpenTelemetrySinkFactory::createEmptyConfigProto() {
return std::make_unique<SinkConfig>();
}

std::string OpenTelemetrySinkFactory::name() const { return OpenTelemetryName; }

/**
* Static registration for the this sink factory. @see RegisterFactory.
*/
LEGACY_REGISTER_FACTORY(OpenTelemetrySinkFactory, Server::Configuration::StatsSinkFactory,
"envoy.open_telemetry_stat_sink");

} // namespace OpenTelemetry
} // namespace StatSinks
} // namespace Extensions
} // namespace Envoy
34 changes: 34 additions & 0 deletions source/extensions/stat_sinks/open_telemetry/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include "envoy/registry/registry.h"
#include "envoy/server/instance.h"

#include "source/server/configuration_impl.h"

namespace Envoy {
namespace Extensions {
namespace StatSinks {
namespace OpenTelemetry {

constexpr char OpenTelemetryName[] = "envoy.stat_sinks.open_telemetry";

/**
* Config registration for the OpenTelemetry stats sink. @see StatsSinkFactory.
*/
class OpenTelemetrySinkFactory : Logger::Loggable<Logger::Id::config>,
public Server::Configuration::StatsSinkFactory {
public:
Stats::SinkPtr createStatsSink(const Protobuf::Message& config,
Server::Configuration::ServerFactoryContext& server) override;

ProtobufTypes::MessagePtr createEmptyConfigProto() override;

std::string name() const override;
};

DECLARE_FACTORY(OpenTelemetrySinkFactory);

} // namespace OpenTelemetry
} // namespace StatSinks
} // namespace Extensions
} // namespace Envoy
Loading