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