diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8fa9bca --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Flask with middleware-run", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/flask/flaskenv/bin/flask", + "args": [ + "run", + "--no-reload" + ], + "env": { + "FLASK_APP": "${workspaceFolder}/flask/app.py", // adjust if your app entry point is different + "FLASK_ENV": "development", + "MW_SERVICE_NAME": "flask-demo-apps", + "PATH": "${workspaceFolder}/flask/flaskenv/bin", + "DEBUG_MODE": "1" + }, + "cwd": "${workspaceFolder}/flask", + "console": "integratedTerminal", + "justMyCode": false, + "python": "${workspaceFolder}/flask/flaskenv/bin/python3", + "subProcess": true + } + ] + } + \ No newline at end of file diff --git a/Flask-O-shop b/Flask-O-shop new file mode 160000 index 0000000..d439c4a --- /dev/null +++ b/Flask-O-shop @@ -0,0 +1 @@ +Subproject commit d439c4a50d10d0c51820db3422f9197d298ead5e diff --git a/django/django_uwsgi_nginx/django_uwsgi_nginx_wsgi.py b/django/django_uwsgi_nginx/django_uwsgi_nginx_wsgi.py index ffda53e..95d3bd6 100755 --- a/django/django_uwsgi_nginx/django_uwsgi_nginx_wsgi.py +++ b/django/django_uwsgi_nginx/django_uwsgi_nginx_wsgi.py @@ -1,5 +1,12 @@ import os from django.core.wsgi import get_wsgi_application +from uwsgidecorators import postfork +from middleware import mw_tracker, MWOptions, record_exception, DETECT_AWS_EC2 + +@postfork +def tracing(): + mw_tracker() os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_uwsgi_nginx_settings') application = get_wsgi_application() + diff --git a/django/django_uwsgi_nginx_otel/Dockerfile b/django/django_uwsgi_nginx_otel/Dockerfile new file mode 100755 index 0000000..ff2a28e --- /dev/null +++ b/django/django_uwsgi_nginx_otel/Dockerfile @@ -0,0 +1,24 @@ +FROM python:3.10 +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY . . +ENV DJANGO_SETTINGS_MODULE=django_uwsgi_nginx_settings +RUN ls -l /app && python manage.py collectstatic --noinput + +# replace with your Middleware API key +ENV MW_API_KEY="whkvkobudfitutobptgonaezuxpjjypnejbb" + +# replace with your Middleware App name +ENV MW_SERVICE_NAME="MyPythonApp" + +# replace with your Middleware App url for serverless +ENV MW_TARGET="https://myapp.middleware.io:443" + +# enable Middleware Console Exporter for logs and debug +ENV MW_CONSOLE_EXPORTER=True +ENV MW_DEBUG_LOG_FILE=True +ENV MW_LOG_LEVEL=DEBUG + +# attach middleware-run to the entrypoint for instrumentation +CMD ["middleware-run","uwsgi", "--http", ":8000", "--module", "django_uwsgi_nginx_wsgi", "--static-map", "/static=/static"] diff --git a/django/django_uwsgi_nginx_otel/README.md b/django/django_uwsgi_nginx_otel/README.md new file mode 100644 index 0000000..871d1e3 --- /dev/null +++ b/django/django_uwsgi_nginx_otel/README.md @@ -0,0 +1,56 @@ +# Django Application with uWSGI, Nginx, and Middleware Integration Guide + +This project demonstrates how to set up a **Django** application with **uWSGI** and **Nginx**, along with **Middleware** integration for Application Performance Monitoring (APM). + +Follow the [Middleware APM setup documentation](https://docs.middleware.io/docs/apm-configuration/python/python-apm-setup) to integrate APM with your Django application. + +[](https://pypi.org/project/middleware-io/) + +| Traces | Metrics | Profiling | Logs (App/Custom) | +|:------:|:-------:|:---------:|:-----------------:| +| Yes | Yes | Yes | Yes/Yes | + +## Prerequisites + +Before running the project, ensure you have the **Middleware Host Agent** installed to view Python demo data on your dashboard. + +--- + +## Steps to Run the Project + +Create and Activate Virtual Environment: + +```python +python3 -m venv env +source env/bin/activate +``` + +Install Dependencies + +``` +pip install -r requirements.txt +``` + +Install OpenTelemetry instrument libraries + +```python +middleware-bootstrap -a install +``` + +Run the Application + +``` +docker compose up --build +``` + +Command for App Instrumentation + +```python +DJANGO_SETTINGS_MODULE="django_uwsgi_nginx_settings" middleware-run uwsgi --http :8000 --module django_uwsgi_nginx_wsgi --static-map /static=/static +``` + +If you are running this application in a serverless setup consider adding `MW_API_KEY` and `MW_TARGET` as mentioned in the command below : + +```python +MW_API_KEY=********** MW_TARGET=https://*****.middleware.io:443 DJANGO_SETTINGS_MODULE="django_uwsgi_nginx_settings" middleware-run uwsgi --http :8000 --module django_uwsgi_nginx_wsgi --static-map /static=/static +``` \ No newline at end of file diff --git a/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_settings.py b/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_settings.py new file mode 100755 index 0000000..25222c0 --- /dev/null +++ b/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_settings.py @@ -0,0 +1,36 @@ +SECRET_KEY = 'replace-with-a-secure-key' +DEBUG = True +ALLOWED_HOSTS = ['*'] +ROOT_URLCONF = 'django_uwsgi_nginx_urls' +WSGI_APPLICATION = 'django_uwsgi_nginx_wsgi.application' + +INSTALLED_APPS = [ + 'django.contrib.contenttypes', + 'django.contrib.staticfiles', + 'sample_app', +] + +MIDDLEWARE = [ + 'django.middleware.common.CommonMiddleware', +] + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [], + }, + }, +] + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': 'db.sqlite3', + } +} + +STATIC_URL = '/static/' +STATIC_ROOT = '/static/' diff --git a/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_urls.py b/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_urls.py new file mode 100755 index 0000000..5d9b6ba --- /dev/null +++ b/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_urls.py @@ -0,0 +1,5 @@ +from django.urls import path, include + +urlpatterns = [ + path('', include('sample_app.urls')), +] diff --git a/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_wsgi.py b/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_wsgi.py new file mode 100755 index 0000000..9c14905 --- /dev/null +++ b/django/django_uwsgi_nginx_otel/django_uwsgi_nginx_wsgi.py @@ -0,0 +1,26 @@ +import os +from django.core.wsgi import get_wsgi_application + +from uwsgidecorators import postfork + +from opentelemetry import trace +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +@postfork +def init_tracing(): + resource = Resource.create(attributes={ + "service.name": "django-uwsgi-otel" + }) + + trace.set_tracer_provider(TracerProvider(resource=resource)) + span_processor = BatchSpanProcessor( + OTLPSpanExporter(endpoint="http://localhost:9319") + ) + trace.get_tracer_provider().add_span_processor(span_processor) + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_uwsgi_nginx_settings') +application = get_wsgi_application() + diff --git a/django/django_uwsgi_nginx_otel/docker-compose.yml b/django/django_uwsgi_nginx_otel/docker-compose.yml new file mode 100755 index 0000000..7e28063 --- /dev/null +++ b/django/django_uwsgi_nginx_otel/docker-compose.yml @@ -0,0 +1,19 @@ +version: '3.8' + +services: + django: + build: . + volumes: + - ./static:/static + ports: + - "8000:8000" + + nginx: + image: nginx:latest + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + - ./static:/static + ports: + - "8080:80" + depends_on: + - django diff --git a/django/django_uwsgi_nginx_otel/manage.py b/django/django_uwsgi_nginx_otel/manage.py new file mode 100755 index 0000000..468980c --- /dev/null +++ b/django/django_uwsgi_nginx_otel/manage.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_uwsgi_nginx_settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) diff --git a/django/django_uwsgi_nginx_otel/nginx.conf b/django/django_uwsgi_nginx_otel/nginx.conf new file mode 100755 index 0000000..34e58da --- /dev/null +++ b/django/django_uwsgi_nginx_otel/nginx.conf @@ -0,0 +1,21 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + server { + listen 80; + + location /static/ { + alias /static/; + } + + location / { + proxy_pass http://django:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + } +} diff --git a/django/django_uwsgi_nginx_otel/requirements.txt b/django/django_uwsgi_nginx_otel/requirements.txt new file mode 100755 index 0000000..661524d --- /dev/null +++ b/django/django_uwsgi_nginx_otel/requirements.txt @@ -0,0 +1,4 @@ +django +uwsgi +opentelemetry-distro +opentelemetry-exporter-otlp \ No newline at end of file diff --git a/django/django_uwsgi_nginx_otel/sample_app/__init__.py b/django/django_uwsgi_nginx_otel/sample_app/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/django/django_uwsgi_nginx_otel/sample_app/migrations/__init__.py b/django/django_uwsgi_nginx_otel/sample_app/migrations/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/django/django_uwsgi_nginx_otel/sample_app/templates/index.html b/django/django_uwsgi_nginx_otel/sample_app/templates/index.html new file mode 100755 index 0000000..4e3355c --- /dev/null +++ b/django/django_uwsgi_nginx_otel/sample_app/templates/index.html @@ -0,0 +1,19 @@ + + +
+