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 new Sampler and SpanProcessor to allow for generating metrics from 100% of spans without impacting sampling #789

Closed
thpierce opened this issue Mar 16, 2023 · 4 comments

Comments

@thpierce
Copy link
Contributor

thpierce commented Mar 16, 2023

Is your feature request related to a problem? Please describe.
Yes. We wish to generate key metrics from OTEL auto-instrumented spans. I had previously engaged the community to discuss this, and after some conversations, decided that the best approach would be to implement a Sampler and a Span Processor to the contrib repositories.

The major requirements for our project are as follows:

  • Metrics should be produced from 100% of Client/Server/Producer/Consumer spans produced by OTEL Auto-Instrumentation, regardless of sampling decision
    • Span sampling decisions should still be respected w.r.t. exporting spans to the collector and propagating sampling decisions to child spans
  • Metric generation must be done when the span is ended, as metric attributes are derived from some span attributes that are not always available when the span is started (e.g. http.route).
  • Metric attributes need to be added to the span attributes before export to Collector, to be used to correlate metrics and spans in a downstream process.

I am raising this issue to garner attention for this change before I raise a PR, and perhaps run conversations in parallel with implementation, which is ongoing. Please note there may be some differences in the final implementation, but the broad strokes should remain the same.

Describe the solution you'd like

All contributions would go to opentelemetry-java-contrib/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray.

  • First, a new Sampler, tentatively called AlwaysRecordSampler.
    • This is an aggregate Sampler that is initialized with a root Sampler (akin to ParentBasedSampler).
    • shouldSample() will call the root sampler and, if the SampleDecision is RECORD_AND_SAMPLE or RECORD_ONLY, it simply returns the result. However, if the SampleDecision is DROP, it will instead create a new result with SampleDecision set to RECORD_ONLY (all other result behaviour unchanged).
    • This Sampler will ensure that 100% of spans get send to the SpanProcessor, without changing the actual Sampling rate/behaviour.
  • Second, a new SpanProcessor, tentatively called AwsSpanMetricsProcessor.
    • This SpanProcessor is initialized with a MeterProvider and a downstream SpanProcessor (akin to the MultiSpanProcessor)
    • All APIs but onEnd() and isEndRequired() will passthrough to the downstream SpanProcessor, as needed.
    • isEndRequired will return true, and onEnd() will:
      • Determine attributes for metrics
      • Emit metrics with attributes
      • If the span is marked for Sampling,
        • Replace span with a new ReadableSpan identical to the original span, but with metric attributes embedded into span attributes.
      • Call downstreamSpanProcessor.onEnd() with span, if required.
    • This SpanProcessor will create desired metrics and embed attributes into processed spans before sending them to the downstream SpanProcessor (for additional processing/export).

Describe alternatives you've considered

We have evaluated a couple different options here:

  • Always exporting spans, regardless of sample decision, implementing a collector SpanProcessor to emit metrics, then drop anything not marked as Sampled. We felt this did not align well with the OTEL specification & would result in heavy traffic to the collector, as well as introduce backwards incompatibility risks for the customer
  • Implement the SpanProcessor as a SpanExporter. The trouble here is that SpanExporters are not supposed to receive RECORD_ONLY spans, and no default SpanProcessor offers that functionality, so we would end up having to write a SpanProcessor anyways. No major value was seen in this approach.

Additional context

@willarmiros
Copy link
Contributor

+1, I support this component's implementation in the X-ray contrib.

@thpierce
Copy link
Contributor Author

thpierce commented Mar 22, 2023

One thing we are evaluating is: where exactly should these components go? We originally thought they would live in aws-xray, but AlwaysRecordSampler is fairly generic - is there a better package that they could fall under? Happy to take guidance here.

thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Mar 29, 2023
ResourceHolder provides generic utility for other components in the awsxray package, and could be more broadly used. In this commit, we are breaking out the ResourceHolder inner class to it's own class, and exposing the functionality of getResource, so that other classes can rely on it.

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Mar 29, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* SpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics, and wraps these metric attributes around the span attributes before passing the span to a delegate span processor for further processing/exporting.
* MetricAttributeGenerator - A generic interface for components that consume spans and resources and export attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* SpanMetricsProcessorBuilder - A builder class for SpanMetricsProcessor

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Mar 29, 2023
ResourceHolder provides generic utility for other components in the awsxray package, and could be more broadly used. In this commit, we are breaking out the ResourceHolder inner class to it's own class, and exposing the functionality of getResource, so that other classes can rely on it.

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Mar 30, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* SpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics, and wraps these metric attributes around the span attributes before passing the span to a delegate span processor for further processing/exporting.
* MetricAttributeGenerator - A generic interface for components that consume spans and resources and export attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* SpanMetricsProcessorBuilder - A builder class for SpanMetricsProcessor

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Apr 3, 2023
ResourceHolder provides generic utility for other components in the awsxray package, and could be more broadly used. In this commit, we are breaking out the ResourceHolder inner class to it's own class, and exposing the functionality of getResource, so that other classes can rely on it. Further, we are deprecating the original ResourceHolder, which we believe was not originally intended to be widely visible/accessible.

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Apr 3, 2023
ResourceHolder provides generic utility for other components in the awsxray package, and could be more broadly used. In this commit, we are breaking out the ResourceHolder inner class to it's own class, and exposing the functionality of getResource, so that other classes can rely on it. Further, we are deprecating the original ResourceHolder, which we believe was not originally intended to be widely visible/accessible.

Related issue: open-telemetry#789
trask pushed a commit that referenced this issue Apr 3, 2023
**Description:**

ResourceHolder provides generic utility for other components in the
awsxray package, and could be more broadly used. In this commit, we are
breaking out the ResourceHolder inner class to it's own class, and
exposing the functionality of getResource, so that other classes can
rely on it.

Specifically, we are working on new components to meet the needs of
#789,
which will require the use of this ResourceHolder. Opening up
ResourceHolder seems to us to be the best path forward.

**Existing Issue(s):**

Tangentially related:
#789

**Testing:**

* Added unit tests, validated they all pass
* `./gradlew clean assemble` succeeds

**Documentation:**

Unclear if any documentation is required here, can help contribute this
as needed. ResourceHolder is a new independent component that can be
used to retrieve the Resource from autoconfiguration.

**Outstanding items:**

None
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Apr 27, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* SpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics, and wraps these metric attributes around the span attributes before passing the span to a delegate span processor for further processing/exporting.
* MetricAttributeGenerator - A generic interface for components that consume spans and resources and export attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* SpanMetricsProcessorBuilder - A builder class for SpanMetricsProcessor

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Apr 28, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* AwsSpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics, and wraps these metric attributes around the span attributes before passing the span to a delegate span processor for further processing/exporting.
* MetricAttributeGenerator - A generic interface for components that consume spans and resources and export attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* AwsSpanMetricsProcessorBuilder - A builder class for SpanMetricsProcessor

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue Apr 28, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* AwsSpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics, and wraps these metric attributes around the span attributes before passing the span to a delegate span processor for further processing/exporting.
* MetricAttributeGenerator - A generic interface for components that consume spans and resources and export attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* AwsSpanMetricsProcessorBuilder - A builder class for AwsSpanMetricsProcessor

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue May 9, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* AwsSpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics.
* AwsMetricAttributesSpanExporter - A span exporter that relies on MetricAttributeGenerator to wraps metric attributes around the span attributes before passing the span to a delegate span exporter for export.
* MetricAttributeGenerator - A generic interface for components that consumes spans and resources and produces attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* AwsSpanMetricsProcessorBuilder - A builder class for AwsSpanMetricsProcessor.
* AwsMetricAttributesSpanExporterBuilder - A builder class for AwsMetricAttributesSpanExporter.

Related issue: open-telemetry#789
thpierce added a commit to bjrara/opentelemetry-java-contrib that referenced this issue May 9, 2023
… without impacting sampling

In this commit, we are adding several new components to the awsxray package:
* AlwaysRecordSampler - A simple aggregate sampler that always ensures spans are "recorded" (i.e. sent to span processors). This allows us to generate metrics from 100% of spans without impacting true sampling rate.
* AwsSpanMetricsProcessor - A span processor that will generate specific metrics pertaining to latency, faults, and errors. Relies on a MetricAttributeGenerator to build attributes for the metrics.
* AwsMetricAttributesSpanExporter - A span exporter that relies on MetricAttributeGenerator to wraps metric attributes around the span attributes before passing the span to a delegate span exporter for export.
* MetricAttributeGenerator - A generic interface for components that consumes spans and resources and produces attributes for metrics generated from these spans.
* AwsMetricAttributeGenerator - A specific implementation of MetricAttributeGenerator, used for generating AWS-specific attributes.
* AwsSpanMetricsProcessorBuilder - A builder class for AwsSpanMetricsProcessor.
* AwsMetricAttributesSpanExporterBuilder - A builder class for AwsMetricAttributesSpanExporter.

Related issue: open-telemetry#789
@trask
Copy link
Member

trask commented May 23, 2023

@thpierce is this issue closed by #802?

@thpierce
Copy link
Contributor Author

Yes! Resolving now, ty for help getting these merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants