diff --git a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsAppSignalsCustomizerProvider.java b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsAppSignalsCustomizerProvider.java index 97d0697772..aa6c993506 100644 --- a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsAppSignalsCustomizerProvider.java +++ b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsAppSignalsCustomizerProvider.java @@ -18,10 +18,13 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.contrib.awsxray.AlwaysRecordSampler; import io.opentelemetry.contrib.awsxray.ResourceHolder; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProvider; @@ -63,13 +66,13 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) { autoConfiguration.addSpanExporterCustomizer(this::customizeSpanExporter); } - private boolean isSmpEnabled(ConfigProperties configProps) { + private boolean isAppSignalsEnabled(ConfigProperties configProps) { return configProps.getBoolean( "otel.aws.app.signals.enabled", configProps.getBoolean("otel.smp.enabled", false)); } private Sampler customizeSampler(Sampler sampler, ConfigProperties configProps) { - if (isSmpEnabled(configProps)) { + if (isAppSignalsEnabled(configProps)) { return AlwaysRecordSampler.create(sampler); } return sampler; @@ -77,16 +80,12 @@ private Sampler customizeSampler(Sampler sampler, ConfigProperties configProps) private SdkTracerProviderBuilder customizeTracerProviderBuilder( SdkTracerProviderBuilder tracerProviderBuilder, ConfigProperties configProps) { - if (isSmpEnabled(configProps)) { - logger.info("Span Metrics Processor enabled"); - String smpEndpoint = - configProps.getString( - "otel.aws.app.signals.exporter.endpoint", - configProps.getString("otel.aws.smp.exporter.endpoint", "http://localhost:4315")); + if (isAppSignalsEnabled(configProps)) { + logger.info("AWS AppSignals enabled"); Duration exportInterval = configProps.getDuration("otel.metric.export.interval", DEFAULT_METRIC_EXPORT_INTERVAL); - logger.log(Level.FINE, String.format("Span Metrics endpoint: %s", smpEndpoint)); - logger.log(Level.FINE, String.format("Span Metrics export interval: %s", exportInterval)); + logger.log( + Level.FINE, String.format("AppSignals Metrics export interval: %s", exportInterval)); // Cap export interval to 60 seconds. This is currently required for metrics-trace correlation // to work correctly. if (exportInterval.compareTo(DEFAULT_METRIC_EXPORT_INTERVAL) > 0) { @@ -100,17 +99,8 @@ private SdkTracerProviderBuilder customizeTracerProviderBuilder( AttributePropagatingSpanProcessorBuilder.create().build()); // Construct meterProvider MetricExporter metricsExporter = - OtlpGrpcMetricExporter.builder() - .setEndpoint(smpEndpoint) - .setDefaultAggregationSelector( - instrumentType -> { - if (instrumentType == InstrumentType.HISTOGRAM) { - return Aggregation.base2ExponentialBucketHistogram(); - } - return Aggregation.defaultAggregation(); - }) - .setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred()) - .build(); + AppSignalsExporterProvider.INSTANCE.createExporter(configProps); + MetricReader metricReader = PeriodicMetricReader.builder(metricsExporter).setInterval(exportInterval).build(); @@ -119,7 +109,7 @@ private SdkTracerProviderBuilder customizeTracerProviderBuilder( .setResource(ResourceHolder.getResource()) .registerMetricReader(metricReader) .build(); - // Construct and set span metrics processor + // Construct and set AppSignals metrics processor SpanProcessor spanMetricsProcessor = AwsSpanMetricsProcessorBuilder.create(meterProvider, ResourceHolder.getResource()) .build(); @@ -130,7 +120,7 @@ private SdkTracerProviderBuilder customizeTracerProviderBuilder( private SpanExporter customizeSpanExporter( SpanExporter spanExporter, ConfigProperties configProps) { - if (isSmpEnabled(configProps)) { + if (isAppSignalsEnabled(configProps)) { return AwsMetricAttributesSpanExporterBuilder.create( spanExporter, ResourceHolder.getResource()) .build(); @@ -138,4 +128,42 @@ private SpanExporter customizeSpanExporter( return spanExporter; } + + private enum AppSignalsExporterProvider { + INSTANCE; + + public MetricExporter createExporter(ConfigProperties configProps) { + String protocol = + OtlpConfigUtil.getOtlpProtocol(OtlpConfigUtil.DATA_TYPE_METRICS, configProps); + logger.log(Level.FINE, String.format("AppSignals export protocol: %s", protocol)); + + String appSignalsEndpoint = + configProps.getString( + "otel.aws.app.signals.exporter.endpoint", + configProps.getString("otel.aws.smp.exporter.endpoint", "http://localhost:4315")); + logger.log(Level.FINE, String.format("AppSignals export endpoint: %s", appSignalsEndpoint)); + + if (protocol.equals(OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF)) { + return OtlpHttpMetricExporter.builder() + .setEndpoint(appSignalsEndpoint) + .setDefaultAggregationSelector(this::getAggregation) + .setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred()) + .build(); + } else if (protocol.equals(OtlpConfigUtil.PROTOCOL_GRPC)) { + return OtlpGrpcMetricExporter.builder() + .setEndpoint(appSignalsEndpoint) + .setDefaultAggregationSelector(this::getAggregation) + .setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred()) + .build(); + } + throw new ConfigurationException("Unsupported AppSignals export protocol: " + protocol); + } + + private Aggregation getAggregation(InstrumentType instrumentType) { + if (instrumentType == InstrumentType.HISTOGRAM) { + return Aggregation.base2ExponentialBucketHistogram(); + } + return Aggregation.defaultAggregation(); + } + } }