Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions azure_monitor/src/azure_monitor/auto_collection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@


class AutoCollection:
"""Starts auto collection of standard metrics, including performance,
dependency and request metrics.

Args:
meter: OpenTelemetry Meter
label_set: OpenTelemetry label set
"""

def __init__(self, meter: Meter, label_set: LabelSet):
self._performance_metrics = PerformanceMetrics(meter, label_set)
self._dependency_metrics = DependencyMetrics(meter, label_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ def dependency_patch(*args, **kwargs) -> None:


class DependencyMetrics:
"""Starts auto collection of dependency metrics, including
"Outgoing Requests per second" metric.

Args:
meter: OpenTelemetry Meter
label_set: OpenTelemetry label set
"""

def __init__(self, meter: Meter, label_set: LabelSet):
self._meter = meter
self._label_set = label_set
Expand All @@ -39,8 +47,8 @@ def _track_dependency_rate(self, observer) -> None:
""" Track Dependency rate

Calculated by obtaining the number of outgoing requests made
using the requests library within an elapsed time and dividing that
value over the elapsed time.
using the requests library within an elapsed time and dividing
that value over the elapsed time.
"""
current_count = dependency_map.get("count", 0)
current_time = time.time()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@


class PerformanceMetrics:
"""Starts auto collection of performance metrics, including
"Processor time as a percentage", "Amount of available memory
in bytes", "Process CPU usage as a percentage" and "Amount of
memory process has used in bytes" metrics.

Args:
meter: OpenTelemetry Meter
label_set: OpenTelemetry label set
"""

def __init__(self, meter: Meter, label_set: LabelSet):
self._meter = meter
self._label_set = label_set
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ def server_patch(*args, **kwargs):


class RequestMetrics:
"""Starts auto collection of request metrics, including
"Incoming Requests Average Execution Time" and
"Incoming Requests Average Execution Rate" metrics.

Args:
meter: OpenTelemetry Meter
label_set: OpenTelemetry label set
"""

def __init__(self, meter: Meter, label_set: LabelSet):
self._meter = meter
self._label_set = label_set
Expand Down
16 changes: 13 additions & 3 deletions azure_monitor/src/azure_monitor/export/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ class ExportResult(Enum):

# pylint: disable=broad-except
class BaseExporter:
"""Azure Monitor base exporter for OpenTelemetry.

Args:
options: :doc:`export.options` to allow configuration for the exporter
"""

def __init__(self, **options):
self._telemetry_processors = []
self.options = ExporterOptions(**options)
Expand All @@ -41,15 +47,17 @@ def add_telemetry_processor(

Telemetry processors will be called one by one before telemetry
item is pushed for sending and in the order they were added.
:param processor: The processor to add.

Args:
processor: Processor to add
"""
self._telemetry_processors.append(processor)

def clear_telemetry_processors(self) -> None:
"""Removes all telemetry processors"""
self._telemetry_processors = []

def apply_telemetry_processors(
def _apply_telemetry_processors(
self, envelopes: typing.List[Envelope]
) -> typing.List[Envelope]:
"""Applies all telemetry processors in the order they were added.
Expand All @@ -59,7 +67,9 @@ def apply_telemetry_processors(
throw exceptions and fail, but the applying of all telemetry processors
will proceed (not fast fail). Processors also return True if envelope
should be included for exporting, False otherwise.
:param envelopes: The envelopes to apply each processor to.

Args:
envelopes: The envelopes to apply each processor to.
"""
filtered_envelopes = []
for envelope in envelopes:
Expand Down
12 changes: 9 additions & 3 deletions azure_monitor/src/azure_monitor/export/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@


class AzureMonitorMetricsExporter(BaseExporter, MetricsExporter):
"""Azure Monitor metrics exporter for OpenTelemetry.

Args:
options: :doc:`export.options` to allow configuration for the exporter
"""

def export(
self, metric_records: Sequence[MetricRecord]
) -> MetricsExportResult:
envelopes = list(map(self.metric_to_envelope, metric_records))
envelopes = list(map(self._metric_to_envelope, metric_records))
envelopes = list(
map(
lambda x: x.to_dict(),
self.apply_telemetry_processors(envelopes),
self._apply_telemetry_processors(envelopes),
)
)
try:
Expand All @@ -48,7 +54,7 @@ def export(
logger.exception("Exception occurred while exporting the data.")
return get_metrics_export_result(ExportResult.FAILED_NOT_RETRYABLE)

def metric_to_envelope(
def _metric_to_envelope(
self, metric_record: MetricRecord
) -> protocol.Envelope:

Expand Down
12 changes: 9 additions & 3 deletions azure_monitor/src/azure_monitor/export/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@


class AzureMonitorSpanExporter(BaseExporter, SpanExporter):
"""Azure Monitor span exporter for OpenTelemetry.

Args:
options: :doc:`export.options` to allow configuration for the exporter
"""

def export(self, spans: Sequence[Span]) -> SpanExportResult:
envelopes = list(map(self.span_to_envelope, spans))
envelopes = list(map(self._span_to_envelope, spans))
envelopes = list(
map(
lambda x: x.to_dict(),
self.apply_telemetry_processors(envelopes),
self._apply_telemetry_processors(envelopes),
)
)
try:
Expand All @@ -43,7 +49,7 @@ def export(self, spans: Sequence[Span]) -> SpanExportResult:

# pylint: disable=too-many-statements
# pylint: disable=too-many-branches
def span_to_envelope(self, span: Span) -> protocol.Envelope:
def _span_to_envelope(self, span: Span) -> protocol.Envelope:
if not span:
return None
envelope = protocol.Envelope(
Expand Down
14 changes: 8 additions & 6 deletions azure_monitor/src/azure_monitor/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@ def __init__(
instrumentation_key: str = None,
storage_maintenance_period: int = 60,
storage_max_size: int = 100 * 1024 * 1024,
storage_path: str = os.path.join(
os.path.expanduser("~"),
".opentelemetry",
".azure",
os.path.basename(sys.argv[0]) or ".console",
),
storage_path: str = None,
storage_retention_period: int = 7 * 24 * 60 * 60,
timeout: int = 10.0, # networking timeout in seconds
) -> None:
if storage_path is None:
storage_path = os.path.join(
os.path.expanduser("~"),
".opentelemetry",
".azure",
os.path.basename(sys.argv[0]) or ".console",
)
self.connection_string = connection_string
self.instrumentation_key = instrumentation_key
self.storage_maintenance_period = storage_maintenance_period
Expand Down
8 changes: 4 additions & 4 deletions azure_monitor/tests/metrics/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def test_export_exception(self, logger_mock):

def test_metric_to_envelope_none(self):
exporter = AzureMonitorMetricsExporter()
self.assertIsNone(exporter.metric_to_envelope(None))
self.assertIsNone(exporter._metric_to_envelope(None))

def test_metric_to_envelope(self):
aggregator = CounterAggregator()
Expand All @@ -123,7 +123,7 @@ def test_metric_to_envelope(self):
aggregator, self._test_label_set, self._test_metric
)
exporter = AzureMonitorMetricsExporter()
envelope = exporter.metric_to_envelope(record)
envelope = exporter._metric_to_envelope(record)
self.assertIsInstance(envelope, Envelope)
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
Expand Down Expand Up @@ -163,7 +163,7 @@ def test_observer_to_envelope(self):
aggregator.take_checkpoint()
record = MetricRecord(aggregator, self._test_label_set, self._test_obs)
exporter = AzureMonitorMetricsExporter()
envelope = exporter.metric_to_envelope(record)
envelope = exporter._metric_to_envelope(record)
self.assertIsInstance(envelope, Envelope)
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
Expand Down Expand Up @@ -209,7 +209,7 @@ def test_measure_to_envelope(self, logger_mock):
aggregator, self._test_label_set, self._test_measure
)
exporter = AzureMonitorMetricsExporter()
envelope = exporter.metric_to_envelope(record)
envelope = exporter._metric_to_envelope(record)
self.assertIsInstance(envelope, Envelope)
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
Expand Down
8 changes: 4 additions & 4 deletions azure_monitor/tests/test_base_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def callback_function(envelope):

base.add_telemetry_processor(callback_function)
envelope = Envelope(data=Data(base_type="type1"))
base.apply_telemetry_processors([envelope])
base._apply_telemetry_processors([envelope])
self.assertEqual(envelope.data.base_type, "type1_world")

def test_telemetry_processor_apply_multiple(self):
Expand All @@ -112,7 +112,7 @@ def callback_function2(envelope):
base.add_telemetry_processor(callback_function)
base.add_telemetry_processor(callback_function2)
envelope = Envelope(data=Data(base_type="type1"))
base.apply_telemetry_processors([envelope])
base._apply_telemetry_processors([envelope])
self.assertEqual(envelope.data.base_type, "type1_world_world2")

def test_telemetry_processor_apply_exception(self):
Expand All @@ -127,7 +127,7 @@ def callback_function2(envelope):
base.add_telemetry_processor(callback_function)
base.add_telemetry_processor(callback_function2)
envelope = Envelope(data=Data(base_type="type1"))
base.apply_telemetry_processors([envelope])
base._apply_telemetry_processors([envelope])
self.assertEqual(envelope.data.base_type, "type1_world2")

def test_telemetry_processor_apply_not_accepted(self):
Expand All @@ -139,7 +139,7 @@ def callback_function(envelope):
base.add_telemetry_processor(callback_function)
envelope = Envelope(data=Data(base_type="type1"))
envelope2 = Envelope(data=Data(base_type="type2"))
envelopes = base.apply_telemetry_processors([envelope, envelope2])
envelopes = base._apply_telemetry_processors([envelope, envelope2])
self.assertEqual(len(envelopes), 1)
self.assertEqual(envelopes[0].data.base_type, "type2")

Expand Down
Loading