Skip to content

Commit 82900f6

Browse files
committed
Added support for PHP auto-instrumentation
1 parent e84193d commit 82900f6

29 files changed

+1210
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: "Publish PHP Auto-Instrumentation"
2+
3+
on:
4+
push:
5+
paths:
6+
- 'autoinstrumentation/php/**'
7+
- '.github/workflows/publish-autoinstrumentation-php.yaml'
8+
branches:
9+
- main
10+
pull_request:
11+
paths:
12+
- 'autoinstrumentation/php/**'
13+
- '.github/workflows/publish-autoinstrumentation-php.yaml'
14+
workflow_dispatch:
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
18+
cancel-in-progress: true
19+
20+
jobs:
21+
publish:
22+
runs-on: ubuntu-22.04
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Read version
28+
run: echo "VERSION=$(cat autoinstrumentation/php/version.txt)" >> $GITHUB_ENV
29+
30+
- name: Docker meta
31+
id: meta
32+
uses: docker/metadata-action@v5
33+
with:
34+
images: |
35+
otel/autoinstrumentation-php
36+
ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-php
37+
tags: |
38+
type=match,pattern=v(.*),group=1,value=v${{ env.VERSION }}
39+
40+
- name: Set up QEMU
41+
uses: docker/setup-qemu-action@v3
42+
43+
- name: Set up Docker Buildx
44+
uses: docker/setup-buildx-action@v3
45+
46+
- name: Cache Docker layers
47+
uses: actions/cache@v4
48+
with:
49+
path: /tmp/.buildx-cache
50+
key: ${{ runner.os }}-buildx-${{ github.sha }}
51+
restore-keys: |
52+
${{ runner.os }}-buildx-
53+
54+
- name: Log into Docker.io
55+
uses: docker/login-action@v3
56+
if: ${{ github.event_name == 'push' }}
57+
with:
58+
username: ${{ secrets.DOCKER_USERNAME }}
59+
password: ${{ secrets.DOCKER_PASSWORD }}
60+
61+
- name: Login to GitHub Package Registry
62+
uses: docker/login-action@v3
63+
if: ${{ github.event_name == 'push' }}
64+
with:
65+
registry: ghcr.io
66+
username: ${{ github.repository_owner }}
67+
password: ${{ secrets.GITHUB_TOKEN }}
68+
69+
- name: Build and push
70+
uses: docker/build-push-action@v6
71+
with:
72+
context: autoinstrumentation/php
73+
platforms: linux/amd64,linux/arm64
74+
push: ${{ github.event_name == 'push' }}
75+
build-args: version=${{ env.VERSION }}
76+
tags: ${{ steps.meta.outputs.tags }}
77+
labels: ${{ steps.meta.outputs.labels }}
78+
cache-from: type=local,src=/tmp/.buildx-cache
79+
cache-to: type=local,dest=/tmp/.buildx-cache

.github/workflows/publish-images.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ jobs:
3737
grep -v '\#' versions.txt | grep autoinstrumentation-python | awk -F= '{print "AUTO_INSTRUMENTATION_PYTHON_VERSION="$2}' >> $GITHUB_ENV
3838
grep -v '\#' versions.txt | grep autoinstrumentation-dotnet | awk -F= '{print "AUTO_INSTRUMENTATION_DOTNET_VERSION="$2}' >> $GITHUB_ENV
3939
grep -v '\#' versions.txt | grep autoinstrumentation-go | awk -F= '{print "AUTO_INSTRUMENTATION_GO_VERSION="$2}' >> $GITHUB_ENV
40+
grep -v '\#' versions.txt | grep autoinstrumentation-php | awk -F= '{print "AUTO_INSTRUMENTATION_PHP_VERSION="$2}' >> $GITHUB_ENV
4041
grep -v '\#' versions.txt | grep autoinstrumentation-apache-httpd | awk -F= '{print "AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION="$2}' >> $GITHUB_ENV
4142
grep -v '\#' versions.txt | grep autoinstrumentation-nginx | awk -F= '{print "AUTO_INSTRUMENTATION_NGINX_VERSION="$2}' >> $GITHUB_ENV
4243
echo "VERSION_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV

.github/workflows/publish-test-e2e-images.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ jobs:
5353
with:
5454
path: nodejs
5555
platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
56+
php:
57+
uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
58+
with:
59+
path: php
60+
platforms: linux/arm64,linux/amd64
5661
metrics-basic-auth:
5762
uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
5863
with:

Makefile

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ AUTO_INSTRUMENTATION_NODEJS_VERSION ?= "$(shell grep -v '\#' versions.txt | grep
1111
AUTO_INSTRUMENTATION_PYTHON_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-python | awk -F= '{print $$2}')"
1212
AUTO_INSTRUMENTATION_DOTNET_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-dotnet | awk -F= '{print $$2}')"
1313
AUTO_INSTRUMENTATION_GO_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-go | awk -F= '{print $$2}')"
14+
AUTO_INSTRUMENTATION_PHP_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-php | awk -F= '{print $$2}')"
1415
AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-apache-httpd | awk -F= '{print $$2}')"
1516
AUTO_INSTRUMENTATION_NGINX_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-nginx | awk -F= '{print $$2}')"
1617
COMMON_LDFLAGS ?= -s -w
17-
OPERATOR_LDFLAGS ?= -X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.otelCol=${OTELCOL_VERSION} -X ${VERSION_PKG}.targetAllocator=${TARGETALLOCATOR_VERSION} -X ${VERSION_PKG}.operatorOpAMPBridge=${OPERATOR_OPAMP_BRIDGE_VERSION} -X ${VERSION_PKG}.autoInstrumentationJava=${AUTO_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationNodeJS=${AUTO_INSTRUMENTATION_NODEJS_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${AUTO_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.autoInstrumentationDotNet=${AUTO_INSTRUMENTATION_DOTNET_VERSION} -X ${VERSION_PKG}.autoInstrumentationGo=${AUTO_INSTRUMENTATION_GO_VERSION} -X ${VERSION_PKG}.autoInstrumentationApacheHttpd=${AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION} -X ${VERSION_PKG}.autoInstrumentationNginx=${AUTO_INSTRUMENTATION_NGINX_VERSION}
18+
OPERATOR_LDFLAGS ?= -X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.otelCol=${OTELCOL_VERSION} -X ${VERSION_PKG}.targetAllocator=${TARGETALLOCATOR_VERSION} -X ${VERSION_PKG}.operatorOpAMPBridge=${OPERATOR_OPAMP_BRIDGE_VERSION} -X ${VERSION_PKG}.autoInstrumentationJava=${AUTO_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationNodeJS=${AUTO_INSTRUMENTATION_NODEJS_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${AUTO_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.autoInstrumentationDotNet=${AUTO_INSTRUMENTATION_DOTNET_VERSION} -X ${VERSION_PKG}.autoInstrumentationPHP=${AUTO_INSTRUMENTATION_PHP_VERSION} -X ${VERSION_PKG}.autoInstrumentationGo=${AUTO_INSTRUMENTATION_GO_VERSION} -X ${VERSION_PKG}.autoInstrumentationApacheHttpd=${AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION} -X ${VERSION_PKG}.autoInstrumentationNginx=${AUTO_INSTRUMENTATION_NGINX_VERSION}
1819
ARCH ?= $(shell go env GOARCH)
1920
ifeq ($(shell uname), Darwin)
2021
SED_INPLACE := sed -i ''
@@ -614,6 +615,7 @@ chlog-insert-components:
614615
@echo "* [OpenTelemetry Contrib - v${OTELCOL_VERSION}](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v${OTELCOL_VERSION})" >>components.md
615616
@echo "* [Java auto-instrumentation - v${AUTO_INSTRUMENTATION_JAVA_VERSION}](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v${AUTO_INSTRUMENTATION_JAVA_VERSION})" >>components.md
616617
@echo "* [.NET auto-instrumentation - v${AUTO_INSTRUMENTATION_DOTNET_VERSION}](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/tag/v${AUTO_INSTRUMENTATION_DOTNET_VERSION})" >>components.md
618+
@echo "* [PHP auto-instrumentation - v${AUTO_INSTRUMENTATION_PHP_VERSION}](https://github.com/open-telemetry/opentelemetry-php-instrumentation/releases/tag/v${AUTO_INSTRUMENTATION_PHP_VERSION})" >>components.md
617619
@echo "* [Node.JS - v${AUTO_INSTRUMENTATION_NODEJS_VERSION}](https://github.com/open-telemetry/opentelemetry-js/releases/tag/experimental%2Fv${AUTO_INSTRUMENTATION_NODEJS_VERSION})" >>components.md
618620
@echo "* [Python - v${AUTO_INSTRUMENTATION_PYTHON_VERSION}](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v${AUTO_INSTRUMENTATION_PYTHON_VERSION})" >>components.md
619621
@echo "* [Go - ${AUTO_INSTRUMENTATION_GO_VERSION}](https://github.com/open-telemetry/opentelemetry-go-instrumentation/releases/tag/${AUTO_INSTRUMENTATION_GO_VERSION})" >>components.md

README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ kubectl patch serviceaccount <service-account-name> -p '{"imagePullSecrets": [{"
219219

220220
### OpenTelemetry auto-instrumentation injection
221221

222-
The operator can inject and configure OpenTelemetry auto-instrumentation libraries. Currently Apache HTTPD, DotNet, Go, Java, Nginx, NodeJS and Python are supported.
222+
The operator can inject and configure OpenTelemetry auto-instrumentation libraries. Currently Apache HTTPD, DotNet, Go, Java, Nginx, NodeJS, Python and PHP are supported.
223223

224224
To use auto-instrumentation, configure an `Instrumentation` resource with the configuration for the SDK and instrumentation.
225225

@@ -260,6 +260,13 @@ spec:
260260
# so data must be sent to 4318 instead of 4317.
261261
- name: OTEL_EXPORTER_OTLP_ENDPOINT
262262
value: http://otel-collector:4318
263+
php:
264+
env:
265+
# Required if endpoint is set to 4317.
266+
# PHP autoinstrumentation uses http/proto by default
267+
# so data must be sent to 4318 instead of 4317.
268+
- name: OTEL_EXPORTER_OTLP_ENDPOINT
269+
value: http://otel-collector:4318
263270
EOF
264271
```
265272

@@ -307,6 +314,12 @@ instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-x64" # for Lin
307314
instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64" # for Linux musl based images
308315
```
309316

317+
PHP:
318+
319+
```bash
320+
instrumentation.opentelemetry.io/inject-php: "true"
321+
```
322+
310323
Go:
311324

312325
Go auto-instrumentation also honors an annotation that will be used to set the [OTEL_GO_AUTO_TARGET_EXE env var](https://github.com/open-telemetry/opentelemetry-go-instrumentation/blob/main/docs/how-it-works.md).
@@ -424,6 +437,12 @@ DotNet:
424437
instrumentation.opentelemetry.io/dotnet-container-names: "dotnet1,dotnet2"
425438
```
426439

440+
PHP:
441+
442+
```bash
443+
instrumentation.opentelemetry.io/php-container-names: "php1,php2"
444+
```
445+
427446
Go:
428447

429448
```bash
@@ -510,6 +529,8 @@ spec:
510529
image: your-customized-auto-instrumentation-image:python
511530
dotnet:
512531
image: your-customized-auto-instrumentation-image:dotnet
532+
php:
533+
image: your-customized-auto-instrumentation-image:php
513534
go:
514535
image: your-customized-auto-instrumentation-image:go
515536
apacheHttpd:
@@ -584,6 +605,7 @@ Language support can be disabled by passing the flag with a value of `false`.
584605
| NodeJS | `enable-nodejs-instrumentation` | `true` |
585606
| Python | `enable-python-instrumentation` | `true` |
586607
| DotNet | `enable-dotnet-instrumentation` | `true` |
608+
| PHP | `enable-php-instrumentation` | `true` |
587609
| ApacheHttpD | `enable-apache-httpd-instrumentation` | `true` |
588610
| Go | `enable-go-instrumentation` | `false` |
589611
| Nginx | `enable-nginx-instrumentation` | `false` |

apis/v1alpha1/instrumentation_types.go

+24
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ type InstrumentationSpec struct {
7272
// +optional
7373
Go Go `json:"go,omitempty"`
7474

75+
// PHP defines configuration for PHP auto-instrumentation.
76+
// +optional
77+
PHP PHP `json:"php,omitempty"`
78+
7579
// ApacheHttpd defines configuration for Apache HTTPD auto-instrumentation.
7680
// +optional
7781
ApacheHttpd ApacheHttpd `json:"apacheHttpd,omitempty"`
@@ -243,6 +247,26 @@ type Go struct {
243247
Resources corev1.ResourceRequirements `json:"resourceRequirements,omitempty"`
244248
}
245249

250+
// PHP defines PHP SDK and instrumentation configuration.
251+
type PHP struct {
252+
// Image is a container image with PHP SDK and auto-instrumentation.
253+
// +optional
254+
Image string `json:"image,omitempty"`
255+
256+
// VolumeSizeLimit defines size limit for volume used for auto-instrumentation.
257+
// The default size is 200Mi.
258+
VolumeSizeLimit *resource.Quantity `json:"volumeLimitSize,omitempty"`
259+
260+
// Env defines PHP specific env vars. There are four layers for env vars' definitions and
261+
// the precedence order is: `original container env vars` > `language specific env vars` > `common env vars` > `instrument spec configs' vars`.
262+
// If the former var had been defined, then the other vars would be ignored.
263+
// +optional
264+
Env []corev1.EnvVar `json:"env,omitempty"`
265+
// Resources describes the compute resource requirements.
266+
// +optional
267+
Resources corev1.ResourceRequirements `json:"resourceRequirements,omitempty"`
268+
}
269+
246270
// ApacheHttpd defines Apache SDK and instrumentation configuration.
247271
type ApacheHttpd struct {
248272
// Image is a container image with Apache SDK and auto-instrumentation.

apis/v1alpha1/instrumentation_webhook.go

+16
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@ func (w InstrumentationWebhook) defaulter(r *Instrumentation) error {
151151
corev1.ResourceMemory: resource.MustParse("128Mi"),
152152
}
153153
}
154+
if r.Spec.PHP.Image == "" {
155+
r.Spec.PHP.Image = w.cfg.AutoInstrumentationPHPImage()
156+
}
157+
if r.Spec.PHP.Resources.Limits == nil {
158+
r.Spec.PHP.Resources.Limits = corev1.ResourceList{
159+
corev1.ResourceCPU: resource.MustParse("500m"),
160+
corev1.ResourceMemory: resource.MustParse("128Mi"),
161+
}
162+
}
163+
if r.Spec.PHP.Resources.Requests == nil {
164+
r.Spec.PHP.Resources.Requests = corev1.ResourceList{
165+
corev1.ResourceCPU: resource.MustParse("50m"),
166+
corev1.ResourceMemory: resource.MustParse("128Mi"),
167+
}
168+
}
154169
if r.Spec.Go.Image == "" {
155170
r.Spec.Go.Image = w.cfg.AutoInstrumentationGoImage()
156171
}
@@ -201,6 +216,7 @@ func (w InstrumentationWebhook) defaulter(r *Instrumentation) error {
201216
r.Annotations[constants.AnnotationDefaultAutoInstrumentationNodeJS] = w.cfg.AutoInstrumentationNodeJSImage()
202217
r.Annotations[constants.AnnotationDefaultAutoInstrumentationPython] = w.cfg.AutoInstrumentationPythonImage()
203218
r.Annotations[constants.AnnotationDefaultAutoInstrumentationDotNet] = w.cfg.AutoInstrumentationDotNetImage()
219+
r.Annotations[constants.AnnotationDefaultAutoInstrumentationPHP] = w.cfg.AutoInstrumentationPHPImage()
204220
r.Annotations[constants.AnnotationDefaultAutoInstrumentationGo] = w.cfg.AutoInstrumentationGoImage()
205221
r.Annotations[constants.AnnotationDefaultAutoInstrumentationApacheHttpd] = w.cfg.AutoInstrumentationApacheHttpdImage()
206222
r.Annotations[constants.AnnotationDefaultAutoInstrumentationNginx] = w.cfg.AutoInstrumentationNginxImage()

apis/v1alpha1/instrumentation_webhook_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func TestInstrumentationDefaultingWebhook(t *testing.T) {
3232
config.WithAutoInstrumentationNodeJSImage("nodejs-img:1"),
3333
config.WithAutoInstrumentationPythonImage("python-img:1"),
3434
config.WithAutoInstrumentationDotNetImage("dotnet-img:1"),
35+
config.WithAutoInstrumentationPHPImage("php-img:1"),
3536
config.WithAutoInstrumentationApacheHttpdImage("apache-httpd-img:1"),
3637
config.WithAutoInstrumentationNginxImage("nginx-img:1"),
3738
),
@@ -41,6 +42,7 @@ func TestInstrumentationDefaultingWebhook(t *testing.T) {
4142
assert.Equal(t, "nodejs-img:1", inst.Spec.NodeJS.Image)
4243
assert.Equal(t, "python-img:1", inst.Spec.Python.Image)
4344
assert.Equal(t, "dotnet-img:1", inst.Spec.DotNet.Image)
45+
assert.Equal(t, "php-img:1", inst.Spec.PHP.Image)
4446
assert.Equal(t, "apache-httpd-img:1", inst.Spec.ApacheHttpd.Image)
4547
assert.Equal(t, "nginx-img:1", inst.Spec.Nginx.Image)
4648
}

autoinstrumentation/php/Dockerfile

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# To build one auto-instrumentation image for php, please:
2+
# - Download your php auto-instrumentation artefacts to `/autoinstrumentation` directory. This is required as when instrumenting the pod,
3+
# one init container will be created to copy the files to your app's container.
4+
# - Grant the necessary access to the files in the `/autoinstrumentation` directory.
5+
# - Following environment variables are injected to the application container to enable the auto-instrumentation.
6+
# PHP_INI_SCAN_DIR=:/otel-auto-instrumentation-php/php_ini_scan_dir
7+
# OTEL_PHP_AUTOLOAD_ENABLED=true
8+
# - For auto-instrumentation by container injection, the Linux command cp is
9+
# used and must be availabe in the image.
10+
11+
FROM php-cli as staging
12+
13+
ARG auto_instrumentation_version
14+
15+
WORKDIR /autoinstrumentation
16+
17+
RUN pecl install opentelemetry-$auto_instrumentation_version
18+
RUN mkdir lib
19+
RUN cp /usr/local/lib/php/extensions/no-debug-non-zts-20230831/opentelemetry.so lib/
20+
RUN mkdir php_ini_scan_dir
21+
COPY php_config_opentelemetry_extension.ini php_ini_scan_dir/php_config_opentelemetry_extension.ini
22+
23+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
24+
ADD composer.json .
25+
RUN composer install
26+
27+
FROM busybox
28+
29+
COPY --from=staging /autoinstrumentation /autoinstrumentation
30+
31+
RUN chmod -R go+r /autoinstrumentation

autoinstrumentation/php/composer.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "open-telemetry/operator-autoinstrumentation-php",
3+
"description": "OpenTelemetry PHP auto-instrumentation packages to include in the image used by Operator for Kubernetes",
4+
"keywords": [ "open telemetry", "OTel", "apm", "tracing", "apm-agent" ],
5+
"type": "project",
6+
"require": {
7+
"open-telemetry/exporter-otlp": "1.1.0",
8+
"open-telemetry/opentelemetry-auto-guzzle": "1.0.0",
9+
"open-telemetry/opentelemetry-auto-http-async": "1.0.1",
10+
"open-telemetry/opentelemetry-auto-laravel": "0.0.28",
11+
"open-telemetry/opentelemetry-auto-pdo": "0.0.15",
12+
"open-telemetry/opentelemetry-auto-psr15": "1.0.6",
13+
"open-telemetry/opentelemetry-auto-psr18": "1.0.4",
14+
"open-telemetry/opentelemetry-auto-slim": "1.0.7",
15+
"open-telemetry/opentelemetry-auto-symfony": "1.0.0beta29",
16+
"open-telemetry/opentelemetry-auto-wordpress": "0.0.16",
17+
"open-telemetry/sdk": "1.1.0",
18+
"php-http/guzzle7-adapter": "1.0.0"
19+
},
20+
"provide": {
21+
"laravel/framework": "*",
22+
"psr/http-client": "*",
23+
"psr/http-server-middleware": "*",
24+
"slim/slim": "*",
25+
"symfony/http-client-contracts": "*",
26+
"symfony/http-kernel": "*"
27+
},
28+
"config": {
29+
"process-timeout": 0,
30+
"sort-packages": true,
31+
"allow-plugins": {
32+
"dealerdirect/phpcodesniffer-composer-installer": true,
33+
"php-http/discovery": true
34+
}
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extension=opentelemetry.so

autoinstrumentation/php/version.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1.1.0

0 commit comments

Comments
 (0)