diff --git a/README.md b/README.md index 3c02834..17e6a8f 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Looking for the containers? [Head over to the Github Container Registry](https:/ * [PRE_START_PATH](#pre_start_path) * [RELOAD](#reload) * [RELOAD_SIGINT_TIMEOUT](#reload_sigint_timeout) + * [OTEL_ENABLED](#otel_enabled) * [Python Versions](#python-versions) * [Image Variants](#image-variants) * [Full](#full) @@ -240,6 +241,10 @@ When `RELOAD` is set this value determines how long to wait for the worker to gr Defaults to 30 seconds. +### `OTEL_ENABLED` + +When set to `true` the container will enable OpenTelemetry (OTel) instrumentation for the Celery worker. This is done by installing the `opentelemetry-distro` and `opentelemetry-exporter-otlp` packages at startup and enabling auto-instrumentation. Any additional instrumentation packages (e.g. `opentelemetry-instrumentation-celery`) must be installed separately. + ## Python Versions This project actively supports these Python versions: diff --git a/assets/entrypoint.sh b/assets/entrypoint.sh index 621f064..de31edf 100755 --- a/assets/entrypoint.sh +++ b/assets/entrypoint.sh @@ -30,9 +30,15 @@ fi # End of tiangolo/gunicorn-uvicorn-docker block # +if [[ "$OTEL_ENABLED" == "true" ]]; then + OTEL_CMD="opentelemetry-instrument" + echo "OpenTelemetry auto-instrumentation enabled" +else + OTEL_CMD="" +fi if [[ "$ENABLE_BEAT" == "true" ]]; then - COMMAND="python -m celery -A $APP_MODULE beat -s /var/celery/celerybeat-schedule" + COMMAND="$OTEL_CMD python -m celery -A $APP_MODULE beat -s /var/celery/celerybeat-schedule" else POOL=${POOL:-prefork} if [[ "$POOL" = "gevent" ]] || [[ "$POOL" = "eventlet" ]] ; then @@ -40,7 +46,7 @@ else else CONCURRENCY=${CONCURRENCY:-2} fi - COMMAND="python -m celery -A $APP_MODULE worker \ + COMMAND="$OTEL_CMD python -m celery -A $APP_MODULE worker \ --pool=$POOL \ --concurrency=$CONCURRENCY \ --prefetch-multiplier=${PREFETCH_MULTIPLIER:-4}" diff --git a/dockerfile b/dockerfile index 6fcde54..c09bd58 100644 --- a/dockerfile +++ b/dockerfile @@ -1,6 +1,7 @@ ARG python_version=3.9 ARG build_target=$python_version ARG publish_target=$python_version +ARG OTEL_ENABLED=false FROM python:$build_target as Builder @@ -26,6 +27,9 @@ ENV PATH="/root/.cargo/bin:${PATH}" RUN bash -c 'if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]] ; then pip install $package==$package_version ; fi' RUN bash -c 'if [[ "$TARGETPLATFORM" != "linux/arm/v7" ]] ; then pip install $package==$package_version watchfiles>=0.15 ; fi' +# Install OpenTelemetry packages +RUN pip install opentelemetry-distro opentelemetry-exporter-otlp && opentelemetry-bootstrap -a install + # Build our actual container now. FROM python:$publish_target @@ -36,9 +40,11 @@ ARG python_version ARG package ARG maintainer="" ARG TARGETPLATFORM="" +ARG OTEL_ENABLED=false LABEL python=$python_version LABEL package=$package LABEL maintainer=$maintainer +LABEL otel_enabled=$OTEL_ENABLED LABEL org.opencontainers.image.description="python:$publish_target $package:$package_version $TARGETPLATFORM" # Used for Celery Beat. @@ -48,6 +54,9 @@ RUN mkdir /var/celery # Copy all of the python files built in the Builder container into this smaller container. COPY --from=Builder /usr/local/lib/python$python_version /usr/local/lib/python$python_version +# Copy binaries (e.g. opentelemetry-instrument) installed by pip in the Builder stage. +COPY --from=Builder /usr/local/bin /usr/local/bin + # Entrypoint Script COPY ./assets/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh