Skip to content

Commit d4d0d8a

Browse files
authored
Merge branch 'main' into add-missing-pytyped-to-sdk
2 parents 9837531 + ff8a6c6 commit d4d0d8a

File tree

8 files changed

+208
-1
lines changed

8 files changed

+208
-1
lines changed

.github/workflows/release.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,65 @@ jobs:
5555
uses: pypa/gh-action-pypi-publish@897895f1e160c830e369f9779632ebc134688e1b
5656
with:
5757
repository-url: https://upload.pypi.org/legacy/
58+
59+
publish-docker:
60+
needs:
61+
- packages
62+
runs-on: ubuntu-latest
63+
permissions:
64+
attestations: write
65+
id-token: write
66+
contents: write
67+
env:
68+
DOCKER_IMAGE_NAME: docker.elastic.co/observability/elastic-otel-python
69+
steps:
70+
- uses: actions/checkout@v4
71+
72+
- name: Set up Docker Buildx
73+
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
74+
75+
- name: Log in to the Elastic Container registry
76+
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
77+
with:
78+
registry: ${{ secrets.ELASTIC_DOCKER_REGISTRY }}
79+
username: ${{ secrets.ELASTIC_DOCKER_USERNAME }}
80+
password: ${{ secrets.ELASTIC_DOCKER_PASSWORD }}
81+
82+
- uses: actions/download-artifact@v4
83+
with:
84+
name: packages
85+
path: dist
86+
87+
- name: Extract metadata (tags, labels)
88+
id: docker-meta
89+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
90+
with:
91+
images: ${{ env.DOCKER_IMAGE_NAME }}
92+
tags: |
93+
type=semver,pattern={{version}}
94+
# "edge" Docker tag on git push to default branch
95+
type=edge
96+
labels: |
97+
org.opencontainers.image.vendor=Elastic
98+
org.opencontainers.image.title=elastic-otel-python
99+
org.opencontainers.image.description=Elastic Distribution of OpenTelemetry Python
100+
101+
- name: Build and push image
102+
id: docker-push
103+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
104+
with:
105+
context: .
106+
platforms: linux/amd64,linux/arm64
107+
push: true
108+
file: operator/Dockerfile
109+
tags: ${{ steps.docker-meta.outputs.tags }}
110+
labels: ${{ steps.docker-meta.outputs.labels }}
111+
build-args: |
112+
DISTRO_DIR=./dist/
113+
114+
- name: generate build provenance (containers)
115+
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
116+
with:
117+
subject-name: "${{ env.DOCKER_IMAGE_NAME }}"
118+
subject-digest: ${{ steps.docker-push.outputs.digest }}
119+
push-to-registry: true

operator/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM docker.elastic.co/wolfi/python:3.12-dev@sha256:e90d34b9e1ecbf8b8092fe9037e86298dec69ec7e9f144a2575cd3db67cea2cb AS build
2+
3+
ENV LANG=C.UTF-8
4+
ENV PYTHONDONTWRITEBYTECODE=1
5+
ENV PYTHONUNBUFFERED=1
6+
7+
ARG DISTRO_DIR
8+
9+
COPY ${DISTRO_DIR} /opt/distro
10+
11+
WORKDIR /operator-build
12+
13+
ADD operator/requirements.txt .
14+
15+
RUN mkdir workspace
16+
17+
RUN pip install --no-cache-dir --target workspace /opt/distro/*.whl -r requirements.txt
18+
19+
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:6fbf07849a440c8dca9aa7e9cb56ed3ecaa9eb40f8a4f36b39393d7b32d78ecc
20+
21+
COPY --from=build /operator-build/workspace /autoinstrumentation
22+
23+
RUN chmod -R go+r /autoinstrumentation

operator/Dockerfile.alpine

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# This is a dockerfile for local testing
2+
FROM python:3.12-alpine AS build
3+
4+
ARG DISTRO_DIR
5+
6+
COPY ${DISTRO_DIR} /opt/distro
7+
8+
WORKDIR /operator-build
9+
10+
ADD operator/requirements.txt .
11+
12+
RUN mkdir workspace
13+
14+
RUN apk add gcc python3-dev musl-dev linux-headers
15+
16+
RUN pip install --target workspace /opt/distro/*.whl -r requirements.txt
17+
18+
FROM python:3.12-alpine
19+
20+
COPY --from=build /operator-build/workspace /autoinstrumentation
21+
22+
RUN chmod -R go+r /autoinstrumentation

operator/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Docker images for Kubernetes OpenTelemetry Operator
2+
3+
In this directory there are two *Dockerfile*s:
4+
- `Dockerfile`, that build the published image, based on Wolfi a glibc based image
5+
- `Dockerfile.alpine`, that can be used for building a testing musl based image
6+
7+
## Local build
8+
9+
From the root of this repository you can build and make available the image locally with:
10+
11+
```bash
12+
docker buildx build -f operator/Dockerfile --build-arg DISTRO_DIR=./dist -t elastic-otel-python-operator:test-wolfi --load .
13+
```

operator/requirements.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
opentelemetry-propagator-aws-xray==1.0.2
2+
opentelemetry-propagator-ot-trace==0.48b0
3+
4+
opentelemetry-instrumentation-aio-pika==0.48b0
5+
opentelemetry-instrumentation-aiohttp-client==0.48b0
6+
opentelemetry-instrumentation-aiohttp-server==0.48b0
7+
opentelemetry-instrumentation-aiopg==0.48b0
8+
opentelemetry-instrumentation-asgi==0.48b0
9+
opentelemetry-instrumentation-asyncio==0.48b0
10+
opentelemetry-instrumentation-asyncpg==0.48b0
11+
opentelemetry-instrumentation-aws-lambda==0.48b0
12+
opentelemetry-instrumentation-boto==0.48b0
13+
opentelemetry-instrumentation-boto3sqs==0.48b0
14+
opentelemetry-instrumentation-botocore==0.48b0
15+
opentelemetry-instrumentation-cassandra==0.48b0
16+
opentelemetry-instrumentation-celery==0.48b0
17+
opentelemetry-instrumentation-confluent-kafka==0.48b0
18+
opentelemetry-instrumentation-dbapi==0.48b0
19+
opentelemetry-instrumentation-django==0.48b0
20+
opentelemetry-instrumentation-elasticsearch==0.48b0
21+
opentelemetry-instrumentation-falcon==0.48b0
22+
opentelemetry-instrumentation-fastapi==0.48b0
23+
opentelemetry-instrumentation-flask==0.48b0
24+
opentelemetry-instrumentation-grpc==0.48b0
25+
opentelemetry-instrumentation-httpx==0.48b0
26+
opentelemetry-instrumentation-jinja2==0.48b0
27+
opentelemetry-instrumentation-kafka-python==0.48b0
28+
opentelemetry-instrumentation-logging==0.48b0
29+
opentelemetry-instrumentation-mysql==0.48b0
30+
opentelemetry-instrumentation-mysqlclient==0.48b0
31+
opentelemetry-instrumentation-pika==0.48b0
32+
opentelemetry-instrumentation-psycopg==0.48b0
33+
opentelemetry-instrumentation-psycopg2==0.48b0
34+
opentelemetry-instrumentation-pymemcache==0.48b0
35+
opentelemetry-instrumentation-pymongo==0.48b0
36+
opentelemetry-instrumentation-pymysql==0.48b0
37+
opentelemetry-instrumentation-pyramid==0.48b0
38+
opentelemetry-instrumentation-redis==0.48b0
39+
opentelemetry-instrumentation-remoulade==0.48b0
40+
opentelemetry-instrumentation-requests==0.48b0
41+
opentelemetry-instrumentation-sqlalchemy==0.48b0
42+
opentelemetry-instrumentation-sqlite3==0.48b0
43+
opentelemetry-instrumentation-starlette==0.48b0
44+
opentelemetry-instrumentation-system-metrics==0.48b0
45+
opentelemetry-instrumentation-threading==0.48b0
46+
opentelemetry-instrumentation-tornado==0.48b0
47+
opentelemetry-instrumentation-tortoiseorm==0.48b0
48+
opentelemetry-instrumentation-urllib==0.48b0
49+
opentelemetry-instrumentation-urllib3==0.48b0
50+
opentelemetry-instrumentation-wsgi==0.48b0

renovate.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3+
"extends": [
4+
"github>elastic/renovate-config:only-chainguard"
5+
]
6+
}

src/elasticotel/distro/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# limitations under the License.
1616

1717
import os
18+
from logging import getLogger
1819

1920
from opentelemetry.environment_variables import (
2021
OTEL_METRICS_EXPORTER,
@@ -36,13 +37,28 @@
3637
from elasticotel.distro.environment_variables import ELASTIC_OTEL_SYSTEM_METRICS_ENABLED
3738

3839

40+
logger = getLogger(__name__)
41+
42+
3943
class ElasticOpenTelemetryConfigurator(_OTelSDKConfigurator):
4044
pass
4145

4246

4347
class ElasticOpenTelemetryDistro(BaseDistro):
4448
def load_instrumentor(self, entry_point: EntryPoint, **kwargs):
45-
instrumentor_class: BaseInstrumentor = entry_point.load()
49+
# When running in the k8s operator loading of an instrumentor may fail because the environment
50+
# in which python extensions are built does not match the one from the running container.
51+
# There are at least two cases:
52+
# - different python version
53+
# - different kind of wheels, e.g. manylinux vs musllinux
54+
# To avoid the distro loading to fail catch ImportError here, that is the kind of exception we see
55+
# when loading shared objects or cython extensions fails.
56+
try:
57+
instrumentor_class: BaseInstrumentor = entry_point.load()
58+
except ImportError:
59+
logger.exception("Instrumenting of %s failed", entry_point.name)
60+
return
61+
4662
instrumentor_kwargs = {}
4763
if instrumentor_class == SystemMetricsInstrumentor:
4864
system_metrics_configuration = os.environ.get(ELASTIC_OTEL_SYSTEM_METRICS_ENABLED, "false")

tests/distro/test_distro.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,18 @@ def test_load_instrumentor_default_kwargs_for_instrumentors(self):
8383
distro.load_instrumentor(entryPoint_mock)
8484

8585
instrumentor_mock.assert_called_once_with()
86+
87+
def test_load_instrumentor_handles_import_error_from_instrumentor_loading(self):
88+
distro = ElasticOpenTelemetryDistro()
89+
entryPoint_mock = mock.Mock()
90+
entryPoint_mock.load.side_effect = ImportError
91+
92+
distro.load_instrumentor(entryPoint_mock)
93+
94+
def test_load_instrumentor_forwards_exceptions(self):
95+
distro = ElasticOpenTelemetryDistro()
96+
entryPoint_mock = mock.Mock()
97+
entryPoint_mock.load.side_effect = ValueError
98+
99+
with self.assertRaises(ValueError):
100+
distro.load_instrumentor(entryPoint_mock)

0 commit comments

Comments
 (0)