Skip to content

Commit

Permalink
insert CWD to sys.path for Django to find the application directory (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
srprash authored May 8, 2024
1 parent a4a0c33 commit e83e336
Showing 1 changed file with 19 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import os
import sys
from logging import Logger, getLogger

from amazon.opentelemetry.distro.patches._instrumentation_patch import apply_instrumentation_patches
from opentelemetry.distro import OpenTelemetryDistro
Expand All @@ -10,6 +12,8 @@
OTEL_EXPORTER_OTLP_PROTOCOL,
)

_logger: Logger = getLogger(__name__)


class AwsOpenTelemetryDistro(OpenTelemetryDistro):
def _configure(self, **kwargs):
Expand All @@ -36,6 +40,21 @@ def _configure(self, **kwargs):
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION environment variable. Need to work with upstream to
make it to be configurable.
"""

# Issue: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2495
# mimicking what is done here: https://tinyurl.com/54mvzmte
# For handling applications like django running in containers, we are setting the current working directory
# to the sys.path for the django application to find its executables.
#
# Note that we are updating the sys.path and not the PYTHONPATH env var, because once sys.path is
# loaded upon process start, it doesn't refresh from the PYTHONPATH value.
#
# To be removed once the issue has been fixed in https://github.com/open-telemetry/opentelemetry-python-contrib
cwd_path = os.getcwd()
_logger.debug("Current working directory path: %s", cwd_path)
if cwd_path not in sys.path:
sys.path.insert(0, cwd_path)

os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, "http/protobuf")

super(AwsOpenTelemetryDistro, self)._configure()
Expand Down

0 comments on commit e83e336

Please sign in to comment.