3
3
# Modifications Copyright The OpenTelemetry Authors. Licensed under the Apache License 2.0 License.
4
4
import os
5
5
from logging import Logger , getLogger
6
- from typing import ClassVar , Dict , Type
6
+ from typing import ClassVar , Dict , List , Type , Union
7
7
8
8
from importlib_metadata import version
9
9
from typing_extensions import override
10
10
11
+ from amazon .opentelemetry .distro ._aws_attribute_keys import AWS_LOCAL_SERVICE
12
+ from amazon .opentelemetry .distro ._aws_resource_attribute_configurator import get_service_attribute
11
13
from amazon .opentelemetry .distro .always_record_sampler import AlwaysRecordSampler
12
14
from amazon .opentelemetry .distro .attribute_propagating_span_processor_builder import (
13
15
AttributePropagatingSpanProcessorBuilder ,
19
21
from amazon .opentelemetry .distro .aws_span_metrics_processor_builder import AwsSpanMetricsProcessorBuilder
20
22
from amazon .opentelemetry .distro .otlp_udp_exporter import OTLPUdpMetricExporter , OTLPUdpSpanExporter
21
23
from amazon .opentelemetry .distro .sampler .aws_xray_remote_sampler import AwsXRayRemoteSampler
24
+ from amazon .opentelemetry .distro .scope_based_exporter import ScopeBasedPeriodicExportingMetricReader
22
25
from opentelemetry .exporter .otlp .proto .http .metric_exporter import OTLPMetricExporter as OTLPHttpOTLPMetricExporter
26
+ from opentelemetry .metrics import set_meter_provider
23
27
from opentelemetry .sdk ._configuration import (
24
28
_get_exporter_names ,
25
29
_get_id_generator ,
28
32
_import_id_generator ,
29
33
_import_sampler ,
30
34
_init_logging ,
31
- _init_metrics ,
32
35
_OTelSDKConfigurator ,
33
36
)
34
37
from opentelemetry .sdk .environment_variables import (
49
52
ObservableUpDownCounter ,
50
53
UpDownCounter ,
51
54
)
52
- from opentelemetry .sdk .metrics .export import AggregationTemporality , PeriodicExportingMetricReader
55
+ from opentelemetry .sdk .metrics .export import (
56
+ AggregationTemporality ,
57
+ MetricExporter ,
58
+ MetricReader ,
59
+ PeriodicExportingMetricReader ,
60
+ )
61
+ from opentelemetry .sdk .metrics .view import DefaultAggregation , DropAggregation , View
53
62
from opentelemetry .sdk .resources import Resource , get_aggregated_resources
54
63
from opentelemetry .sdk .trace import TracerProvider
55
64
from opentelemetry .sdk .trace .export import BatchSpanProcessor , SpanExporter
58
67
from opentelemetry .semconv .resource import ResourceAttributes
59
68
from opentelemetry .trace import set_tracer_provider
60
69
61
- APP_SIGNALS_ENABLED_CONFIG = "OTEL_AWS_APP_SIGNALS_ENABLED"
70
+ DEPRECATED_APP_SIGNALS_ENABLED_CONFIG = "OTEL_AWS_APP_SIGNALS_ENABLED"
62
71
APPLICATION_SIGNALS_ENABLED_CONFIG = "OTEL_AWS_APPLICATION_SIGNALS_ENABLED"
63
- APP_SIGNALS_EXPORTER_ENDPOINT_CONFIG = "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT"
72
+ APPLICATION_SIGNALS_RUNTIME_ENABLED_CONFIG = "OTEL_AWS_APPLICATION_SIGNALS_RUNTIME_ENABLED"
73
+ DEPRECATED_APP_SIGNALS_EXPORTER_ENDPOINT_CONFIG = "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT"
64
74
APPLICATION_SIGNALS_EXPORTER_ENDPOINT_CONFIG = "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT"
65
75
METRIC_EXPORT_INTERVAL_CONFIG = "OTEL_METRIC_EXPORT_INTERVAL"
66
76
DEFAULT_METRIC_EXPORT_INTERVAL = 60000.0
@@ -112,13 +122,16 @@ def _initialize_components():
112
122
113
123
auto_resource : Dict [str , any ] = {}
114
124
auto_resource = _customize_versions (auto_resource )
115
- resource = get_aggregated_resources (
116
- [
117
- AwsEc2ResourceDetector (),
118
- AwsEksResourceDetector (),
119
- AwsEcsResourceDetector (),
120
- ]
121
- ).merge (Resource .create (auto_resource ))
125
+ # auto_resource = _set_aws_attributes(auto_resource)
126
+ resource = _customize_resource (
127
+ get_aggregated_resources (
128
+ [
129
+ AwsEc2ResourceDetector (),
130
+ AwsEksResourceDetector (),
131
+ AwsEcsResourceDetector (),
132
+ ]
133
+ ).merge (Resource .create (auto_resource ))
134
+ )
122
135
123
136
sampler_name = _get_sampler ()
124
137
sampler = _custom_import_sampler (sampler_name , resource )
@@ -160,6 +173,27 @@ def _init_tracing(
160
173
set_tracer_provider (trace_provider )
161
174
162
175
176
+ def _init_metrics (
177
+ exporters_or_readers : Dict [str , Union [Type [MetricExporter ], Type [MetricReader ]]],
178
+ resource : Resource = None ,
179
+ ):
180
+ metric_readers = []
181
+ views = []
182
+
183
+ for _ , exporter_or_reader_class in exporters_or_readers .items ():
184
+ exporter_args = {}
185
+
186
+ if issubclass (exporter_or_reader_class , MetricReader ):
187
+ metric_readers .append (exporter_or_reader_class (** exporter_args ))
188
+ else :
189
+ metric_readers .append (PeriodicExportingMetricReader (exporter_or_reader_class (** exporter_args )))
190
+
191
+ _customize_metric_exporters (metric_readers , views )
192
+
193
+ provider = MeterProvider (resource = resource , metric_readers = metric_readers , views = views )
194
+ set_meter_provider (provider )
195
+
196
+
163
197
# END The OpenTelemetry Authors code
164
198
165
199
@@ -283,14 +317,9 @@ def _customize_span_processors(provider: TracerProvider, resource: Resource) ->
283
317
# Construct meterProvider
284
318
_logger .info ("AWS Application Signals enabled" )
285
319
otel_metric_exporter = ApplicationSignalsExporterProvider ().create_exporter ()
286
- export_interval_millis = float (os .environ .get (METRIC_EXPORT_INTERVAL_CONFIG , DEFAULT_METRIC_EXPORT_INTERVAL ))
287
- _logger .debug ("Span Metrics export interval: %s" , export_interval_millis )
288
- # Cap export interval to 60 seconds. This is currently required for metrics-trace correlation to work correctly.
289
- if export_interval_millis > DEFAULT_METRIC_EXPORT_INTERVAL :
290
- export_interval_millis = DEFAULT_METRIC_EXPORT_INTERVAL
291
- _logger .info ("AWS Application Signals metrics export interval capped to %s" , export_interval_millis )
320
+
292
321
periodic_exporting_metric_reader = PeriodicExportingMetricReader (
293
- exporter = otel_metric_exporter , export_interval_millis = export_interval_millis
322
+ exporter = otel_metric_exporter , export_interval_millis = _get_metric_export_interval ()
294
323
)
295
324
meter_provider : MeterProvider = MeterProvider (resource = resource , metric_readers = [periodic_exporting_metric_reader ])
296
325
# Construct and set application signals metrics processor
@@ -299,25 +328,68 @@ def _customize_span_processors(provider: TracerProvider, resource: Resource) ->
299
328
return
300
329
301
330
331
+ def _customize_metric_exporters (metric_readers : List [MetricReader ], views : List [View ]) -> None :
332
+ if _is_application_signals_runtime_enabled ():
333
+ system_metrics_scope_name = "opentelemetry.instrumentation.system_metrics"
334
+ if 0 == len (metric_readers ):
335
+ _logger .info ("Registered scope %s" , system_metrics_scope_name )
336
+ views .append (View (meter_name = system_metrics_scope_name , aggregation = DefaultAggregation ()))
337
+ views .append (View (instrument_name = "*" , aggregation = DropAggregation ()))
338
+
339
+ otel_metric_exporter = ApplicationSignalsExporterProvider ().create_exporter ()
340
+ scope_based_periodic_exporting_metric_reader = ScopeBasedPeriodicExportingMetricReader (
341
+ exporter = otel_metric_exporter ,
342
+ export_interval_millis = _get_metric_export_interval (),
343
+ registered_scope_names = {system_metrics_scope_name },
344
+ )
345
+ metric_readers .append (scope_based_periodic_exporting_metric_reader )
346
+
347
+
302
348
def _customize_versions (auto_resource : Dict [str , any ]) -> Dict [str , any ]:
303
349
distro_version = version ("aws-opentelemetry-distro" )
304
350
auto_resource [ResourceAttributes .TELEMETRY_AUTO_VERSION ] = distro_version + "-aws"
305
351
_logger .debug ("aws-opentelementry-distro - version: %s" , auto_resource [ResourceAttributes .TELEMETRY_AUTO_VERSION ])
306
352
return auto_resource
307
353
308
354
355
+ def _customize_resource (resource : Resource ) -> Resource :
356
+ service_name , is_unknown = get_service_attribute (resource )
357
+ if is_unknown :
358
+ _logger .debug ("No valid service name found" )
359
+
360
+ return resource .merge (Resource .create ({AWS_LOCAL_SERVICE : service_name }))
361
+
362
+
309
363
def _is_application_signals_enabled ():
310
364
return (
311
- os .environ .get (APPLICATION_SIGNALS_ENABLED_CONFIG , os .environ .get (APP_SIGNALS_ENABLED_CONFIG , "false" )).lower ()
365
+ os .environ .get (
366
+ APPLICATION_SIGNALS_ENABLED_CONFIG , os .environ .get (DEPRECATED_APP_SIGNALS_ENABLED_CONFIG , "false" )
367
+ ).lower ()
312
368
== "true"
313
369
)
314
370
315
371
372
+ def _is_application_signals_runtime_enabled ():
373
+ return _is_application_signals_enabled () and (
374
+ os .environ .get (APPLICATION_SIGNALS_RUNTIME_ENABLED_CONFIG , "true" ).lower () == "true"
375
+ )
376
+
377
+
316
378
def _is_lambda_environment ():
317
379
# detect if running in AWS Lambda environment
318
380
return AWS_LAMBDA_FUNCTION_NAME_CONFIG in os .environ
319
381
320
382
383
+ def _get_metric_export_interval ():
384
+ export_interval_millis = float (os .environ .get (METRIC_EXPORT_INTERVAL_CONFIG , DEFAULT_METRIC_EXPORT_INTERVAL ))
385
+ _logger .debug ("Span Metrics export interval: %s" , export_interval_millis )
386
+ # Cap export interval to 60 seconds. This is currently required for metrics-trace correlation to work correctly.
387
+ if export_interval_millis > DEFAULT_METRIC_EXPORT_INTERVAL :
388
+ export_interval_millis = DEFAULT_METRIC_EXPORT_INTERVAL
389
+ _logger .info ("AWS Application Signals metrics export interval capped to %s" , export_interval_millis )
390
+ return export_interval_millis
391
+
392
+
321
393
class ApplicationSignalsExporterProvider :
322
394
_instance : ClassVar ["ApplicationSignalsExporterProvider" ] = None
323
395
@@ -353,7 +425,7 @@ def create_exporter(self):
353
425
if protocol == "http/protobuf" :
354
426
application_signals_endpoint = os .environ .get (
355
427
APPLICATION_SIGNALS_EXPORTER_ENDPOINT_CONFIG ,
356
- os .environ .get (APP_SIGNALS_EXPORTER_ENDPOINT_CONFIG , "http://localhost:4316/v1/metrics" ),
428
+ os .environ .get (DEPRECATED_APP_SIGNALS_EXPORTER_ENDPOINT_CONFIG , "http://localhost:4316/v1/metrics" ),
357
429
)
358
430
_logger .debug ("AWS Application Signals export endpoint: %s" , application_signals_endpoint )
359
431
return OTLPHttpOTLPMetricExporter (
@@ -369,7 +441,7 @@ def create_exporter(self):
369
441
370
442
application_signals_endpoint = os .environ .get (
371
443
APPLICATION_SIGNALS_EXPORTER_ENDPOINT_CONFIG ,
372
- os .environ .get (APP_SIGNALS_EXPORTER_ENDPOINT_CONFIG , "localhost:4315" ),
444
+ os .environ .get (DEPRECATED_APP_SIGNALS_EXPORTER_ENDPOINT_CONFIG , "localhost:4315" ),
373
445
)
374
446
_logger .debug ("AWS Application Signals export endpoint: %s" , application_signals_endpoint )
375
447
return OTLPGrpcOTLPMetricExporter (
0 commit comments