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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
([#254](https://github.com/microsoft/ApplicationInsights-Python/pull/254))
- Add support for FastAPI instrumentation
([#255](https://github.com/microsoft/ApplicationInsights-Python/pull/255))
- Add support for Urllib3/Urllib instrumentation
([#256](https://github.com/microsoft/ApplicationInsights-Python/pull/256))

## [1.0.0b10](https://github.com/microsoft/ApplicationInsights-Python/releases/tag/v1.0.0b10) - 2023-02-23

Expand Down
11 changes: 8 additions & 3 deletions azure-monitor-opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ This distro automatically installs the following libraries:

## Officially supported instrumentations

The following OpenTelemetry instrumentations come bundled in with the Azure monitor distro. If you would like to add support for another OpenTelemetry instrumentation, please submit a feature [request][distro_feature_request]. In the meantime, you can use the OpenTelemetry instrumentation manually via it's own APIs (i.e. `instrument()`) in your code.
The following OpenTelemetry instrumentations come bundled in with the Azure monitor distro. If you would like to add support for another OpenTelemetry instrumentation, please submit a feature [request][distro_feature_request]. In the meantime, you can use the OpenTelemetry instrumentation manually via it's own APIs (i.e. `instrument()`) in your code. See [this][samples_manual] for an example.

* [OpenTelemetry Requests Instrumentation][opentelemetry_instrumentation_requests]
* [OpenTelemetry Django Instrumentation][opentelemetry_instrumentation_django]
* [OpenTelemetry FastApi Instrumentation][opentelemetry_instrumentation_fastapi]
* [OpenTelemetry Flask Instrumentation][opentelemetry_instrumentation_flask]
* [OpenTelemetry Psycopg2 Instrumentation][opentelemetry_instrumentation_psycopg2]
* [OpenTelemetry Requests Instrumentation][opentelemetry_instrumentation_requests]
* [OpenTelemetry UrlLib Instrumentation][opentelemetry_instrumentation_urllib]
* [OpenTelemetry UrlLib3 Instrumentation][opentelemetry_instrumentation_urllib3]

## Getting started

Expand Down Expand Up @@ -117,13 +119,16 @@ Samples are available [here][samples] to demonstrate how to utilize the above co
[ot_sdk_python_metric_reader]: https://opentelemetry-python.readthedocs.io/en/stable/sdk/metrics.export.html#opentelemetry.sdk.metrics.export.MetricReader
[ot_sdk_python_resource]: https://github.com/open-telemetry/opentelemetry-python/blob/main/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py#L153
[ot_sdk_python_view_examples]: https://github.com/open-telemetry/opentelemetry-python/tree/main/docs/examples/metrics/views
[opentelemetry_instrumentation_requests]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-requests
[opentelemetry_instrumentation_django]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-django
[opentelemetry_instrumentation_fastapi]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-fastapi
[opentelemetry_instrumentation_flask]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-flask
[opentelemetry_instrumentation_psycopg2]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-psycopg2
[opentelemetry_instrumentation_requests]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-requests
[opentelemetry_instrumentation_urllib]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-urllib
[opentelemetry_instrumentation_urllib3]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-urllib3
[opentelemetry_spec_resource]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#resource-sdk
[opentelemetry_spec_view]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view
[python]: https://www.python.org/downloads/
[pip]: https://pypi.org/project/pip/
[samples]: https://github.com/microsoft/ApplicationInsights-Python/tree/main/azure-monitor-opentelemetry/samples
[samples_manual]: https://github.com/microsoft/ApplicationInsights-Python/tree/main/azure-monitor-opentelemetry/samples/tracing/manual.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
"flask",
"psycopg2",
"requests",
"urllib",
"urllib3",
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
tracing_export_interval_millis=15000,
)

# Database calls using the psycopg2 library will be automatically captured
cnx = psycopg2.connect(database="test", user="<user>", password="<password>")
cursor = cnx.cursor()
cursor.execute("INSERT INTO test_tables (test_field) VALUES (123)")
Expand Down
10 changes: 8 additions & 2 deletions azure-monitor-opentelemetry/samples/tracing/http_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@

# Requests made to fastapi endpoints will be automatically captured
@app.get("/")
async def root():
async def test():
return {"message": "Hello World"}


# Exceptions that are raised within the request are automatically captured
@app.get("/exception")
async def exception():
raise Exception("Hit an exception")


# Telemetry from this endpoint will not be captured due to excluded_urls config above
@app.get("/exclude")
async def root():
async def exclude():
return {"message": "Telemetry was not captured"}
34 changes: 34 additions & 0 deletions azure-monitor-opentelemetry/samples/tracing/http_urllib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License in the project root for
# license information.
# --------------------------------------------------------------------------
import logging
from urllib import request

from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace

logger = logging.getLogger(__name__)

# Configure Azure monitor collection telemetry pipeline
configure_azure_monitor(
connection_string="<your-connection-string>",
disable_logging=True,
disable_metrics=True,
tracing_export_interval_millis=15000,
)

tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("Request parent span") as span:
try:
# Requests made using the urllib library will be automatically captured
req = request.Request("https://www.example.org/", method="GET")
r = request.urlopen(req)
logger.warning("Request sent")
except Exception as ex:
# If an exception occurs, this can be manually recorded on the parent span
span.set_attribute("status", "exception")
span.record_exception(ex)

input()
35 changes: 35 additions & 0 deletions azure-monitor-opentelemetry/samples/tracing/http_urllib3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License in the project root for
# license information.
# --------------------------------------------------------------------------
import logging

import urllib3
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace

logger = logging.getLogger(__name__)

# Configure Azure monitor collection telemetry pipeline
configure_azure_monitor(
connection_string="<your-connection-string>",
disable_logging=True,
disable_metrics=True,
tracing_export_interval_millis=15000,
)

http = urllib3.PoolManager()

tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("Request parent span") as span:
try:
# Requests made using the urllib3 library will be automatically captured
response = http.request("GET", "https://www.example.org/")
logger.warning("Request sent")
except Exception as ex:
# If an exception occurs, this can be manually recorded on the parent span
span.set_attribute("status", "exception")
span.record_exception(ex)

input()
30 changes: 30 additions & 0 deletions azure-monitor-opentelemetry/samples/tracing/manual.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License in the project root for
# license information.
# --------------------------------------------------------------------------
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from sqlalchemy import create_engine, text

configure_azure_monitor(
connection_string="<your-connection-string>",
tracing_export_interval_millis=15000,
disable_logging=True,
disable_metrics=True,
)

engine = create_engine("sqlite:///:memory:")
# SQLAlchemy instrumentation is not officially supported by this package
# However, you can use the OpenTelemetry instument method manually in
# conjunction with configure_azure_monitor
SQLAlchemyInstrumentor().instrument(
engine=engine,
)

# Database calls using the SqlAlchemy library will be automatically captured
with engine.connect() as conn:
result = conn.execute(text("select 'hello world'"))
print(result.all())

input()
27 changes: 27 additions & 0 deletions azure-monitor-opentelemetry/samples/tracing/sampling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License in the project root for
# license information.
# --------------------------------------------------------------------------

from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace

configure_azure_monitor(
connection_string="<your-connection-string>",
# Sampling ratio of between 0 and 1 inclusive
# 0.1 means approximately 10% of your traces are sent
sampling_ratio=0.1,
tracing_export_interval_millis=15000,
disable_logging=True,
disable_metrics=True,
)

tracer = trace.get_tracer(__name__)

for i in range(100):
# Approximately 90% of these spans should be sampled out
with tracer.start_as_current_span("hello"):
print("Hello, World!")

input()
2 changes: 2 additions & 0 deletions azure-monitor-opentelemetry/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@
"opentelemetry-instrumentation-flask~=0.36b0",
"opentelemetry-instrumentation-psycopg2~=0.36b0",
"opentelemetry-instrumentation-requests~=0.36b0",
"opentelemetry-instrumentation-urllib~=0.36b0",
"opentelemetry-instrumentation-urllib3~=0.36b0",
"opentelemetry-api==1.15.0",
"opentelemetry-sdk==1.15.0",
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License in the project root for
# license information.
# --------------------------------------------------------------------------

import unittest

from opentelemetry.instrumentation.urllib import URLLibInstrumentor


class TestUrllibInstrumentation(unittest.TestCase):
def test_instrument(self):
try:
URLLibInstrumentor().instrument()
except Exception as ex: # pylint: disable=broad-except
print(ex)
self.fail(
f"Unexpected exception raised when instrumenting {URLLibInstrumentor.__name__}"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License in the project root for
# license information.
# --------------------------------------------------------------------------

import unittest

from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor


class TestUrllib3Instrumentation(unittest.TestCase):
def test_instrument(self):
try:
URLLib3Instrumentor().instrument()
except Exception as ex: # pylint: disable=broad-except
print(ex)
self.fail(
f"Unexpected exception raised when instrumenting {URLLib3Instrumentor.__name__}"
)
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ fastapi
flask
psycopg2
requests
urllib3