Skip to content

Commit 900a616

Browse files
Merge pull request #252050 from AaronMaxwell/aaronmax-otel-python-comments-1
Adding comments to OpenTelemetry Python code
2 parents c9b0514 + 08062ee commit 900a616

File tree

2 files changed

+123
-17
lines changed

2 files changed

+123
-17
lines changed

articles/azure-monitor/app/opentelemetry-add-modify.md

Lines changed: 99 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ Dependencies
152152
- [Redis-4](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-redis-4)
153153
- [Azure SDK](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/instrumentation/opentelemetry-instrumentation-azure-sdk)
154154

155-
Auto instrumentation of Logs is currently only supported when using `applicationinsights` v3 Beta package. (https://www.npmjs.com/package/applicationinsights/v/beta)
155+
Automatic instrumentation of Logs is currently only supported when using `applicationinsights` v3 Beta package. (https://www.npmjs.com/package/applicationinsights/v/beta)
156+
156157
Logs
157158
- [Node.js console](https://nodejs.org/api/console.html)
158159
- [Bunyan](https://github.com/trentm/node-bunyan#readme)
@@ -268,21 +269,23 @@ To add a community instrumentation library (not officially supported/included in
268269
> Instrumenting a [supported instrumentation library](.\opentelemetry-add-modify.md?tabs=python#included-instrumentation-libraries) manually with `instrument()` in conjunction with the distro `configure_azure_monitor()` is not recommended. This is not a supported scenario and you may get undesired behavior for your telemetry.
269270
270271
```python
272+
# Import the `configure_azure_monitor()`, `SQLAlchemyInstrumentor`, `create_engine`, and `text` functions from the appropriate packages.
271273
from azure.monitor.opentelemetry import configure_azure_monitor
272274
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
273275
from sqlalchemy import create_engine, text
274276

277+
# Configure OpenTelemetry to use Azure Monitor.
275278
configure_azure_monitor()
276279

280+
# Create a SQLAlchemy engine.
277281
engine = create_engine("sqlite:///:memory:")
278-
# SQLAlchemy instrumentation is not officially supported by this package
279-
# However, you can use the OpenTelemetry instrument() method manually in
280-
# conjunction with configure_azure_monitor
282+
283+
# SQLAlchemy instrumentation is not officially supported by this package, however, you can use the OpenTelemetry `instrument()` method manually in conjunction with `configure_azure_monitor()`.
281284
SQLAlchemyInstrumentor().instrument(
282285
engine=engine,
283286
)
284287

285-
# Database calls using the SqlAlchemy library will be automatically captured
288+
# Database calls using the SQLAlchemy library will be automatically captured.
286289
with engine.connect() as conn:
287290
result = conn.execute(text("select 'hello world'"))
288291
print(result.all())
@@ -489,19 +492,26 @@ public class Program {
489492
#### [Python](#tab/python)
490493

491494
```python
495+
# Import the `configure_azure_monitor()` and `metrics` functions from the appropriate packages.
492496
from azure.monitor.opentelemetry import configure_azure_monitor
493497
from opentelemetry import metrics
494498

499+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
500+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
495501
configure_azure_monitor(
496502
connection_string="<your-connection-string>",
497503
)
504+
505+
# Get a meter provider and a meter with the name "otel_azure_monitor_histogram_demo".
498506
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_histogram_demo")
499507

508+
# Record three values to the histogram.
500509
histogram = meter.create_histogram("histogram")
501510
histogram.record(1.0, {"test_key": "test_value"})
502511
histogram.record(100.0, {"test_key2": "test_value"})
503512
histogram.record(30.0, {"test_key": "test_value2"})
504513

514+
# Wait for background execution.
505515
input()
506516
```
507517

@@ -639,19 +649,30 @@ public class Program {
639649
#### [Python](#tab/python)
640650

641651
```python
652+
# Import the `configure_azure_monitor()` and `metrics` functions from the appropriate packages.
642653
from azure.monitor.opentelemetry import configure_azure_monitor
643654
from opentelemetry import metrics
644655

656+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
657+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
645658
configure_azure_monitor(
646659
connection_string="<your-connection-string>",
647660
)
661+
# Get a meter provider and a meter with the name "otel_azure_monitor_counter_demo".
648662
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_counter_demo")
649663

664+
# Create a counter metric with the name "counter".
650665
counter = meter.create_counter("counter")
666+
667+
# Add three values to the counter.
668+
# The first argument to the `add()` method is the value to add.
669+
# The second argument is a dictionary of dimensions.
670+
# Dimensions are used to group related metrics together.
651671
counter.add(1.0, {"test_key": "test_value"})
652672
counter.add(5.0, {"test_key2": "test_value"})
653673
counter.add(3.0, {"test_key": "test_value2"})
654674

675+
# Wait for background execution.
655676
input()
656677
```
657678

@@ -796,17 +817,25 @@ public class Program {
796817
#### [Python](#tab/python)
797818

798819
```python
820+
# Import the necessary packages.
799821
from typing import Iterable
800822

801823
from azure.monitor.opentelemetry import configure_azure_monitor
802824
from opentelemetry import metrics
803825
from opentelemetry.metrics import CallbackOptions, Observation
804826

827+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
828+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
805829
configure_azure_monitor(
806830
connection_string="<your-connection-string>",
807831
)
832+
833+
# Get a meter provider and a meter with the name "otel_azure_monitor_gauge_demo".
808834
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_gauge_demo")
809835

836+
# Define two observable gauge generators.
837+
# The first generator yields a single observation with the value 9.
838+
# The second generator yields a sequence of 10 observations with the value 9 and a different dimension value for each observation.
810839
def observable_gauge_generator(options: CallbackOptions) -> Iterable[Observation]:
811840
yield Observation(9, {"test_key": "test_value"})
812841

@@ -818,9 +847,11 @@ def observable_gauge_sequence(options: CallbackOptions) -> Iterable[Observation]
818847
)
819848
return observations
820849

850+
# Create two observable gauges using the defined generators.
821851
gauge = meter.create_observable_gauge("gauge", [observable_gauge_generator])
822852
gauge2 = meter.create_observable_gauge("gauge2", [observable_gauge_sequence])
823853

854+
# Wait for background execution.
824855
input()
825856
```
826857

@@ -966,16 +997,22 @@ You can use `opentelemetry-api` to update the status of a span and record except
966997
The OpenTelemetry Python SDK is implemented in such a way that exceptions thrown are automatically captured and recorded. See the following code sample for an example of this behavior.
967998

968999
```python
1000+
# Import the necessary packages.
9691001
from azure.monitor.opentelemetry import configure_azure_monitor
9701002
from opentelemetry import trace
9711003

1004+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
1005+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
9721006
configure_azure_monitor(
9731007
connection_string="<your-connection-string>",
9741008
)
1009+
1010+
# Get a tracer for the current module.
9751011
tracer = trace.get_tracer("otel_azure_monitor_exception_demo")
9761012

9771013
# Exception events
9781014
try:
1015+
# Start a new span with the name "hello".
9791016
with tracer.start_as_current_span("hello") as span:
9801017
# This exception will be automatically recorded
9811018
raise Exception("Custom exception message.")
@@ -989,8 +1026,10 @@ within the context manager and use `record_exception()` directly as shown in the
9891026

9901027
```python
9911028
...
1029+
# Start a new span with the name "hello" and disable exception recording.
9921030
with tracer.start_as_current_span("hello", record_exception=False) as span:
9931031
try:
1032+
# Raise an exception.
9941033
raise Exception("Custom exception message.")
9951034
except Exception as ex:
9961035
# Manually record exception
@@ -1165,15 +1204,20 @@ The code example shows how to use the `tracer.start_as_current_span()` method to
11651204

11661205
```python
11671206
...
1207+
# Import the necessary packages.
11681208
from opentelemetry import trace
11691209

1210+
# Get a tracer for the current module.
11701211
tracer = trace.get_tracer(__name__)
11711212

1213+
# Start a new span with the name "my first span" and make it the current span.
11721214
# The "with" context manager starts, makes the span current, and ends the span within it's context
11731215
with tracer.start_as_current_span("my first span") as span:
11741216
try:
1175-
# Do stuff within the context of this
1217+
# Do stuff within the context of this span.
1218+
# All telemetry generated within this scope will be attributed to this span.
11761219
except Exception as ex:
1220+
# Record the exception on the span.
11771221
span.record_exception(ex)
11781222
...
11791223

@@ -1185,11 +1229,16 @@ If your method represents a background job not already captured by autoinstrumen
11851229

11861230
```python
11871231
...
1232+
# Import the necessary packages.
11881233
from opentelemetry import trace
11891234
from opentelemetry.trace import SpanKind
11901235

1236+
# Get a tracer for the current module.
11911237
tracer = trace.get_tracer(__name__)
1238+
1239+
# Start a new span with the name "my request span" and the kind set to SpanKind.SERVER.
11921240
with tracer.start_as_current_span("my request span", kind=SpanKind.SERVER) as span:
1241+
# Do stuff within the context of this span.
11931242
...
11941243
```
11951244

@@ -1329,7 +1378,7 @@ Not available in .NET.
13291378

13301379
If you want to add custom events or access the Application Insights API, replace the @azure/monitor-opentelemetry package with the `applicationinsights` [v3 Beta package](https://www.npmjs.com/package/applicationinsights/v/beta). It offers the same methods and interfaces, and all sample code for @azure/monitor-opentelemetry applies to the v3 Beta package.
13311380

1332-
To send custom telemetry with the Application Insights Classic API, use the `applicationinsights` [v3 Beta package](https://www.npmjs.com/package/applicationinsights/v/beta).
1381+
You need to use the `applicationinsights` v3 Beta package to send custom telemetry using the Application Insights classic API. (https://www.npmjs.com/package/applicationinsights/v/beta)
13331382

13341383
```javascript
13351384
const { TelemetryClient } = require("applicationinsights");
@@ -1575,28 +1624,38 @@ Use a custom processor:
15751624

15761625
```python
15771626
...
1627+
# Import the necessary packages.
15781628
from azure.monitor.opentelemetry import configure_azure_monitor
15791629
from opentelemetry import trace
15801630

1631+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
1632+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
15811633
configure_azure_monitor(
15821634
connection_string="<your-connection-string>",
15831635
)
1636+
1637+
# Create a SpanEnrichingProcessor instance.
15841638
span_enrich_processor = SpanEnrichingProcessor()
1585-
# Add the processor shown below to the current `TracerProvider`
1639+
1640+
# Add the span enrich processor to the current TracerProvider.
15861641
trace.get_tracer_provider().add_span_processor(span_enrich_processor)
15871642
...
15881643
```
15891644

15901645
Add `SpanEnrichingProcessor.py` to your project with the following code:
15911646

15921647
```python
1648+
# Import the SpanProcessor class from the opentelemetry.sdk.trace module.
15931649
from opentelemetry.sdk.trace import SpanProcessor
15941650

15951651
class SpanEnrichingProcessor(SpanProcessor):
15961652

15971653
def on_end(self, span):
1654+
# Prefix the span name with the string "Updated-".
15981655
span._name = "Updated-" + span.name
1656+
# Add the custom dimension "CustomDimension1" with the value "Value1".
15991657
span._attributes["CustomDimension1"] = "Value1"
1658+
# Add the custom dimension "CustomDimension2" with the value "Value2".
16001659
span._attributes["CustomDimension2"] = "Value2"
16011660
```
16021661

@@ -1652,6 +1711,7 @@ Use the add [custom property example](#add-a-custom-property-to-a-span), but rep
16521711
Use the add [custom property example](#add-a-custom-property-to-a-span), but replace the following lines of code in `SpanEnrichingProcessor.py`:
16531712

16541713
```python
1714+
# Set the `http.client_ip` attribute of the span to the specified IP address.
16551715
span._attributes["http.client_ip"] = "<IP Address>"
16561716
```
16571717

@@ -1726,6 +1786,7 @@ Use the add [custom property example](#add-a-custom-property-to-a-span), but rep
17261786
Use the add [custom property example](#add-a-custom-property-to-a-span), but replace the following lines of code:
17271787

17281788
```python
1789+
# Set the `enduser.id` attribute of the span to the specified user ID.
17291790
span._attributes["enduser.id"] = "<User ID>"
17301791
```
17311792

@@ -1777,6 +1838,7 @@ The Python [logging](https://docs.python.org/3/howto/logging.html) library is [a
17771838

17781839
```python
17791840
...
1841+
# Create a warning log message with the properties "key1" and "value1".
17801842
logger.warning("WARNING: Warning log with properties", extra={"key1": "value1"})
17811843
...
17821844

@@ -1945,17 +2007,21 @@ Use the add [custom property example](#add-a-custom-property-to-a-span), but rep
19452007

19462008
```python
19472009
...
2010+
# Import the Flask and Azure Monitor OpenTelemetry SDK libraries.
19482011
import flask
19492012
from azure.monitor.opentelemetry import configure_azure_monitor
19502013

1951-
# Configure Azure monitor collection telemetry pipeline
2014+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
2015+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
19522016
configure_azure_monitor(
19532017
connection_string="<your-connection-string>",
19542018
)
2019+
2020+
# Create a Flask application.
19552021
app = flask.Flask(__name__)
19562022

1957-
# Requests sent to this endpoint will not be tracked due to
1958-
# flask_config configuration
2023+
# Define a route. Requests sent to this endpoint will not be tracked due to
2024+
# flask_config configuration.
19592025
@app.route("/ignore")
19602026
def ignore():
19612027
return "Request received but not tracked."
@@ -1966,27 +2032,41 @@ Use the add [custom property example](#add-a-custom-property-to-a-span), but rep
19662032

19672033
```python
19682034
...
2035+
# Import the necessary libraries.
19692036
from azure.monitor.opentelemetry import configure_azure_monitor
19702037
from opentelemetry import trace
19712038

2039+
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
2040+
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
19722041
configure_azure_monitor(
19732042
connection_string="<your-connection-string>",
19742043
)
2044+
2045+
# Add a SpanFilteringProcessor to the tracer provider.
19752046
trace.get_tracer_provider().add_span_processor(SpanFilteringProcessor())
19762047
...
19772048
```
19782049

19792050
Add `SpanFilteringProcessor.py` to your project with the following code:
19802051

19812052
```python
2053+
# Import the necessary libraries.
19822054
from opentelemetry.trace import SpanContext, SpanKind, TraceFlags
19832055
from opentelemetry.sdk.trace import SpanProcessor
19842056

2057+
# Define a custom span processor called `SpanFilteringProcessor`.
19852058
class SpanFilteringProcessor(SpanProcessor):
19862059

1987-
# prevents exporting spans from internal activities
2060+
# Prevents exporting spans from internal activities.
19882061
def on_start(self, span):
2062+
# Check if the span is an internal activity.
19892063
if span._kind is SpanKind.INTERNAL:
2064+
# Create a new span context with the following properties:
2065+
# * The trace ID is the same as the trace ID of the original span.
2066+
# * The span ID is the same as the span ID of the original span.
2067+
# * The is_remote property is set to `False`.
2068+
# * The trace flags are set to `DEFAULT`.
2069+
# * The trace state is the same as the trace state of the original span.
19902070
span._context = SpanContext(
19912071
span.context.trace_id,
19922072
span.context.span_id,
@@ -2072,12 +2152,14 @@ Get the request trace ID and the span ID in your code:
20722152

20732153
Get the request trace ID and the span ID in your code:
20742154

2075-
```python
2076-
from opentelemetry import trace
2155+
```python
2156+
# Import the necessary libraries.
2157+
from opentelemetry import trace
20772158

2078-
trace_id = trace.get_current_span().get_span_context().trace_id
2079-
span_id = trace.get_current_span().get_span_context().span_id
2080-
```
2159+
# Get the trace ID and span ID of the current span.
2160+
trace_id = trace.get_current_span().get_span_context().trace_id
2161+
span_id = trace.get_current_span().get_span_context().span_id
2162+
```
20812163

20822164
---
20832165

0 commit comments

Comments
 (0)