Skip to content
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
176 changes: 171 additions & 5 deletions sdk/monitor/azure-monitor-opentelemetry-exporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,41 @@ Install the Microsoft Opentelemetry exporter for Azure Monitor with [pip][pip]:
pip install azure-monitor-opentelemetry-exporter --pre
```

### Prerequisites:
### Prerequisites

To use this package, you must have:

* Azure subscription - [Create a free account][azure_sub]
* Azure Monitor - [How to use application insights][application_insights_namespace]
* Opentelemetry SDK - [Opentelemtry SDK for Python][ot_sdk_python]
* Python 3.6 or later - [Install Python][python]

### Instantiate the client

Interaction with Azure monitor exporter starts with an instance of the `AzureMonitorTraceExporter` class for distributed tracing or `AzureMonitorLogExporter` for logging. You will need a **connection_string** to instantiate the object.
Interaction with Azure monitor exporter starts with an instance of the `AzureMonitorTraceExporter` class for distributed tracing, `AzureMonitorLogExporter` for logging and `AzureMonitorMetricExporter` for metrics. You will need a **connection_string** to instantiate the object.
Please find the samples linked below for demonstration as to how to construct the exporter using a connection string.

#### Logging

NOTE: The logging signal for the `AzureMonitorLogExporter` is currently in an EXPERIMENTAL state. Possible breaking changes may ensue in the future.

```Python
from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter
exporter = AzureMonitorLogExporter.from_connection_string(
conn_str = os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
```

#### Metrics

```Python
from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter
exporter = AzureMonitorMetricExporter.from_connection_string(
conn_str = os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

```

#### Tracing

```Python
Expand All @@ -53,6 +67,11 @@ from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter
exporter = AzureMonitorLogExporter()
```

```python
from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter
exporter = AzureMonitorMetricExporter()
```

```python
from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter
exporter = AzureMonitorTraceExporter()
Expand Down Expand Up @@ -80,7 +99,21 @@ Some of the key concepts for the Azure monitor exporter include:

* [AzureMonitorLogExporter][log_reference]: This is the class that is initialized to send logging related telemetry to Azure Monitor.

* [Trace][trace_concept]: Trace refers to distributed tracing. It can be thought of as a directed acyclic graph (DAG) of `Span`s, where the edges between `Span`s are defined as parent/child relationship.
* [Metric][metric_concept]: `Metric` refers to recording raw measurements with predefined aggregation and sets of attributes for a period in time.

* [Measurement][measurement]: Represents a data point recorded at a point in time.

* [Instrument][instrument]: Instruments are used to report `Measurement`s.

* [Meter][meter]: The `Meter` is responsible for creating `Instruments`.

* [Meter Provider][meter_provider]: Provides a `Meter` for the given instrumentation library.

* [Metric Reader][metric_reader]: An SDK implementation object that provides the common configurable aspects of the OpenTelemetry Metrics SDK such as collection, flushing and shutdown.

* [AzureMonitorMetricExporter][metric_reference]: This is the class that is initialized to send metric related telemetry to Azure Monitor.

* [Trace][trace_concept]: Trace refers to distributed tracing. A distributed trace is a set of events, triggered as a result of a single logical operation, consolidated across various components of an application. In particular, a Trace can be thought of as a directed acyclic graph (DAG) of Spans, where the edges between Spans are defined as parent/child relationship.

* [Span][span]: Represents a single operation within a `Trace`. Can be nested to form a trace tree. Each trace contains a root span, which typically describes the entire operation and, optionally, one ore more sub-spans for its sub-operations.

Expand All @@ -105,6 +138,7 @@ The following sections provide several code snippets covering some of the most c
* [Exporting a log record](#export-hello-world-log)
* [Exporting correlated log record](#export-correlated-log)
* [Exporting log record with custom properties](#export-custom-properties-log)
* [Exporting an exceptions log record](#export-exceptions-log)

#### Export Hello World Log

Expand Down Expand Up @@ -216,6 +250,131 @@ logger = logging.getLogger(__name__)
logger.debug("DEBUG: Debug with properties", extra={"debug": "true"})
```

#### Export Exceptions Log

```Python
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
"""
An example showing how to export exception telemetry using the AzureMonitorLogExporter.
"""
import os
import logging

from opentelemetry.sdk._logs import (
LogEmitterProvider,
LoggingHandler,
get_log_emitter_provider,
set_log_emitter_provider,
)
from opentelemetry.sdk._logs.export import BatchLogProcessor

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter

set_log_emitter_provider(LogEmitterProvider())
exporter = AzureMonitorLogExporter.from_connection_string(
os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
get_log_emitter_provider().add_log_processor(BatchLogProcessor(exporter))

# Attach LoggingHandler to namespaced logger
handler = LoggingHandler()
logger = logging.getLogger(__name__)
logger.addHandler(handler)
logger.setLevel(logging.NOTSET)

# The following code will generate two pieces of exception telemetry
# that are identical in nature
try:
val = 1 / 0
print(val)
except ZeroDivisionError:
logger.exception("Error: Division by zero")

try:
val = 1 / 0
print(val)
except ZeroDivisionError:
logger.error("Error: Division by zero", stack_info=True, exc_info=True)
```

### Metrics

The following sections provide several code snippets covering some of the most common tasks, including:

* [Using different metric instruments](#metric-instrument-usage)

#### Metric instrument usage

```python
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
"""
An example to show an application using all instruments in the OpenTelemetry SDK. Metrics created
and recorded using the sdk are tracked and telemetry is exported to application insights with the
AzureMonitorMetricsExporter.
"""
import os
from typing import Iterable

from opentelemetry import metrics
from opentelemetry.metrics import CallbackOptions, Observation
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter

exporter = AzureMonitorMetricExporter.from_connection_string(
os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=5000)
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))

# Create a namespaced meter
meter = metrics.get_meter_provider().get_meter("sample")

# Callback functions for observable instruments
def observable_counter_func(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(1, {})


def observable_up_down_counter_func(
options: CallbackOptions,
) -> Iterable[Observation]:
yield Observation(-10, {})


def observable_gauge_func(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(9, {})

# Counter
counter = meter.create_counter("counter")
counter.add(1)

# Async Counter
observable_counter = meter.create_observable_counter(
"observable_counter", [observable_counter_func]
)

# UpDownCounter
updown_counter = meter.create_up_down_counter("updown_counter")
updown_counter.add(1)
updown_counter.add(-5)

# Async UpDownCounter
observable_updown_counter = meter.create_observable_up_down_counter(
"observable_updown_counter", [observable_up_down_counter_func]
)

# Histogram
histogram = meter.create_histogram("histogram")
histogram.record(99.9)

# Async Gauge
gauge = meter.create_observable_gauge("gauge", [observable_gauge_func])

```

### Tracing

The following sections provide several code snippets covering some of the most common tasks, including:
Expand Down Expand Up @@ -334,11 +493,18 @@ contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additio
[log_emitter_provider]: https://opentelemetry-python.readthedocs.io/en/stable/sdk/logs.html#opentelemetry.sdk._logs.LogEmitterProvider
[log_processor]: https://opentelemetry-python.readthedocs.io/en/stable/sdk/logs.html#opentelemetry.sdk._logs.LogProcessor
[logging_handler]: https://opentelemetry-python.readthedocs.io/en/stable/sdk/logs.html#opentelemetry.sdk._logs.LoggingHandler
[log_reference]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/logs/_exporter.py#L30
[log_reference]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/logs/_exporter.py
[metric_concept]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#metric-signal
[measurement]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#measurement
[instrument]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument
[meter]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#meter
[meter_provider]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#meterprovider
[metric_reader]:https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#metricreader
[metric_reference]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/metrics/_exporter.py
[trace_concept]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#tracing-signal
[span]: https://opentelemetry-python.readthedocs.io/en/stable/api/trace.html?highlight=TracerProvider#opentelemetry.trace.Span
[tracer]: https://opentelemetry-python.readthedocs.io/en/stable/api/trace.html?highlight=TracerProvider#opentelemetry.trace.Tracer
[tracer_provider]: https://opentelemetry-python.readthedocs.io/en/stable/api/trace.html?highlight=TracerProvider#opentelemetry.trace.TracerProvider
[span_processor]: https://opentelemetry-python.readthedocs.io/en/stable/_modules/opentelemetry/sdk/trace.html?highlight=SpanProcessor#
[trace_reference]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py#L30
[trace_reference]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py
[sampler_ref]: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#sampling
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@
logger.addHandler(handler)
logger.setLevel(logging.NOTSET)

# The following code will generate two pieces of exception telemetry
# that are identical in nature
try:
val = 1 / 0
print(val)
except ZeroDivisionError:
logger.exception("Error: Division by zero")

try:
val = 1 / 0
print(val)
except ZeroDivisionError:
logger.error("Error: Division by zero", stack_info=True, exc_info=True)
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ products:

These code samples show common champion scenario operations with the AzureMonitorMetricExporter.

* Metrics: [sample_metrics.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/samples/metrics/sample_metrics.py)
* Instruments: [sample_instruments.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/samples/metrics/sample_instruments.py)


## Installation

```sh
Expand All @@ -22,17 +20,6 @@ $ pip install azure-monitor-opentelemetry-exporter --pre

## Run the Applications

### Metrics

* Update `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable

* Run the sample

```sh
$ # from this directory
$ python sample_metrics.py
```

### Instrument usage

* Update `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable
Expand Down

This file was deleted.