Skip to content

Commit

Permalink
feat(plugins/policies): support opentelemetry tracing
Browse files Browse the repository at this point in the history
Signed-off-by: Benedikt Bongartz <bongartz@klimlive.de>
  • Loading branch information
frzifus committed Feb 11, 2023
1 parent e3f3cbf commit 5184ce7
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 4 deletions.
10 changes: 9 additions & 1 deletion pkg/plugins/policies/meshtrace/api/v1alpha1/meshtrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,20 @@ type Conf struct {
Tags *[]Tag `json:"tags,omitempty"`
}

// Only one of zipkin or datadog can be used.
// Only one of zipkin, datadog or opentelemetry can be used.
type Backend struct {
// Zipkin backend configuration.
Zipkin *ZipkinBackend `json:"zipkin,omitempty"`
// Datadog backend configuration.
Datadog *DatadogBackend `json:"datadog,omitempty"`
// OpenTelemetry backend configuration.
OpenTelemetry *OpenTelemetryBackend `json:"opentelemetry,omitempty"`
}

// OpenTelemetry tracing backend configuration.
type OpenTelemetryBackend struct {
// Address of OpenTelemetry collector e.g. otelcol:4317.
Endpoint string `json:"url"`
}

// Zipkin tracing backend configuration.
Expand Down
19 changes: 18 additions & 1 deletion pkg/plugins/policies/meshtrace/plugin/v1alpha1/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package v1alpha1
import (
net_url "net/url"
"strconv"
"strings"

envoy_listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"

Expand Down Expand Up @@ -168,9 +169,12 @@ func applyToClusters(rules xds.SingleItemRules, rs *xds.ResourceSet, proxy *xds.
if backend.Zipkin != nil {
endpoint = endpointForZipkin(backend.Zipkin)
provider = plugin_xds.ZipkinProviderName
} else {
} else if backend.Datadog != nil {
endpoint = endpointForDatadog(backend.Datadog)
provider = plugin_xds.DatadogProviderName
} else {
endpoint = endpointForOpenTelemetry(backend.OpenTelemetry)
provider = plugin_xds.OpenTelemetryProviderName
}

res, err := clusters.NewClusterBuilder(proxy.APIVersion).
Expand Down Expand Up @@ -200,6 +204,19 @@ func endpointForZipkin(cfg *api.ZipkinBackend) *xds.Endpoint {
}
}

func endpointForOpenTelemetry(cfg *api.OpenTelemetryBackend) *xds.Endpoint {
target := strings.Split(cfg.Endpoint, ":")
port := uint32(4317) // default gRPC port
if len(target) > 1 {
val, _ := strconv.ParseInt(target[1], 10, 32)
port = uint32(val)
}
return &xds.Endpoint{
Target: target[0],
Port: port,
}
}

func endpointForDatadog(cfg *api.DatadogBackend) *xds.Endpoint {
url, _ := net_url.ParseRequestURI(cfg.Url)
port, _ := strconv.ParseInt(url.Port(), 10, 32)
Expand Down
129 changes: 129 additions & 0 deletions pkg/plugins/policies/meshtrace/plugin/v1alpha1/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,135 @@ var _ = Describe("MeshTrace", func() {
portValue: 9411
name: meshtrace:zipkin
type: STRICT_DNS
`},
}),
Entry("inbound/outbound for opentelemetry", testCase{
resources: inboundAndOutbound(),
singleItemRules: core_xds.SingleItemRules{
Rules: []*core_xds.Rule{
{
Subset: []core_xds.Tag{},
Conf: api.Conf{
Tags: &[]api.Tag{
{Name: "app", Literal: pointer.To("backend")},
{Name: "app_code", Header: &api.HeaderTag{Name: "app_code"}},
{Name: "client_id", Header: &api.HeaderTag{Name: "client_id", Default: pointer.To("none")}},
},
Sampling: &api.Sampling{
Overall: pointer.To(intstr.FromInt(10)),
Client: pointer.To(intstr.FromInt(20)),
Random: pointer.To(intstr.FromInt(50)),
},
Backends: &[]api.Backend{{
OpenTelemetry: &api.OpenTelemetryBackend{
Endpoint: "jaeger-collector.mesh-observability:4317",
},
}},
},
},
}},
expectedListeners: []string{`
address:
socketAddress:
address: 127.0.0.1
portValue: 17777
enableReusePort: false
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
httpFilters:
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
statPrefix: "127_0_0_1_17777"
tracing:
clientSampling:
value: 20
customTags:
- literal:
value: backend
tag: app
- requestHeader:
name: app_code
tag: app_code
- requestHeader:
defaultValue: none
name: client_id
tag: client_id
overallSampling:
value: 10
provider:
name: envoy.tracers.opentelemetry
typedConfig:
'@type': type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
grpcService:
envoyGrpc:
clusterName: meshtrace:opentelemetry
serviceName: backend
randomSampling:
value: 50
name: inbound:127.0.0.1:17777
trafficDirection: INBOUND`, `
address:
socketAddress:
address: 127.0.0.1
portValue: 27777
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
httpFilters:
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
statPrefix: "127_0_0_1_27777"
tracing:
clientSampling:
value: 20
customTags:
- literal:
value: backend
tag: app
- requestHeader:
name: app_code
tag: app_code
- requestHeader:
defaultValue: none
name: client_id
tag: client_id
overallSampling:
value: 10
provider:
name: envoy.tracers.opentelemetry
typedConfig:
'@type': type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
grpcService:
envoyGrpc:
clusterName: meshtrace:opentelemetry
serviceName: backend
randomSampling:
value: 50
name: outbound:127.0.0.1:27777
trafficDirection: OUTBOUND
`},
expectedClusters: []string{`
altStatName: meshtrace_opentelemetry
connectTimeout: 10s
dnsLookupFamily: V4_ONLY
loadAssignment:
clusterName: meshtrace:opentelemetry
endpoints:
- lbEndpoints:
- endpoint:
address:
socketAddress:
address: jaeger-collector.mesh-observability
portValue: 4317
name: meshtrace:opentelemetry
type: STRICT_DNS
`},
}),
Entry("inbound/outbound for datadog", testCase{
Expand Down
37 changes: 35 additions & 2 deletions pkg/plugins/policies/meshtrace/plugin/xds/configurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ type Configurer struct {
var _ v3.FilterChainConfigurer = &Configurer{}

const (
ZipkinProviderName = "zipkin"
DatadogProviderName = "datadog"
ZipkinProviderName = "zipkin"
DatadogProviderName = "datadog"
OpenTelemetryProviderName = "opentelemetry"
)

func (c *Configurer) Configure(filterChain *envoy_listener.FilterChain) error {
Expand Down Expand Up @@ -94,6 +95,14 @@ func (c *Configurer) Configure(filterChain *envoy_listener.FilterChain) error {
hcm.Tracing.Provider = tracing
}

if backend.OpenTelemetry != nil {
tracing, err := c.opentelemetryConfig(GetTracingClusterName(OpenTelemetryProviderName))
if err != nil {
return err
}
hcm.Tracing.Provider = tracing
}

return nil
})
}
Expand Down Expand Up @@ -127,6 +136,30 @@ func (c *Configurer) datadogConfig(clusterName string) (*envoy_trace.Tracing_Htt
return tracingConfig, nil
}

func (c *Configurer) opentelemetryConfig(clusterName string) (*envoy_trace.Tracing_Http, error) {
otelConfig := envoy_trace.OpenTelemetryConfig{
ServiceName: c.Service,
GrpcService: &envoy_core.GrpcService{
TargetSpecifier: &envoy_core.GrpcService_EnvoyGrpc_{
EnvoyGrpc: &envoy_core.GrpcService_EnvoyGrpc{
ClusterName: clusterName,
},
},
},
}
otelConfigAny, err := proto.MarshalAnyDeterministic(&otelConfig)
if err != nil {
return nil, err
}
tracingConfig := &envoy_trace.Tracing_Http{
Name: "envoy.tracers.opentelemetry",
ConfigType: &envoy_trace.Tracing_Http_TypedConfig{
TypedConfig: otelConfigAny,
},
}
return tracingConfig, nil
}

func (c *Configurer) zipkinConfig(clusterName string) (*envoy_trace.Tracing_Http, error) {
zipkin := pointer.Deref(c.Conf.Backends)[0].Zipkin
url, err := net_url.ParseRequestURI(zipkin.Url)
Expand Down

0 comments on commit 5184ce7

Please sign in to comment.