diff --git a/README.md b/README.md
index 6a2aecf..8bdfb26 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,62 @@
-[Middleware](https://middleware.io/)'s APM (Application Performance Monitoring) tool is a powerful solution that empowers developers to gain valuable insights into the performance and behavior of their Python applications.
+[![Contributors][contributors-shield]][contributors-url]
+[![Forks][forks-shield]][forks-url]
+[![Stargazers][stars-shield]][stars-url]
+[![Issues][issues-shield]][issues-url]
+[![MIT License][license-shield]][license-url]
+[![LinkedIn][linkedin-shield]][linkedin-url]
-By installing the Middleware Host agent and integrating the APM package, developers can seamlessly monitor their applications and take advantage of various functionalities. The APM allows automatic collection of distributed tracing data, metrics, logs, and profiling information.
+
+
-You can follow our [documentation](https://docs.middleware.io/docs/apm-configuration/python/python-apm-setup) to install the Middleware Host agent and integrate the APM package with your [Python](https://app.middleware.io/installation/apm/python) application.
+
Middleware - Python APM
+
+
+ An Application Performance Monitoring (APM) tool for Python applications and libraries
+
+ Explore the docs »
+
+
+ Report Bug
+ ·
+ Request Feature
+
+
+
+## About
+
+[![Product Name Screen Shot][product-screenshot]](https://middleware.io/)
+
+Middleware's APM (Application Performance Monitoring) tool offers a comprehensive solution for developers seeking to enhance the performance and observability of their Python applications.
+
+By installing the Middleware Host Agent and integrating the APM package, developers can seamlessly monitor applications, capturing distributed tracing data, metrics, logs, and profiling information. This enables a thorough view of application performance and behavior.
+
+For detailed instructions on installing the Middleware Host Agent and integrating the APM package, refer to our [documentation](https://docs.middleware.io/apm-configuration/python) for Python applications.
+
+# Installation
+
+Run the following command in your terminal:
+
+```shell
+pip install middleware-apm
+```
+
+For further details on prerequisites, configuration options, and use, visit our docs page at [https://docs.middleware.io/apm-configuration/python](https://docs.middleware.io/apm-configuration/python).
+
+
+## License
+
+Distributed under the Apache License. See `LICENSE` for more information.
+
+[contributors-shield]: https://img.shields.io/github/contributors/middleware-labs/agent-apm-python.svg?style=for-the-badge
+[contributors-url]: https://github.com/middleware-labs/agent-apm-python/graphs/contributors
+[forks-shield]: https://img.shields.io/github/forks/middleware-labs/agent-apm-python.svg?style=for-the-badge
+[forks-url]: https://github.com/middleware-labs/agent-apm-python/network/members
+[stars-shield]: https://img.shields.io/github/stars/middleware-labs/agent-apm-python.svg?style=for-the-badge
+[stars-url]: https://github.com/middleware-labs/agent-apm-python/stargazers
+[issues-shield]: https://img.shields.io/github/issues/middleware-labs/agent-apm-python.svg?style=for-the-badge
+[issues-url]: https://github.com/middleware-labs/agent-apm-python/issues
+[license-shield]: https://img.shields.io/github/license/middleware-labs/agent-apm-python.svg?style=for-the-badge
+[license-url]: https://github.com/middleware-labs/agent-apm-python/blob/master/LICENSE
+[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
+[linkedin-url]: https://www.linkedin.com/company/middleware-labs
+[product-screenshot]: https://private-user-images.githubusercontent.com/176276560/353724065-da5d3b3b-cd41-4dbc-b322-235eb1e7b0de.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzAzMjA3NTksIm5iZiI6MTczMDMyMDQ1OSwicGF0aCI6Ii8xNzYyNzY1NjAvMzUzNzI0MDY1LWRhNWQzYjNiLWNkNDEtNGRiYy1iMzIyLTIzNWViMWU3YjBkZS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMDMwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTAzMFQyMDM0MTlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kYmRiMTA3MDAxYmRmODBlNDFiNGEyYTZhMTIyOWU4MWEyOGM0MTY0MTQ0ZjJjZmM4YmJlNzI2NTAwMjRiZmU2JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.lN0ps1u5z1kDwvwuWN6r2IYCdkHlz31x_WRdWuuIgi4
diff --git a/dev-requirements.txt b/dev-requirements.txt
new file mode 100644
index 0000000..b2e88be
--- /dev/null
+++ b/dev-requirements.txt
@@ -0,0 +1,181 @@
+#
+# This file is autogenerated by pip-compile with Python 3.12
+# by the following command:
+#
+# pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml
+#
+astroid==3.3.5
+ # via pylint
+black==24.10.0
+ # via middleware-apm (pyproject.toml)
+build==1.2.2.post1
+ # via pip-tools
+certifi==2024.8.30
+ # via requests
+cffi==1.17.1
+ # via pyroscope-io
+charset-normalizer==3.4.0
+ # via requests
+click==8.1.7
+ # via
+ # black
+ # pip-tools
+deprecated==1.2.14
+ # via
+ # opentelemetry-api
+ # opentelemetry-exporter-otlp-proto-grpc
+ # opentelemetry-propagator-b3
+ # opentelemetry-semantic-conventions
+dill==0.3.9
+ # via pylint
+distro==1.9.0
+ # via middleware-apm (pyproject.toml)
+googleapis-common-protos==1.65.0
+ # via opentelemetry-exporter-otlp-proto-grpc
+grpcio==1.67.1
+ # via opentelemetry-exporter-otlp-proto-grpc
+idna==3.10
+ # via requests
+importlib-metadata==8.4.0
+ # via
+ # opentelemetry-api
+ # opentelemetry-instrumentation-flask
+isort==5.13.2
+ # via
+ # middleware-apm (pyproject.toml)
+ # pylint
+mccabe==0.7.0
+ # via pylint
+mypy-extensions==1.0.0
+ # via black
+opentelemetry-api==1.27.0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-distro
+ # opentelemetry-exporter-otlp-proto-grpc
+ # opentelemetry-instrumentation
+ # opentelemetry-instrumentation-django
+ # opentelemetry-instrumentation-flask
+ # opentelemetry-instrumentation-wsgi
+ # opentelemetry-propagator-aws-xray
+ # opentelemetry-propagator-b3
+ # opentelemetry-propagator-gcp
+ # opentelemetry-propagator-jaeger
+ # opentelemetry-propagator-ot-trace
+ # opentelemetry-sdk
+ # opentelemetry-semantic-conventions
+opentelemetry-distro==0.48b0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-exporter-otlp-proto-common==1.27.0
+ # via opentelemetry-exporter-otlp-proto-grpc
+opentelemetry-exporter-otlp-proto-grpc==1.27.0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-instrumentation==0.48b0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-distro
+ # opentelemetry-instrumentation-django
+ # opentelemetry-instrumentation-flask
+ # opentelemetry-instrumentation-wsgi
+opentelemetry-instrumentation-django==0.48b0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-instrumentation-flask==0.48b0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-instrumentation-wsgi==0.48b0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-instrumentation-django
+ # opentelemetry-instrumentation-flask
+opentelemetry-propagator-aws-xray==1.0.2
+ # via middleware-apm (pyproject.toml)
+opentelemetry-propagator-b3==1.27.0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-propagator-gcp==1.7.0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-propagator-jaeger==1.27.0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-propagator-ot-trace==0.48b0
+ # via middleware-apm (pyproject.toml)
+opentelemetry-proto==1.27.0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-exporter-otlp-proto-common
+ # opentelemetry-exporter-otlp-proto-grpc
+opentelemetry-sdk==1.27.0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-distro
+ # opentelemetry-exporter-otlp-proto-grpc
+ # opentelemetry-propagator-ot-trace
+opentelemetry-semantic-conventions==0.48b0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-instrumentation-django
+ # opentelemetry-instrumentation-flask
+ # opentelemetry-instrumentation-wsgi
+ # opentelemetry-sdk
+opentelemetry-util-http==0.48b0
+ # via
+ # middleware-apm (pyproject.toml)
+ # opentelemetry-instrumentation-django
+ # opentelemetry-instrumentation-flask
+ # opentelemetry-instrumentation-wsgi
+packaging==24.1
+ # via
+ # black
+ # build
+ # opentelemetry-instrumentation-flask
+pathspec==0.12.1
+ # via black
+pip-tools==7.4.1
+ # via middleware-apm (pyproject.toml)
+platformdirs==4.3.6
+ # via
+ # black
+ # pylint
+protobuf==4.25.5
+ # via
+ # googleapis-common-protos
+ # opentelemetry-proto
+psutil==6.0.0
+ # via middleware-apm (pyproject.toml)
+pycparser==2.22
+ # via cffi
+pylint==3.3.1
+ # via middleware-apm (pyproject.toml)
+pyproject-hooks==1.2.0
+ # via
+ # build
+ # pip-tools
+pyroscope-io==0.8.5 ; sys_platform != "win32"
+ # via middleware-apm (pyproject.toml)
+python-dotenv==1.0.1
+ # via middleware-apm (pyproject.toml)
+pyyaml==6.0.2
+ # via middleware-apm (pyproject.toml)
+requests==2.32.3
+ # via middleware-apm (pyproject.toml)
+six==1.16.0
+ # via thrift
+thrift==0.20.0
+ # via middleware-apm (pyproject.toml)
+tomli==2.0.1
+ # via middleware-apm (pyproject.toml)
+tomlkit==0.13.2
+ # via pylint
+typing-extensions==4.12.2
+ # via opentelemetry-sdk
+urllib3==2.2.3
+ # via requests
+wheel==0.44.0
+ # via pip-tools
+wrapt==1.16.0
+ # via
+ # deprecated
+ # opentelemetry-instrumentation
+zipp==3.20.2
+ # via importlib-metadata
+
+# The following packages are considered to be unsafe in a requirements file:
+# pip
+# setuptools
diff --git a/middleware/__init__.py b/middleware/__init__.py
index 9c536c7..c1b8b09 100644
--- a/middleware/__init__.py
+++ b/middleware/__init__.py
@@ -1 +1,6 @@
+"""
+An Application Performance Monitoring (APM) tool for Python applications and
+libraries
+"""
+
from .lib.mw_tracker import MwTracker
diff --git a/middleware/lib/mw_tracker.py b/middleware/lib/mw_tracker.py
index f164754..9ce1304 100644
--- a/middleware/lib/mw_tracker.py
+++ b/middleware/lib/mw_tracker.py
@@ -1,3 +1,5 @@
+"""Module for MwTracker class"""
+
import os
import psutil
import logging
@@ -11,6 +13,18 @@
class MwTracker:
+ """Class that pulls configuration settings from either environment
+ variables or ``middleware.ini`` and begins emitting and exporting
+ telemetry upon initialization. This should be intialized at the top
+ of your entrypoint.
+
+ Example
+ --------
+
+ >>> from middleware import MwTracker
+ >>> tracker = MwTracker()
+ """
+
def __init__(self):
self.project_name = config.project_name
@@ -52,7 +66,22 @@ def collect_logs(self):
logging.getLogger().addHandler(handler)
logging.setLogRecordFactory(self._set_custom_log_attr)
- def record_error(self, error):
+ def record_error(self, error: BaseException) -> None:
+ """Records an exception and creates a span event
+
+ Parameters
+ ----------
+ error : BaseException
+ An Exception
+
+ Example
+ --------
+
+ >>> try:
+ ... not_possible = 12 / 0
+ ... except ZeroDivisionError as e:
+ ... tracker.record_error(e)
+ """
from ._tracer import record_error
record_error(error)
@@ -60,6 +89,7 @@ def record_error(self, error):
def django_instrument(self):
if config.collect_traces:
from opentelemetry.instrumentation.django import DjangoInstrumentor
+
DjangoInstrumentor().instrument()
def _set_custom_log_attr(self, *args, **kwargs):
@@ -82,7 +112,7 @@ def _get_project_name(self, resource_attributes) -> str:
return project_name
def _health_check(self):
- if config.target == "" or ("https" not in config.target) :
+ if config.target == "" or ("https" not in config.target):
try:
response = requests.get(
f"http://{config.mw_agent_service}:13133/healthcheck", timeout=5
@@ -92,7 +122,9 @@ def _health_check(self):
f"[{yellow_color}WARN{reset_color}]: MW Agent Health Check is failing ...\nThis could be due to incorrect value of MW_AGENT_SERVICE\nIgnore the warning if you are using MW Agent older than 1.7.7 (You can confirm by running `mw-agent version`)"
)
except requests.exceptions.RequestException as e:
- print(f"[{yellow_color}WARN{reset_color}]: MW Agent Health Check is failing ...\nException while MW Agent Health Check:{e}")
+ print(
+ f"[{yellow_color}WARN{reset_color}]: MW Agent Health Check is failing ...\nException while MW Agent Health Check:{e}"
+ )
def _get_instrument_info(self):
if config.disable_info != True:
diff --git a/pyproject.toml b/pyproject.toml
index 329bd60..eaef367 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,15 @@ requires-python = ">=3.8"
license = { text = "Apache-2.0" }
authors = [{ name = "middleware-dev" }]
maintainers = [{ name = "middleware-dev" }]
-keywords = ["APM", "middleware", "monitoring", "tracing", "metrics", "logs", "profiling"]
+keywords = [
+ "APM",
+ "middleware",
+ "monitoring",
+ "tracing",
+ "metrics",
+ "logs",
+ "profiling",
+]
dependencies = [
"distro==1.9.0",
"opentelemetry-api==1.27.0",
@@ -35,9 +43,12 @@ dependencies = [
"opentelemetry-propagator-jaeger==1.27.0",
"opentelemetry-propagator-aws-xray==1.0.2",
"opentelemetry-propagator-ot-trace==0.48b0",
- "opentelemetry-propagator-gcp==1.7.0"
+ "opentelemetry-propagator-gcp==1.7.0",
]
+[project.optional-dependencies]
+dev = ["pip-tools", "pylint", "black", "python-dotenv", "isort"]
+
[project.urls]
Source = "https://github.com/middleware-labs/agent-apm-python.git"
Homepage = "https://docs.middleware.io/docs/apm-configuration/python"
@@ -52,4 +63,10 @@ middleware-bootstrap = "opentelemetry.instrumentation.bootstrap:run"
include = ["scripts", "middleware", "middleware.installer", "middleware.lib"]
[tool.setuptools.package-data]
-"*" = ["middleware.ini"]
\ No newline at end of file
+"*" = ["middleware.ini"]
+
+[tool.pylint.format]
+max-line-length = "88"
+
+[tool.isort]
+profile = "black"