2
2
# SPDX-License-Identifier: Apache-2.0
3
3
import os
4
4
from logging import Logger , getLogger
5
- from typing import Dict , Type
5
+ from typing import ClassVar , Dict , Type
6
6
7
7
from typing_extensions import override
8
8
15
15
)
16
16
from amazon .opentelemetry .distro .aws_span_metrics_processor_builder import AwsSpanMetricsProcessorBuilder
17
17
from amazon .opentelemetry .distro .sampler .aws_xray_remote_sampler import AwsXRayRemoteSampler
18
- from opentelemetry .exporter .otlp .proto .grpc .metric_exporter import OTLPMetricExporter
18
+ from opentelemetry .exporter .otlp .proto .grpc .metric_exporter import OTLPMetricExporter as OTLPGrpcOTLPMetricExporter
19
+ from opentelemetry .exporter .otlp .proto .http .metric_exporter import OTLPMetricExporter as OTLPHttpOTLPMetricExporter
19
20
from opentelemetry .sdk ._configuration import (
20
21
_get_exporter_names ,
21
22
_get_id_generator ,
29
30
)
30
31
from opentelemetry .sdk .environment_variables import (
31
32
_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED ,
33
+ OTEL_EXPORTER_OTLP_METRICS_PROTOCOL ,
34
+ OTEL_EXPORTER_OTLP_PROTOCOL ,
32
35
OTEL_TRACES_SAMPLER_ARG ,
33
36
)
34
37
from opentelemetry .sdk .extension .aws .resource .ec2 import AwsEc2ResourceDetector
55
58
OTEL_AWS_APP_SIGNALS_ENABLED = "OTEL_AWS_APP_SIGNALS_ENABLED"
56
59
OTEL_METRIC_EXPORT_INTERVAL = "OTEL_METRIC_EXPORT_INTERVAL"
57
60
OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT = "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT"
61
+ OTEL_AWS_SMP_EXPORTER_ENDPOINT = "OTEL_AWS_SMP_EXPORTER_ENDPOINT"
58
62
DEFAULT_METRIC_EXPORT_INTERVAL = 60000.0
59
63
60
64
_logger : Logger = getLogger (__name__ )
@@ -172,41 +176,28 @@ def _custom_import_sampler(sampler_name: str, resource: Resource) -> Sampler:
172
176
173
177
174
178
def _customize_sampler (sampler : Sampler ) -> Sampler :
175
- if not is_smp_enabled ():
179
+ if not is_app_signals_enabled ():
176
180
return sampler
177
181
return AlwaysRecordSampler (sampler )
178
182
179
183
180
184
def _customize_exporter (span_exporter : SpanExporter , resource : Resource ) -> SpanExporter :
181
- if not is_smp_enabled ():
185
+ if not is_app_signals_enabled ():
182
186
return span_exporter
183
187
return AwsMetricAttributesSpanExporterBuilder (span_exporter , resource ).build ()
184
188
185
189
186
190
def _customize_span_processors (provider : TracerProvider , resource : Resource ) -> None :
187
- if not is_smp_enabled ():
191
+ if not is_app_signals_enabled ():
188
192
return
189
193
190
194
# Construct and set local and remote attributes span processor
191
195
provider .add_span_processor (AttributePropagatingSpanProcessorBuilder ().build ())
192
196
193
197
# Construct meterProvider
194
- temporality_dict : Dict [type , AggregationTemporality ] = {}
195
- for typ in [
196
- Counter ,
197
- UpDownCounter ,
198
- ObservableCounter ,
199
- ObservableCounter ,
200
- ObservableUpDownCounter ,
201
- ObservableGauge ,
202
- Histogram ,
203
- ]:
204
- temporality_dict [typ ] = AggregationTemporality .DELTA
205
- _logger .info ("Span Metrics Processor enabled" )
206
- smp_endpoint = os .environ .get (OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT , "http://localhost:4315" )
207
- otel_metric_exporter = OTLPMetricExporter (endpoint = smp_endpoint , preferred_temporality = temporality_dict )
198
+ _logger .info ("AWS AppSignals enabled" )
199
+ otel_metric_exporter = AppSignalsExporterProvider ().create_exporter ()
208
200
export_interval_millis = float (os .environ .get (OTEL_METRIC_EXPORT_INTERVAL , DEFAULT_METRIC_EXPORT_INTERVAL ))
209
- _logger .debug ("Span Metrics endpoint: %s" , smp_endpoint )
210
201
_logger .debug ("Span Metrics export interval: %s" , export_interval_millis )
211
202
# Cap export interval to 60 seconds. This is currently required for metrics-trace correlation to work correctly.
212
203
if export_interval_millis > DEFAULT_METRIC_EXPORT_INTERVAL :
@@ -216,11 +207,53 @@ def _customize_span_processors(provider: TracerProvider, resource: Resource) ->
216
207
exporter = otel_metric_exporter , export_interval_millis = export_interval_millis
217
208
)
218
209
meter_provider : MeterProvider = MeterProvider (resource = resource , metric_readers = [periodic_exporting_metric_reader ])
219
- # Construct and set span metrics processor
210
+ # Construct and set AppSignals metrics processor
220
211
provider .add_span_processor (AwsSpanMetricsProcessorBuilder (meter_provider , resource ).build ())
221
212
222
213
return
223
214
224
215
225
- def is_smp_enabled ():
216
+ def is_app_signals_enabled ():
226
217
return os .environ .get (OTEL_AWS_APP_SIGNALS_ENABLED , False )
218
+
219
+
220
+ class AppSignalsExporterProvider :
221
+ _instance : ClassVar ["AppSignalsExporterProvider" ] = None
222
+
223
+ def __new__ (cls , * args , ** kwargs ):
224
+ if cls ._instance is None :
225
+ cls ._instance = super ().__new__ (cls )
226
+ return cls ._instance
227
+
228
+ # pylint: disable=no-self-use
229
+ def create_exporter (self ):
230
+ protocol = os .environ .get (
231
+ OTEL_EXPORTER_OTLP_METRICS_PROTOCOL , os .environ .get (OTEL_EXPORTER_OTLP_PROTOCOL , "grpc" )
232
+ )
233
+ _logger .debug ("AppSignals export protocol: %s" , protocol )
234
+
235
+ app_signals_endpoint = os .environ .get (
236
+ OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT ,
237
+ os .environ .get (OTEL_AWS_SMP_EXPORTER_ENDPOINT , "http://localhost:4315" ),
238
+ )
239
+
240
+ _logger .debug ("AppSignals export endpoint: %s" , app_signals_endpoint )
241
+
242
+ temporality_dict : Dict [type , AggregationTemporality ] = {}
243
+ for typ in [
244
+ Counter ,
245
+ UpDownCounter ,
246
+ ObservableCounter ,
247
+ ObservableCounter ,
248
+ ObservableUpDownCounter ,
249
+ ObservableGauge ,
250
+ Histogram ,
251
+ ]:
252
+ temporality_dict [typ ] = AggregationTemporality .DELTA
253
+
254
+ if protocol == "http/protobuf" :
255
+ return OTLPHttpOTLPMetricExporter (endpoint = app_signals_endpoint , preferred_temporality = temporality_dict )
256
+ if protocol == "grpc" :
257
+ return OTLPGrpcOTLPMetricExporter (endpoint = app_signals_endpoint , preferred_temporality = temporality_dict )
258
+
259
+ raise RuntimeError (f"Unsupported AppSignals export protocol: { protocol } " )
0 commit comments