Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django app on K8s crashes when auto-instrumented via the opentelemetry-operator without explicitly setting the PYTHONPATH and DJANGO_SETTINGS_MODULE #2495

Open
srprash opened this issue May 3, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@srprash
Copy link

srprash commented May 3, 2024

Describe your environment Describe any aspect of your environment relevant to the problem, including your Python version, platform, version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main.

  • Python version: 3.11
  • Platform: Kubernetes
  • Installed dependencies:
    • Django~=5.0.4
    • requests==2.31.0
  • Hosting: hosting locally on minikube, but same issue when hosted on AWS EKS

Steps to reproduce
Sample app code is here: https://github.com/srprash/otel-python-k8s-samples/tree/main/django

  1. Install Docker and Minikube, and run both.
  2. Run eval $(minikube docker-env) so that minikube can use the docker images from local repository.
  3. Build the application docker image using docker build -t django-app .
  4. Deploy the application to minikube using kubectl apply -f k8s/deployment.yaml and kubectl apply -f k8s/service.yaml
  5. Enable port-forwarding kubectl port-forward svc/django-service 8000
  6. Make a request to the application on http://127.0.0.1:8000/outgoing-http-call endpoint

What is the expected behavior?
What did you expect to see?

  • The application should run without an issues and produce a server span for the incoming request and a client span for the outgoing http request

What is the actual behavior?
What did you see instead?

  • The application fails to start with the error:
    Defaulted container "django-app" out of: django-app, opentelemetry-auto-instrumentation-python (init)
    CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
    
  • When I uncomment these lines (that is, explicitly set the PYTHONPATH and DJANGO_SETTINGS_MODULE), only then the application works correctly and is instrumented.

Additional context

@srprash srprash added the bug Something isn't working label May 3, 2024
@srprash
Copy link
Author

srprash commented May 3, 2024

This issue was also discussed in the Python SIG meeting on May 02, 2024. Notes: https://docs.google.com/document/d/1CIMGoIOZ-c3-igzbd6_Pnxx1SjAkjwqoYSUWxPY8XIs/edit

Between the meeting and discussion on this slack thread, it seems like the operator login needs to be fixed on how the pythonpath is handled.

@srprash
Copy link
Author

srprash commented May 3, 2024

From the SIG meeting discussion, tagging @jeremydvoss since he encountered this issue as well and to take a look.

srprash added a commit to aws-observability/aws-otel-python-instrumentation that referenced this issue May 8, 2024
…179)

*Issue #, if available:*
open-telemetry/opentelemetry-python-contrib#2495
The issue is that users on K8s/EKS/ECS explicitly need to set their
Django application container's working directory in the `PYTHONPATH`
environment variable ([operator
code](https://github.com/open-telemetry/opentelemetry-operator/blob/d42a0ce1166efe86c95f85268f265e338d0002f8/pkg/instrumentation/python.go#L55-L63)
that handles the `PYTHONPATH`), otherwise the application fails to start
with error messages related to the Django's settings module.

*Analysis:*
Python auto-instrumentation using the `opentelemetry-instrument` command
doesn't have this issue, which is I believe is because of [this specific
handling of Django app current
directory](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/1ee7261ea7117fbd22e2262e488402213a874125/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/__init__.py#L98-L102)
in the auto-instrumentation startup. Since [this script is only run when
using the `opentelemetry-instrument`
command](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/1ee7261ea7117fbd22e2262e488402213a874125/opentelemetry-instrumentation/pyproject.toml#L34),
auto-instrumentation done by the operator (using the
[sitecustomize](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py)
I believe) doesn't set the current working directory in the PYTHONPATH.

*Description of changes:*
Solution is to insert the current working directory to the `sys.path`
within the auto-instrumentation so that Django can find the application
folder. We are adding to the `sys.path` and not `PYTHONPATH` because at
this point the python process has already started and mutations to
`PYTHONPATH` doesn't reflect in the `sys.path` which is what Django
uses.

*Testing:*
Manually tested by deploying a [Django sample
application](https://github.com/srprash/otel-python-k8s-samples/tree/main/django)
to minikube without setting the `PYTHONPATH` in the container
environment.



By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant