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

Added support for PHP auto-instrumentation #3331

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/publish-autoinstrumentation-php.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: "Publish PHP Auto-Instrumentation"

on:
push:
paths:
- 'autoinstrumentation/php/**'
- '.github/workflows/publish-autoinstrumentation-php.yaml'
branches:
- main
pull_request:
paths:
- 'autoinstrumentation/php/**'
- '.github/workflows/publish-autoinstrumentation-php.yaml'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
publish:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4

- name: Read version
run: echo "VERSION=$(cat autoinstrumentation/php/version.txt)" >> $GITHUB_ENV

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
otel/autoinstrumentation-php
ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-php
tags: |
type=match,pattern=v(.*),group=1,value=v${{ env.VERSION }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-

- name: Log into Docker.io
uses: docker/login-action@v3
if: ${{ github.event_name == 'push' }}
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Login to GitHub Package Registry
uses: docker/login-action@v3
if: ${{ github.event_name == 'push' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: autoinstrumentation/php
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name == 'push' }}
build-args: version=${{ env.VERSION }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
1 change: 1 addition & 0 deletions .github/workflows/publish-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
grep -v '\#' versions.txt | grep autoinstrumentation-python | awk -F= '{print "AUTO_INSTRUMENTATION_PYTHON_VERSION="$2}' >> $GITHUB_ENV
grep -v '\#' versions.txt | grep autoinstrumentation-dotnet | awk -F= '{print "AUTO_INSTRUMENTATION_DOTNET_VERSION="$2}' >> $GITHUB_ENV
grep -v '\#' versions.txt | grep autoinstrumentation-go | awk -F= '{print "AUTO_INSTRUMENTATION_GO_VERSION="$2}' >> $GITHUB_ENV
grep -v '\#' versions.txt | grep autoinstrumentation-php | awk -F= '{print "AUTO_INSTRUMENTATION_PHP_VERSION="$2}' >> $GITHUB_ENV
grep -v '\#' versions.txt | grep autoinstrumentation-apache-httpd | awk -F= '{print "AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION="$2}' >> $GITHUB_ENV
grep -v '\#' versions.txt | grep autoinstrumentation-nginx | awk -F= '{print "AUTO_INSTRUMENTATION_NGINX_VERSION="$2}' >> $GITHUB_ENV
echo "VERSION_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/publish-test-e2e-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ jobs:
with:
path: nodejs
platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
php:
uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
with:
path: php
platforms: linux/arm64,linux/amd64
metrics-basic-auth:
uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
with:
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ AUTO_INSTRUMENTATION_NODEJS_VERSION ?= "$(shell grep -v '\#' versions.txt | grep
AUTO_INSTRUMENTATION_PYTHON_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-python | awk -F= '{print $$2}')"
AUTO_INSTRUMENTATION_DOTNET_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-dotnet | awk -F= '{print $$2}')"
AUTO_INSTRUMENTATION_GO_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-go | awk -F= '{print $$2}')"
AUTO_INSTRUMENTATION_PHP_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-php | awk -F= '{print $$2}')"
AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-apache-httpd | awk -F= '{print $$2}')"
AUTO_INSTRUMENTATION_NGINX_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-nginx | awk -F= '{print $$2}')"
COMMON_LDFLAGS ?= -s -w
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}
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}
ARCH ?= $(shell go env GOARCH)
ifeq ($(shell uname), Darwin)
SED_INPLACE := sed -i ''
Expand Down Expand Up @@ -614,6 +615,7 @@ chlog-insert-components:
@echo "* [OpenTelemetry Contrib - v${OTELCOL_VERSION}](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v${OTELCOL_VERSION})" >>components.md
@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
@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
@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
@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
@echo "* [Python - v${AUTO_INSTRUMENTATION_PYTHON_VERSION}](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v${AUTO_INSTRUMENTATION_PYTHON_VERSION})" >>components.md
@echo "* [Go - ${AUTO_INSTRUMENTATION_GO_VERSION}](https://github.com/open-telemetry/opentelemetry-go-instrumentation/releases/tag/${AUTO_INSTRUMENTATION_GO_VERSION})" >>components.md
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ kubectl patch serviceaccount <service-account-name> -p '{"imagePullSecrets": [{"

### OpenTelemetry auto-instrumentation injection

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

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

Expand Down Expand Up @@ -260,6 +260,13 @@ spec:
# so data must be sent to 4318 instead of 4317.
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://otel-collector:4318
php:
env:
# Required if endpoint is set to 4317.
# PHP autoinstrumentation uses http/proto by default
# so data must be sent to 4318 instead of 4317.
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://otel-collector:4318
EOF
```

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

PHP:

```bash
instrumentation.opentelemetry.io/inject-php: "true"
```

Go:

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).
Expand Down Expand Up @@ -424,6 +437,12 @@ DotNet:
instrumentation.opentelemetry.io/dotnet-container-names: "dotnet1,dotnet2"
```

PHP:

```bash
instrumentation.opentelemetry.io/php-container-names: "php1,php2"
```

Go:

```bash
Expand Down Expand Up @@ -510,6 +529,8 @@ spec:
image: your-customized-auto-instrumentation-image:python
dotnet:
image: your-customized-auto-instrumentation-image:dotnet
php:
image: your-customized-auto-instrumentation-image:php
go:
image: your-customized-auto-instrumentation-image:go
apacheHttpd:
Expand Down Expand Up @@ -584,6 +605,7 @@ Language support can be disabled by passing the flag with a value of `false`.
| NodeJS | `enable-nodejs-instrumentation` | `true` |
| Python | `enable-python-instrumentation` | `true` |
| DotNet | `enable-dotnet-instrumentation` | `true` |
| PHP | `enable-php-instrumentation` | `true` |
| ApacheHttpD | `enable-apache-httpd-instrumentation` | `true` |
| Go | `enable-go-instrumentation` | `false` |
| Nginx | `enable-nginx-instrumentation` | `false` |
Expand Down
24 changes: 24 additions & 0 deletions apis/v1alpha1/instrumentation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ type InstrumentationSpec struct {
// +optional
Go Go `json:"go,omitempty"`

// PHP defines configuration for PHP auto-instrumentation.
// +optional
PHP PHP `json:"php,omitempty"`

// ApacheHttpd defines configuration for Apache HTTPD auto-instrumentation.
// +optional
ApacheHttpd ApacheHttpd `json:"apacheHttpd,omitempty"`
Expand Down Expand Up @@ -243,6 +247,26 @@ type Go struct {
Resources corev1.ResourceRequirements `json:"resourceRequirements,omitempty"`
}

// PHP defines PHP SDK and instrumentation configuration.
type PHP struct {
// Image is a container image with PHP SDK and auto-instrumentation.
// +optional
Image string `json:"image,omitempty"`

// VolumeSizeLimit defines size limit for volume used for auto-instrumentation.
// The default size is 200Mi.
VolumeSizeLimit *resource.Quantity `json:"volumeLimitSize,omitempty"`

// Env defines PHP specific env vars. There are four layers for env vars' definitions and
// the precedence order is: `original container env vars` > `language specific env vars` > `common env vars` > `instrument spec configs' vars`.
// If the former var had been defined, then the other vars would be ignored.
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`
// Resources describes the compute resource requirements.
// +optional
Resources corev1.ResourceRequirements `json:"resourceRequirements,omitempty"`
}

// ApacheHttpd defines Apache SDK and instrumentation configuration.
type ApacheHttpd struct {
// Image is a container image with Apache SDK and auto-instrumentation.
Expand Down
16 changes: 16 additions & 0 deletions apis/v1alpha1/instrumentation_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,21 @@ func (w InstrumentationWebhook) defaulter(r *Instrumentation) error {
corev1.ResourceMemory: resource.MustParse("128Mi"),
}
}
if r.Spec.PHP.Image == "" {
r.Spec.PHP.Image = w.cfg.AutoInstrumentationPHPImage()
}
if r.Spec.PHP.Resources.Limits == nil {
r.Spec.PHP.Resources.Limits = corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("500m"),
corev1.ResourceMemory: resource.MustParse("128Mi"),
}
}
if r.Spec.PHP.Resources.Requests == nil {
r.Spec.PHP.Resources.Requests = corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("50m"),
corev1.ResourceMemory: resource.MustParse("128Mi"),
}
}
if r.Spec.Go.Image == "" {
r.Spec.Go.Image = w.cfg.AutoInstrumentationGoImage()
}
Expand Down Expand Up @@ -201,6 +216,7 @@ func (w InstrumentationWebhook) defaulter(r *Instrumentation) error {
r.Annotations[constants.AnnotationDefaultAutoInstrumentationNodeJS] = w.cfg.AutoInstrumentationNodeJSImage()
r.Annotations[constants.AnnotationDefaultAutoInstrumentationPython] = w.cfg.AutoInstrumentationPythonImage()
r.Annotations[constants.AnnotationDefaultAutoInstrumentationDotNet] = w.cfg.AutoInstrumentationDotNetImage()
r.Annotations[constants.AnnotationDefaultAutoInstrumentationPHP] = w.cfg.AutoInstrumentationPHPImage()
r.Annotations[constants.AnnotationDefaultAutoInstrumentationGo] = w.cfg.AutoInstrumentationGoImage()
r.Annotations[constants.AnnotationDefaultAutoInstrumentationApacheHttpd] = w.cfg.AutoInstrumentationApacheHttpdImage()
r.Annotations[constants.AnnotationDefaultAutoInstrumentationNginx] = w.cfg.AutoInstrumentationNginxImage()
Expand Down
2 changes: 2 additions & 0 deletions apis/v1alpha1/instrumentation_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestInstrumentationDefaultingWebhook(t *testing.T) {
config.WithAutoInstrumentationNodeJSImage("nodejs-img:1"),
config.WithAutoInstrumentationPythonImage("python-img:1"),
config.WithAutoInstrumentationDotNetImage("dotnet-img:1"),
config.WithAutoInstrumentationPHPImage("php-img:1"),
config.WithAutoInstrumentationApacheHttpdImage("apache-httpd-img:1"),
config.WithAutoInstrumentationNginxImage("nginx-img:1"),
),
Expand All @@ -41,6 +42,7 @@ func TestInstrumentationDefaultingWebhook(t *testing.T) {
assert.Equal(t, "nodejs-img:1", inst.Spec.NodeJS.Image)
assert.Equal(t, "python-img:1", inst.Spec.Python.Image)
assert.Equal(t, "dotnet-img:1", inst.Spec.DotNet.Image)
assert.Equal(t, "php-img:1", inst.Spec.PHP.Image)
assert.Equal(t, "apache-httpd-img:1", inst.Spec.ApacheHttpd.Image)
assert.Equal(t, "nginx-img:1", inst.Spec.Nginx.Image)
}
Expand Down
31 changes: 31 additions & 0 deletions autoinstrumentation/php/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# To build one auto-instrumentation image for php, please:
# - Download your php auto-instrumentation artefacts to `/autoinstrumentation` directory. This is required as when instrumenting the pod,
# one init container will be created to copy the files to your app's container.
# - Grant the necessary access to the files in the `/autoinstrumentation` directory.
# - Following environment variables are injected to the application container to enable the auto-instrumentation.
# PHP_INI_SCAN_DIR=:/otel-auto-instrumentation-php/php_ini_scan_dir
# OTEL_PHP_AUTOLOAD_ENABLED=true
# - For auto-instrumentation by container injection, the Linux command cp is
# used and must be availabe in the image.

FROM php-cli as staging

ARG auto_instrumentation_version

WORKDIR /autoinstrumentation

RUN pecl install opentelemetry-$auto_instrumentation_version
RUN mkdir lib
RUN cp /usr/local/lib/php/extensions/no-debug-non-zts-20230831/opentelemetry.so lib/
RUN mkdir php_ini_scan_dir
COPY php_config_opentelemetry_extension.ini php_ini_scan_dir/php_config_opentelemetry_extension.ini

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
ADD composer.json .
RUN composer install

FROM busybox

COPY --from=staging /autoinstrumentation /autoinstrumentation

RUN chmod -R go+r /autoinstrumentation
36 changes: 36 additions & 0 deletions autoinstrumentation/php/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "open-telemetry/operator-autoinstrumentation-php",
"description": "OpenTelemetry PHP auto-instrumentation packages to include in the image used by Operator for Kubernetes",
"keywords": [ "open telemetry", "OTel", "apm", "tracing", "apm-agent" ],
"type": "project",
"require": {
"open-telemetry/exporter-otlp": "1.1.0",
"open-telemetry/opentelemetry-auto-guzzle": "1.0.0",
"open-telemetry/opentelemetry-auto-http-async": "1.0.1",
"open-telemetry/opentelemetry-auto-laravel": "0.0.28",
"open-telemetry/opentelemetry-auto-pdo": "0.0.15",
"open-telemetry/opentelemetry-auto-psr15": "1.0.6",
"open-telemetry/opentelemetry-auto-psr18": "1.0.4",
"open-telemetry/opentelemetry-auto-slim": "1.0.7",
"open-telemetry/opentelemetry-auto-symfony": "1.0.0beta29",
"open-telemetry/opentelemetry-auto-wordpress": "0.0.16",
"open-telemetry/sdk": "1.1.0",
"php-http/guzzle7-adapter": "1.0.0"
},
"provide": {
"laravel/framework": "*",
"psr/http-client": "*",
"psr/http-server-middleware": "*",
"slim/slim": "*",
"symfony/http-client-contracts": "*",
"symfony/http-kernel": "*"
},
"config": {
"process-timeout": 0,
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"php-http/discovery": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extension=opentelemetry.so
1 change: 1 addition & 0 deletions autoinstrumentation/php/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.1.0
Loading
Loading