Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ routes:
unmatched: path
prometheus_export:
port: 8999
features:
- application
- application_process
otel_traces_export:
endpoint: http://jaeger:4318
meter_provider:
obi_features:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we call them obi_features, instead of features?

- application
- application_process
attributes:
kubernetes:
cluster_name: obi-k8s-test-cluster
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ metadata:
data:
obi-config.yml: |
log_level: debug
meter_provider:
obi_features: ["network", "network_inter_zone"]
otel_metrics_export:
endpoint: http://otelcol.default:4317
features: ["network", "network_inter_zone"]
network:
protocols:
- TCP
Expand Down
17 changes: 10 additions & 7 deletions pkg/appolly/instrumenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,13 @@ func newGraphBuilder(
// some nodes (ipNodesFilter, span name limiter...) are only passed to the metrics export nodes.
// Nodes directly handling raw traces will still get the unfiltered exportableSpans queue.
// If no metrics exporter is configured, we will not start the metrics subpipeline to save resources.
exportingMetrics := config.Metrics.Enabled() ||
config.Metrics.ServiceGraphMetricsEnabled() ||
config.Prometheus.Enabled()
exportingMetrics := config.MeterProvider.Features.AnyAppO11yMetric() &&
(config.Metrics.EndpointEnabled() || config.Prometheus.EndpointEnabled())
if exportingMetrics {
setupMetricsSubPipeline(config, ctxInfo, swi, exportableSpans, selectorCfg, processEventsCh)
}

swi.Add(prom.BPFMetrics(ctxInfo, &config.Prometheus),
swi.Add(prom.BPFMetrics(ctxInfo, &config.Prometheus, &config.MeterProvider),
swarm.WithID("BPFMetrics"))

// The returned builder later invokes its "Build" function that, given
Expand All @@ -155,9 +154,10 @@ func setupMetricsSubPipeline(

spanNameAggregatedMetrics := newQueue("spanNameAggregatedMetrics")
swi.Add(transform.SpanNameLimiter(transform.SpanNameLimiterConfig{
Limit: config.Attributes.MetricSpanNameAggregationLimit,
OTEL: &config.Metrics,
Prom: &config.Prometheus,
Limit: config.Attributes.MetricSpanNameAggregationLimit,
OTEL: &config.Metrics,
Prom: &config.Prometheus,
MeterProvider: &config.MeterProvider,
}, exportableSpans, spanNameAggregatedMetrics))

unresolvedCfg := request.UnresolvedNames{
Expand All @@ -169,6 +169,7 @@ func setupMetricsSubPipeline(
swi.Add(otel.ReportMetrics(
ctxInfo,
&config.Metrics,
&config.MeterProvider,
selectorCfg,
unresolvedCfg,
spanNameAggregatedMetrics,
Expand All @@ -178,6 +179,7 @@ func setupMetricsSubPipeline(
swi.Add(otel.ReportSvcGraphMetrics(
ctxInfo,
&config.Metrics,
&config.MeterProvider,
unresolvedCfg,
spanNameAggregatedMetrics,
processEventsCh,
Expand All @@ -186,6 +188,7 @@ func setupMetricsSubPipeline(
swi.Add(prom.PrometheusEndpoint(
ctxInfo,
&config.Prometheus,
&config.MeterProvider,
selectorCfg,
unresolvedCfg,
spanNameAggregatedMetrics,
Expand Down
41 changes: 23 additions & 18 deletions pkg/appolly/instrumenter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
attr "go.opentelemetry.io/obi/pkg/export/attributes/names"
"go.opentelemetry.io/obi/pkg/export/imetrics"
"go.opentelemetry.io/obi/pkg/export/instrumentations"
"go.opentelemetry.io/obi/pkg/export/otel/decfg"
"go.opentelemetry.io/obi/pkg/export/otel/otelcfg"
"go.opentelemetry.io/obi/pkg/filter"
"go.opentelemetry.io/obi/pkg/internal/testutil"
Expand Down Expand Up @@ -56,6 +57,10 @@ var allMetrics = attributes.Selection{
"*": attributes.InclusionLists{Include: []string{"*"}},
}

var mpConfig = decfg.MeterProvider{
Features: export.FeatureApplicationRED,
}

func allMetricsBut(patterns ...string) attributes.Selection {
return attributes.Selection{
attributes.HTTPServerDuration.Section: attributes.InclusionLists{
Expand All @@ -74,7 +79,6 @@ func TestBasicPipeline(t *testing.T) {
tracesInput := msg.NewQueue[[]request.Span](msg.ChannelBufferLen(10))
processEvents := msg.NewQueue[exec.ProcessEvent](msg.ChannelBufferLen(20))
cfg := otelcfg.MetricsConfig{
Features: export.FeatureApplication,
MetricsEndpoint: tc.ServerEndpoint, Interval: 10 * time.Millisecond,
ReportersCacheLen: 16,
TTL: 5 * time.Minute,
Expand All @@ -83,9 +87,10 @@ func TestBasicPipeline(t *testing.T) {
},
}
gb := newGraphBuilder(&obi.Config{
NameResolver: obi.DefaultConfig.NameResolver,
Metrics: cfg,
Attributes: obi.Attributes{Select: allMetrics, InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"}},
NameResolver: obi.DefaultConfig.NameResolver,
MeterProvider: mpConfig,
Metrics: cfg,
Attributes: obi.Attributes{Select: allMetrics, InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"}},
}, gctx(0, &cfg), tracesInput, processEvents)

// Override eBPF tracer to send some fake data
Expand Down Expand Up @@ -193,7 +198,6 @@ func TestMergedMetricsTracePipeline(t *testing.T) {
tracesInput := msg.NewQueue[[]request.Span](msg.ChannelBufferLen(10))
processEvents := msg.NewQueue[exec.ProcessEvent](msg.ChannelBufferLen(20))
mCfg := otelcfg.MetricsConfig{
Features: export.FeatureApplication,
MetricsEndpoint: tc.ServerEndpoint, Interval: 10 * time.Millisecond,
ReportersCacheLen: 16,
TTL: 5 * time.Minute,
Expand All @@ -210,8 +214,9 @@ func TestMergedMetricsTracePipeline(t *testing.T) {
}

gb := newGraphBuilder(&obi.Config{
Metrics: mCfg,
Traces: tCfg,
Metrics: mCfg,
Traces: tCfg,
MeterProvider: mpConfig,
Attributes: obi.Attributes{
Select: allMetrics,
InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"},
Expand Down Expand Up @@ -282,7 +287,6 @@ func TestRouteConsolidation(t *testing.T) {

cfg := otelcfg.MetricsConfig{
SDKLogLevel: "debug",
Features: export.FeatureApplication,
MetricsEndpoint: tc.ServerEndpoint, Interval: 10 * time.Millisecond,
ReportersCacheLen: 16,
TTL: 5 * time.Minute,
Expand All @@ -291,9 +295,10 @@ func TestRouteConsolidation(t *testing.T) {
},
}
gb := newGraphBuilder(&obi.Config{
Metrics: cfg,
Routes: &transform.RoutesConfig{Patterns: []string{"/user/{id}", "/products/{id}/push"}},
Attributes: obi.Attributes{Select: allMetricsBut("client.address", "url.path"), InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"}},
Metrics: cfg,
MeterProvider: mpConfig,
Routes: &transform.RoutesConfig{Patterns: []string{"/user/{id}", "/products/{id}/push"}},
Attributes: obi.Attributes{Select: allMetricsBut("client.address", "url.path"), InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"}},
}, gctx(attributes.GroupHTTPRoutes, &cfg), tracesInput, processEvents)
// Override eBPF tracer to send some fake data
tracesInput.Send(newRequest("svc-1", "/user/1234", 200))
Expand Down Expand Up @@ -416,7 +421,6 @@ func TestGRPCPipeline(t *testing.T) {
processEvents := msg.NewQueue[exec.ProcessEvent](msg.ChannelBufferLen(20))

cfg := otelcfg.MetricsConfig{
Features: export.FeatureApplication,
MetricsEndpoint: tc.ServerEndpoint, Interval: time.Millisecond,
ReportersCacheLen: 16,
TTL: 5 * time.Minute,
Expand All @@ -425,8 +429,9 @@ func TestGRPCPipeline(t *testing.T) {
},
}
gb := newGraphBuilder(&obi.Config{
Metrics: cfg,
Attributes: obi.Attributes{Select: allMetrics, InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"}},
Metrics: cfg,
MeterProvider: mpConfig,
Attributes: obi.Attributes{Select: allMetrics, InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"}},
}, gctx(0, &cfg), tracesInput, processEvents)
// Override eBPF tracer to send some fake data
tracesInput.Send(newGRPCRequest("grpc-svc", "/foo/bar", 3))
Expand Down Expand Up @@ -514,7 +519,6 @@ func TestBasicPipelineInfo(t *testing.T) {
tracesInput := msg.NewQueue[[]request.Span](msg.ChannelBufferLen(10))
processEvents := msg.NewQueue[exec.ProcessEvent](msg.ChannelBufferLen(20))
cfg := otelcfg.MetricsConfig{
Features: export.FeatureApplication,
MetricsEndpoint: tc.ServerEndpoint,
Interval: 10 * time.Millisecond, ReportersCacheLen: 16,
TTL: 5 * time.Minute,
Expand All @@ -523,7 +527,8 @@ func TestBasicPipelineInfo(t *testing.T) {
},
}
gb := newGraphBuilder(&obi.Config{
Metrics: cfg,
Metrics: cfg,
MeterProvider: mpConfig,
Attributes: obi.Attributes{
Select: allMetrics,
InstanceID: config.InstanceIDConfig{OverrideHostname: "the-host"},
Expand Down Expand Up @@ -609,14 +614,14 @@ func TestSpanAttributeFilterNode(t *testing.T) {
processEvents := msg.NewQueue[exec.ProcessEvent](msg.ChannelBufferLen(20))
cfg := otelcfg.MetricsConfig{
SDKLogLevel: "debug",
Features: export.FeatureApplication,
MetricsEndpoint: tc.ServerEndpoint, Interval: 10 * time.Millisecond,
ReportersCacheLen: 16,
TTL: 5 * time.Minute,
Instrumentations: []instrumentations.Instrumentation{instrumentations.InstrumentationALL},
}
gb := newGraphBuilder(&obi.Config{
Metrics: cfg,
Metrics: cfg,
MeterProvider: mpConfig,
Filters: filter.AttributesConfig{
Application: map[string]filter.MatchDefinition{"url.path": {Match: "/user/*"}},
},
Expand Down
80 changes: 74 additions & 6 deletions pkg/export/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ type Features maps.Bits
const (
FeatureNetwork Features = 1 << iota
FeatureNetworkInterZone
FeatureApplication
FeatureSpan
FeatureApplicationRED
FeatureSpanLegacy
FeatureSpanOTel
FeatureSpanSizes
FeatureGraph
Expand All @@ -33,8 +33,8 @@ const (
var featureMapper = map[string]maps.Bits{
"network": maps.Bits(FeatureNetwork),
"network_inter_zone": maps.Bits(FeatureNetworkInterZone),
"application": maps.Bits(FeatureApplication),
"application_span": maps.Bits(FeatureSpan),
"application": maps.Bits(FeatureApplicationRED),
"application_span": maps.Bits(FeatureSpanLegacy),
"application_span_otel": maps.Bits(FeatureSpanOTel),
"application_span_sizes": maps.Bits(FeatureSpanSizes),
"application_service_graph": maps.Bits(FeatureGraph),
Expand All @@ -49,11 +49,11 @@ func LoadFeatures(features []string) Features {
return Features(maps.MappedBits(features, featureMapper))
}

func (f Features) Has(feature Features) bool {
func (f Features) has(feature Features) bool {
return maps.Bits(f).Has(maps.Bits(feature))
}

func (f Features) Any(feature Features) bool {
func (f Features) any(feature Features) bool {
return maps.Bits(f).Any(maps.Bits(feature))
}

Expand All @@ -77,3 +77,71 @@ func (f *Features) UnmarshalText(text []byte) error {
*f = LoadFeatures(strings.Split(string(text), ","))
return nil
}

func (f Features) AnyAppO11yMetric() bool {
return f.any(
FeatureApplicationRED |
FeatureSpanLegacy |
FeatureSpanOTel |
FeatureSpanSizes |
FeatureGraph |
FeatureProcess |
FeatureApplicationHost)
}

func (f Features) SpanMetrics() bool {
return f.any(FeatureSpanLegacy | FeatureSpanOTel)
}

func (f Features) AnySpanMetrics() bool {
return f.any(FeatureSpanLegacy | FeatureSpanOTel | FeatureSpanSizes)
}

func (f Features) AnyNetwork() bool {
return f.any(FeatureNetwork | FeatureNetworkInterZone)
}

func (f Features) AppOrSpan() bool {
return f.any(FeatureApplicationRED |
FeatureSpanSizes |
FeatureApplicationHost |
FeatureSpanLegacy |
FeatureSpanOTel)
}

func (f Features) LegacySpanMetrics() bool {
return f.any(FeatureSpanLegacy)
}

func (f Features) ServiceGraph() bool {
return f.any(FeatureGraph)
}

func (f Features) AppHost() bool {
return f.any(FeatureApplicationHost)
}

func (f Features) AppRED() bool {
return f.any(FeatureApplicationRED)
}

func (f Features) SpanSizes() bool {
return f.any(FeatureSpanSizes)
}

func (f Features) NetworkBytes() bool {
return f.any(FeatureNetwork)
}

func (f Features) NetworkInterZone() bool {
return f.any(FeatureNetworkInterZone)
}

func (f Features) BPF() bool {
return f.any(FeatureEBPF)
}

// InvalidSpanMetricsConfig is used to make sure that you can't define both legacy and OTEL span metrics at the same time
func (f Features) InvalidSpanMetricsConfig() bool {
return f.has(FeatureSpanLegacy | FeatureSpanOTel)
}
Loading
Loading