Мониторинг PHP приложений с помощью Proto Observability
На этой странице:
- Введение
- Установка PHP трейсера для подключения PHP приложений к Proto Observability Platform
- Отключение PHP-трейсера
- Поддерживаемые технологии
- Пользовательская (дополнительная) инструментация
Введение
Общий процесс подключения PHP приложения на мониторинг:
- Установка ProtoOBP Агента.
- Установка трейсера.
Установка PHP трейсера для подключения PHP приложений к Proto Observability Platform
Proto Observability Platform поддерживает следующие трейсеры:
- ProtoOBP PHP трейсер
- Datadog PHP трейсер
- OpenTelemetry PHP трейсер
- New Relic PHP трейсер (скоро)
Если приложение запускается в Linux среде (без контейнеризации)
- 
Скачайте и разахивируйте архив с PHP трейсером : curl --header "PRIVATE-TOKEN:<your_token>" \ "https://git.proto.group/api/v4/projects/125/packages/generic/pobptrace-php-agent/2.3.2/protoobp-php-agent-2.3.2.tar.gz" \ --output protoobp-php-agent-2.3.2.tar.gztar -xzvf protoobp-php-agent-2.3.2.tar.gz
- 
Установите пакет PHP трейсера: Платформа Пакет Ubuntu, Debian dpkg -i protoobp-php-tracer_2.3.2_amd64.debCentos rpm -ivh protoobp-php-tracer-2.3.2-1.x86_64.rpmAlpine apk add --allow-untrusted protoobp-php-tracer_2.3.2_x86_64.apk
- 
В файле 98-pobptrace.ini* укажите следующее:protoobp.service = my_service_name ; название сервиса protoobp.env = prod ; действительное значение названия окружения, например: prod/test/stage*Расположение .ini файла вы можете узнать, выполнив php --ini. Обычно это/etc/php.d/98-pobptrace.ini.
- 
Установите Datadog PHP трейсер одним из двух способов: Установка трейсера с помощью скрипта установки (рекомендуется, необходим доступ к Интернет на подключаемой машине): - Скачайте последнюю версию установщика трейсера:
curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php- если вы используете Alpine Linux необходимо установить libgcc_sдо запуска установщика:apk add libgcc
 
- если вы используете Alpine Linux необходимо установить 
- Запустите установку трейсера (для работы необходим доступ к Интернет):
php datadog-setup.php --php-bin=all
 Установка трейсера с помощью RPM/DEB/APK пакетов (если требуется оффлайн установка без доступа к Интернет): - 
Скачайте RPM/DEB/APKпакет для своей ОС со страницы последнего релиза трейсера:
- 
Установите пакет PHP трейсера: Платформа Пакет Ubuntu, Debian dpkg -i datadog-php-tracer_<version>_amd64.debCentos rpm -ivh datadog-php-tracer-<version>>.x86_64.rpmAlpine apk add --allow-untrusted datadog-php-tracer_<version>_x86_64.apk
 
- Скачайте последнюю версию установщика трейсера:
- 
Раскомментируйте и настройте необходимые параметры в файле 98-ddtrace.ini* :datadog.service = my_service_name ; название сервиса datadog.env = prod ; действительное значение названия окружения, например: prod/test/stage*Расположение .ini файла вы можете узнать, выполнив php --ini. Обычно это/etc/php.d/98-ddtrace.ini.
Скоро
- 
Выполните шаги, указанные на странице подключения инструметации OpenTelemetry для PHP: https://opentelemetry.io/docs/languages/php/instrumentation/ 
- 
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform. 
Перезапустите PHP (например, Apache, Nginx PHP-FPM):
service httpd restart
service nginx restart
Если приложение запускается в Docker контейнере (без Kubernetes)
- 
Скачайте и разахивируйте архив с трейсером: curl --header "PRIVATE-TOKEN:<your_token>" \ "https://git.proto.group/api/v4/projects/125/packages/generic/pobptrace-php-agent/2.3.3/protoobp-php-agent-2.3.3.tar.gz" \ --output protoobp-php-agent-2.3.3.tar.gztar -xzvf protoobp-php-agent-2.3.3.tar.gz
- 
Добавьте соответствующий пакет с трейсером в ваш контейнер: Платформа Пакет Ubuntu, Debian protoobp-php-tracer_2.3.3_amd64.debCentos protoobp-php-tracer-2.3.3-1.x86_64.rpmAlpine protoobp-php-tracer_2.3.3_x86_64.apk
- 
Установите пакет: Платформа Пакет Ubuntu, Debian RUN dpkg -i protoobp-php-tracer_2.3.3_amd64.debCentos RUN rpm -ivh protoobp-php-tracer-2.3.3-1.x86_64.rpmAlpine RUN apk add --allow-untrusted protoobp-php-tracer_2.3.3_x86_64.apk
- 
Добавьте следующие переменные окружения: - POBP_AGENT_HOST– адрес Агента, на который будет отсылать данные трейсер:- если Агент запущен в Docker контейнере, укажите имя Docker контейнера Агента:
Убедитесь, что контейнер Агента и контейнер приложения находятся в одной Docker сети. Адрес агента должен быть доступен из Docker контейнера приложения.ENV POBP_AGENT_HOST="protoobp-agent"
- если Агент запущен на хосте как сервис (не в контейнере):
Убедитесь что в конфигурации Агента разрешен прием APM данных от контейнеров:ENV POBP_AGENT_HOST="host.docker.internal"apm_config: apm_non_local_traffic: true
 
- если Агент запущен в Docker контейнере, укажите имя Docker контейнера Агента:
- POBP_SERVICE– имя сервиса, которое будет отображаться в интерфейсе Proto OBP:- ENV POBP_SERVICE="my_service_name"
- POBP_TRACE_TELEMETRY_ENABLED– установите в- false- ENV POBP_TRACE_TELEMETRY_ENABLED="false"
 
Пример готового Dockerfile
FROM php:7.4-apache
RUN apt-get update && apt-get install -yqq unzip wget curl libzip-dev \
        && docker-php-ext-install pdo_mysql opcache zip
COPY status.conf /etc/apache2/mods-available/status.conf
RUN a2enmod rewrite && a2enmod status
WORKDIR /var/www/html
COPY html/ /var/www/html
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer install
RUN rm -Rf /var/www/var/*
RUN chown -R www-data /var/www
RUN chmod -R 777 /var/www
#Установка Proto Observability PHP Agent
ENV POBP_AGENT_HOST=protoobp-agent
ENV POBP_SERVICE=my_service
ENV POBP_TRACE_TELEMETRY_ENABLED=false
## используйте актуальную версию трейсера
COPY ./protoobp-php-tracer_2.3.3_amd64.deb /opt
RUN dpkg -i /opt/protoobp-php-tracer_2.3.3_amd64.deb
- 
Установите Datadog PHP трейсер одним из двух способов: Установка трейсера с помощью скрипта установки (рекомендуется, необходим доступ к Интернет на подключаемой машине): - Скачайте последнюю версию установщика трейсера:
curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php- если вы используете Alpine Linux необходимо установить libgcc_sдо запуска установщика:apk add libgcc
 
- если вы используете Alpine Linux необходимо установить 
- Запустите установку трейсера (для работы необходим доступ к Интернет):
php datadog-setup.php --php-bin=all
 Установка трейсера с помощью RPM/DEB/APK пакетов (если требуется оффлайн установка без доступа к Интернет): - 
Скачайте RPM/DEB/APKпакет для своей ОС со страницы последнего релиза трейсера:
- 
Установите пакет PHP трейсера: Платформа Пакет Ubuntu, Debian dpkg -i datadog-php-tracer_<version>_amd64.debCentos rpm -ivh datadog-php-tracer-<version>>.x86_64.rpmAlpine apk add --allow-untrusted datadog-php-tracer_<version>_x86_64.apk
 
- Скачайте последнюю версию установщика трейсера:
- 
Добавьте следующие переменные окружения: - DD_AGENT_HOST– адрес Агента, на который будет отсылать данные трейсер:- если Агент запущен в Docker контейнере, укажите имя Docker контейнера Агента:
Убедитесь, что контейнер Агента и контейнер приложения находятся в одной Docker сети. Адрес агента должен быть доступен из Docker контейнера приложения.ENV POBP_AGENT_HOST="datadog-agent"
- если Агент запущен на хосте как сервис (не в контейнере):
Убедитесь что в конфигурации Агента разрешен прием APM данных от контейнеров:ENV DD_AGENT_HOST="host.docker.internal"apm_config: apm_non_local_traffic: true
 
- если Агент запущен в Docker контейнере, укажите имя Docker контейнера Агента:
- DD_SERVICE– имя сервиса, которое будет отображаться в интерфейсе Proto OBP:- ENV DD_SERVICE="my_service_name"
- DD_TRACE_TELEMETRY_ENABLED– установите в- false- ENV DD_TRACE_TELEMETRY_ENABLED="false"
 
Пример готового Dockerfile
FROM php:7.4-apache
RUN apt-get update && apt-get install -yqq unzip wget curl libzip-dev \
        && docker-php-ext-install pdo_mysql opcache zip
COPY status.conf /etc/apache2/mods-available/status.conf
RUN a2enmod rewrite && a2enmod status
WORKDIR /var/www/html
COPY html/ /var/www/html
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer install
RUN rm -Rf /var/www/var/*
RUN chown -R www-data /var/www
RUN chmod -R 777 /var/www
### Установка трейсера Datadog онлайн
RUN curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php \
    && php datadog-setup.php --php-bin=all
# ИЛИ установка трейсера Datadog оффлайн
# скачанный ранее файл трейсера из https://github.com/DataDog/dd-trace-php/releases/download/1.12.1/datadog-php-tracer_1.12.1_amd64.deb доступен при сборке контейнера
COPY ./datadog-php-tracer_1.12.1_amd64.deb /opt
RUN dpkg -i /opt/datadog-php-tracer_1.12.1_amd64.deb
# Установка переменных окружения
ENV DD_AGENT_HOST=datadog-agent
ENV DD_SERVICE=my_service
ENV DD_TRACE_TELEMETRY_ENABLED=false
Скоро
- 
Следуйте инструкциям из официальной документации OpenTelemetry для PHP: 
- 
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform. 
Если приложение работает в Kubernetes
Убедитесь, что у вас успешно установлен и настроен ProtoOBP Агент для Kubernetes.
Убедитесь, что пакет с трейсером установлен в контейнер согласно инструкции для Docker контейнера. При работе сервиса в Kubernetes переменные окружения в Dockerfile задавать не нужно, так как это нужно делать в спецификации деплоймента подключаемого приложения.
Дополнительно необходимо передать поду переменную окружения POBP_AGENT_HOST со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную согласно реальному используемому имени кластера).
apiVersion: apps/v1
kind: Deployment
#(...)
    spec:
      containers:
      - name: "<CONTAINER_NAME>"
        image: "<CONTAINER_IMAGE>/<TAG>"
        env:
          - name: POBP_SERVICE
            value: your_service_name			    # обязательно, имя сервиса для отображения в интерфейсе
          - name: POBP_ENV
            value: prod/test/stage/etc			  # крайне желательно, название окружения сервиса для отображения в интерфейсе
          - name: POBP_VERSION
            value: your_service_version			  # опционально, версия сервиса для отображения в интерфейсе            
          - name: POBP_AGENT_HOST
            valueFrom:
              fieldRef:
                fieldPath: status.hostIP
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POBP_TAGS
            value: "pod_name:$(POD_NAME),node:$(NODE_NAME),kube_namespace:$(POD_NAMESPACE),kube_cluster_name:<my_cluster_name>"
            
Дополнительно необходимо передать поду переменную окружения DD_AGENT_HOST со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную согласно реальному используемому имени кластера).
apiVersion: apps/v1
kind: Deployment
#(...)
    spec:
      containers:
      - name: "<CONTAINER_NAME>"
        image: "<CONTAINER_IMAGE>/<TAG>"
        env:
          - name: DD_SERVICE
            value: your_service_name			    # обязательно, имя сервиса для отображения в интерфейсе
          - name: DD_ENV
            value: prod/stage/dev/etc			    # крайне желательно, название окружения сервиса для отображения в интерфейсе  
          - name: DD_VERSION
            value: your_service_version			  # опционально, версия сервиса для отображения в интерфейсе            
          - name: DD_AGENT_HOST
            valueFrom:
              fieldRef:
                fieldPath: status.hostIP
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: DD_TAGS
            value: "pod_name:$(POD_NAME),node:$(NODE_NAME),kube_namespace:$(POD_NAMESPACE),kube_cluster_name:<my_cluster_name>"                  
Скоро
- 
Выполните шаги, указанные на странице подключения инструметации OpenTelemetry для PHP: 
- 
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform. 
Отключение PHP-трейсера
Для php-fpm - остановите сервис php-fpm, или остановите веб-сервер Apache.
Удалите файлы 98-pobptrace.ini и 99-pobptrace-custom.ini из папки конфигураций php.
Для php-fpm - перезапустите сервис php-fpm, или перезапустите веб-сервер Apache.
Если вы используете кэширование второго уровня в OPcache, задав параметр opcache.file_cache - удалите папку с кэшем.
Также можно отключить работу трейсера (при этом PHP-модуль трейсера будет оставаться загруженным):
- 
через файл конфигурации pobptrace.trace.enabled=0
- 
через переменную окружения POBP_TRACE_ENABLEDЗначение по умолчанию: 1
 Комментарий: Включает/отключает трейсер глобально.
Для удаления трейсера после отключения также можно удалить установленный RPM/DEB/APK пакет.
Для php-fpm - остановите сервис php-fpm, или остановите веб-сервер Apache.
Удалите файлы 98-ddtrace.ini и 99-ddtrace-custom.ini из папки конфигураций php.
Для php-fpm - перезапустите сервис php-fpm, или перезапустите веб-сервер Apache.
Если вы используете кэширование второго уровня в OPcache, задав параметр opcache.file_cache - удалите папку с кэшем.
Также можно отключить работу трейсера (при этом PHP-модуль трейсера будет оставаться загруженным):
- 
через файл конфигурации datadog.trace.enabled = Off
- 
через переменную окружения DD_TRACE_ENABLEDЗначение по умолчанию: 1
 Комментарий: Включает/отключает трейсер глобально.Для удаления трейсера после отключения также можно удалить установленный RPM/DEB/APK пакет. 
Скоро
Следуйте инструкциям из официальной документации OpenTelemetry для PHP:
Поддерживаемые технологии
Версии PHP
| Версия | Поддерживается | 
|---|---|
| 8.3.x | ✅ | 
| 8.2.x | ✅ | 
| 8.1.x | ✅ | 
| 8.0.x | ✅ | 
| 7.4.x | ✅ | 
| 7.3.x | ✅ | 
| 7.2.x | ✅ | 
| 7.1.x | ✅ | 
| 7.0.x | ✅ | 
| 5.6.x | ✅ | 
| 5.5.x | ✅ Поддерживается ProtoOBP трейсером версии 2.2.3 | 
| 5.4.x | ✅ Поддерживается ProtoOBP трейсером версии 2.2.3 | 
| Режим работы PHP | Поддерживается | 
|---|---|
| apache2handler | ✅ | 
| cli | ✅ | 
| fpm-fcgi | ✅ | 
| cgi-fcgi | ✅ | 
Автоматическая инструментация библиотек и фреймворков
Трейсинг запросов включен по умолчанию после установки трейсера. Proto Observability Platform поддерживает все PHP фреймворки из коробки, с инструментацией на уровне фреймворка или стандартного трейсинга веб-приложения.
Автоматическая инструментация работает благодаря модификации PHP рантайма для оборачивания функций и методов для их трейсинга.
Благодаря автоматической инструментации вам доступна следующая информация:
- время исполнения метода;
- данные транзакции, такие как URL и код ответа для веб запросов, текст SQL запроса для запросов к базам данных;
- необработанные исключения, в том числе стэк трейс, если он доступен.
PHP фреймворки
По умолчанию Proto Observability Platform поддерживает все PHP фреймворки из коробки, с инструментацией на уровне фреймворка или стандартного трейсинга веб-приложения.
Инструментация на уровне фреймворка включает отслеживание внутренних методов и простановку тегов, специфичных для фреймворка.
Стандартный трейсинг веб-приложения включает спан web.request для отслеживания задержки и ошибок, возникающих при вызове, в дополнение к спанам для вызовов поддерживаемых библиотек, например, при обращении к базам данных или HTTP-клиентам.
В следующей таблице перечислены некоторые из фреймворков и версий, для которых Proto Observability Platform успешно производит автоматический трейсинг.
| Фреймворк | Версия | Версии PHP | Уровень инструментации | 
|---|---|---|---|
| Битрикс | все | Все поддерживаемые версии PHP | Стандартный трейсинг веб-приложения | 
| CakePHP | 2.x | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| CodeIgniter | 2.x | PHP 7+ | Инструментация методов уровня фреймворка | 
| CodeIgniter | 3.x | PHP 7+ | Стандартный трейсинг веб-приложения | 
| Drupal | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | |
| FuelPHP | 1.1 | PHP 7+ | Стандартный трейсинг веб-приложения | 
| Laminas | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | |
| Laravel | 4.2, 5.x, 6.x | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Laravel 8+ | 8.x, 9.x, 10.x | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Lumen | 5.2+ | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Magento | 1 | Все поддерживаемые версии PHP | Стандартный трейсинг веб-приложения | 
| Magento | 2 | PHP 7+ | Инструментация методов уровня фреймворка | 
| Neos Flow | 1.1 | Все поддерживаемые версии PHP | Стандартный трейсинг веб-приложения | 
| Phalcon | 1.3, 3.4 | Все поддерживаемые версии PHP | Стандартный трейсинг веб-приложения | 
| RoadRunner | 2.x | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Slim | 2.x, 3.x, 4.x | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Symfony | 2.x, 3.3, 3.4, 4.x, 5.x, 6.x | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| WordPress | 4.x, 5.x, 6.x | PHP 7+ | Инструментация методов уровня фреймворка | 
| Yii | 1.1, 2.0 | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Zend Framework | 1.12, 1.21 | Все поддерживаемые версии PHP | Инструментация методов уровня фреймворка | 
| Zend Framework | 2.x | Все поддерживаемые версии PHP | Стандартный трейсинг веб-приложения | 
CLI
Поддержка трейсинга PHP CLI отключена по умолчанию.
Для включения трейсинга PHP CLI скриптов, установите переменную окружения POBP_TRACE_CLI_ENABLED=true.
| Модуль | Версии | Поддерживается | 
|---|---|---|
| CakePHP Console | 2.x | ✅ | 
| Laravel Artisan | 5.x, 8.x, 9.x, 10.x | ✅ | 
| Symfony CLI | 4.x, 5.x, 6.x | ✅ | 
Базы данных и datastore
| Модуль | Версии | Поддерживается | 
|---|---|---|
| Amazon RDS (используя PDO или MySQLi) | Все | ✅ | 
| Elasticsearch | 1+ | ✅ | 
| Eloquent | Все поддерживаемые версии Laravel | ✅ | 
| Laravel Queues | Все поддерживаемые версии Laravel | ✅ | 
| Memcache | Все | ✅ | 
| Memcached | Все | ✅ | 
| MongoDB | 1.4.x | ✅ | 
| MySQLi | Все | ✅ | 
| PDO | Все | ✅ | 
| PhpRedis | 3, 4, 5 | ✅ PHP 7, 8 | 
| Predis | 1.1 | ✅ | 
| SQLSRV | Все | ✅ | 
Прочие библиотеки и HTTP-клиенты
| Модуль | Версии | Поддерживается | 
|---|---|---|
| php-amqplib | 2.x, 3.x | ✅ PHP 7.1+ | 
| Curl | Все | ✅ | 
| Guzzle | 5.x, 6.x, 7.x | ✅ | 
Информацию по совместимости трейсера Datadog можно уточнить на оффициальном сайте:
https://docs.datadoghq.com/tracing/trace_collection/compatibility/php/
Скоро
Информацию по наличию инструментированных PHP библиотек с помощью OpenTelemetry можно уточнить на оффициальном сайте:
- 
Подключение поддерживаемых библиотек OpenTelemetry: 
- 
Актуальный список инструментированных с помощью OpenTelemetry библиотек: https://packagist.org/search/?query=open-telemetry&tags=instrumentation 
Пользовательская (дополнительная) инструментация
Инструментация через аннотации
Если вы используете PHP 8, то вы можете добавлять аннотации кода для его инструментации. Это более легкая альтернатива пользовательской инструментации, написанной в коде. Например, добавьте атрибут #[POBPTrace\Trace] к методам, чтобы Proto Observability Platform отслеживал их.
<?php
class Server {
    #[POBPTrace\Trace(name: "spanName", resource: "resourceName", type: "Custom", service: "myService", tags: ["aTag" => "aValue"])]
    static function process($arg) {}
    #[POBPTrace\Trace]
    function get() {
      Foo::simple(1);
    }
}
Вы можете указать следующие аргументы:
- $name: Имя операции, которое должно быть назначено спану. По умолчанию используется имя функции.
- $resource: Ресурс, который будет присвоен спану.
- $type: Тип, который будет присвоен спану.
- $service: Имя сервиса, которое будет назначена спану. По умолчанию принимает наследуемое имя сервиса.
- $tags: Теги, которые будут присвоены спану.
- $recurse: Должны ли отслеживаться рекурсивные вызовы.
- $run_if_limited: Должна ли функция трассироваться в ограниченном режиме. (Например, при превышении лимита спанов).
Если вы используете PHP 8, то вы можете добавлять аннотации кода для его инструментации. Это более легкая альтернатива пользовательской инструментации, написанной в коде. Например, добавьте атрибут #[DDTrace\Trace] к методам, чтобы Proto Observability Platform отслеживал их.
<?php
class Server {
    #[\DDTrace\Trace(name: "spanName", resource: "resourceName", type: "Custom", service: "myService", tags: ["aTag" => "aValue"])]
    static function process($arg) {}
    #[\DDTrace\Trace]
    function get() {
      Foo::simple(1);
    }
}
Вы можете указать следующие аргументы:
- $name: Имя операции, которое должно быть назначено спану. По умолчанию используется имя функции.
- $resource: Ресурс, который будет присвоен спану.
- $type: Тип, который будет присвоен спану.
- $service: Имя сервиса, которое будет назначена спану. По умолчанию принимает наследуемое имя сервиса.
- $tags: Теги, которые будут присвоены спану.
- $recurse: Должны ли отслеживаться рекурсивные вызовы.
- $run_if_limited: Должна ли функция трассироваться в ограниченном режиме. (Например, при превышении лимита спанов).
Скоро
Следуйте инструкциям из официальной документации OpenTelemetry для PHP:
Добавление пользовательской инструментации в коде
Если вам необходимо добавить собственную инструментацию, рассмотрите следующий пример приложения и пройдитесь по примеру.
Пример приложения, которое необходимо инструментировать
Предположим, что структура каталогов следующая:
.
|-- composer.json
|-- docker-compose.yml
|-- index.php
`-- src
    |-- Exceptions
    |   `-- NotFound.php
    |-- Services
    |   `-- SampleRegistry.php
    `-- utils
        `-- functions.php
Внутри него в двух файлах содержатся функции и методы, которые интересны для инструментации. Наиболее значимыми файлами являются src/utils/functions.php:
namespace App;
function some_utility_function($someArg)
{
    return 'result';
}
И src/Services/SampleRegistry.php:
namespace App\Services;
use App\Exceptions\NotFound;
use Exception;
class SampleRegistry
{
    public function put($key, $value)
    {
        \App\some_utility_function('some argument');
        // Возвращает идентификатор вставленного элемента
        return 456;
    }
    public function faultyMethod()
    {
        throw new Exception('Генерируется во время выполнения');
    }
    public function get($key)
    {
        // Для сообщения о том, что ключ не найден, сервис использует исключение.
        throw new NotFound('Ключ не был найден');
    }
    public function compact()
    {
        // Эта функция выполняет некоторые операции над реестром и
        // ничего не возвращает. В середине функции имеется интересное значение,
        // которое не возвращается, но может быть связано с замедлением функции
        $numberOfItemsProcessed = 123;
        // ...
    }
}
Написание пользовательской инструментации
Для написания пользовательской инструментации дополнительный пакет composer не требуется.
Чтобы не смешивать бизнес-логику приложения или сервиса с кодом инструментации, напишем необходимый код в отдельном файле.
- 
Создадим файл protoobp/instrumentation.phpи добавим его в автозагрузкуcomposer.//composer.json { ... "autoload": { ... "files": [ ... "protoobp/instrumentation.php" ] }, ... }
- 
Обновите autoloader, например, выполнивcomposer dump.
<p>Файл, содержащий пользовательскую инструментацию, и реальные классы, которые подвергаются инструментации, не обязательно должны находиться в одной кодовой базе и пакете.</p>
Регистрация входной точки инструментации в composer.json в секции autoload.files гарантирует, что файл всегда будет выполняться.
- 
В файле protoobp/instrumentation.php, проверьте, что расширение загружено. Если расширение не загружено, то все функции, используемые в этом файле, не существуют.#protoobp/instrumentation.php if (!extension_loaded('pobptrace')) { return; }
- 
Инструментируем функцию \App\some_utility_function. Если вас не интересует какой-либо конкретный аспект функции, кроме времени выполнения, то это все, что требуется:#protoobp/instrumentation.php \POBPTrace\trace_function('App\some_utility_function', function (\POBPTrace\SpanData $span, $args, $ret, $exception) {});
- 
Допустим, что для метода SampleRegistry::put, вы хотите не только сгенерировать спан, но и добавить тег со значением возвращаемого идентификатора элемента, а также тег для ключа. Посколькуput- это метод, используйте\POBPTrace\trace_methodвместо\POBPTrace\trace_function:#protoobp/instrumentation.php ... \POBPTrace\trace_method( 'App\Services\SampleRegistry', 'put', function (\POBPTrace\SpanData $span, $args, $ret, $exception) { $span->meta['app.cache.key'] = $args[0]; // Первый аргумент 'key' $span->meta['app.cache.item_id'] = $ret; // Возвращаемое значение } );
<p>При задании дополнительнх тегов следует избегать перезаписи существующих тегов, автоматически добавляемых основной инструментацией.</p>
Правильно:
$span->meta['mytag'] = 'value'
Неверно:
$span->meta = ['mytag' => 'value']
- 
В коде примера SampleRegistry::faultyMethodгенерирует исключение. При этом вам не требуется ничего дополнительно делать с точки зрения пользовательской инструментации. Если метод инструментирован, то стандартный механизм сообщения об исключениях позаботится о добавлении в спан сообщения об исключении и трассировки стека.#protoobp/instrumentation.php ... \POBPTrace\trace_method( 'App\Services\SampleRegistry', 'faultyMethod', function (\POBPTrace\SpanData $span, $args, $ret, $exception) { } );
- 
Метод SampleRegistry::getиспользует исключениеNotFoundдля уведомления о том, что элемент не найден. Допустим, это исключение является ожидаемой частью бизнес-логики приложения, и вы не хотите отмечать спан с этим исключением как ошибку. Тогда вы можете просто изменить имя ресурса, чтобы добавить его в пул операцийnot_found. Для этого необходимо сделатьunsetисключению для спана:#protoobp/instrumentation.php ... \POBPTrace\trace_method( 'App\Services\SampleRegistry', 'get', function (\POBPTrace\SpanData $span, $args, $ret, $exception) { if ($exception instanceof \App\Exceptions\NotFound) { unset($span->exception); $span->resource = 'cache.get.not_found'; } } );
- 
Метод SampleRegistry::compactдемонстрирует интересный случай использования. Если вас интересует добавление тега со значением, которое не является ни аргументом, ни значением, возвращаемым функцией, то для этого отредактируйте файлprotoobp/instrumentation.phpи файл классаsrc/Services/SampleRegistry.php:#protoobp/instrumentation.php ... \POBPTrace\trace_method( 'App\Services\SampleRegistry', 'compact', function (\POBPTrace\SpanData $span, $args, $ret, $exception) { } );В файле src/Services/SampleRegistry.phpотредактируйте тело метода:#src/Services/SampleRegistry.php ... public function compact() { // Эта функция выполняет некоторые операции над реестром и // ничего не возвращает. В середине функции имеется интересное значение, // которое не возвращается, но может быть связано с замедлением функции $numberOfItemsProcessed = 123; // Добавьте код инструментации в бизнес-логику. if (\function_exists('\POBPTrace\active_span') && $span = \POBPTrace\active_span()) { $span->meta['registry.compact.items_processed'] = $numberOfItemsProcessed; } // ... }
Подробнее о trace_function и trace_method
Функции POBPTrace\trace_function и POBPTrace\trace_method инструментируют (трассируют) вызовы определенных функций и методов. Эти функции автоматически решают следующие задачи:
- Открытие спана перед выполнением кода.
- Добавление в спан всех ошибок, возникших при выполнении инструменированного вызова.
- Закрытие спана после завершения инструментированного вызова.
Дополнительные теги устанавливаются на спан из закрытия (называемого закрытием трассировки).
Например, в следующем фрагменте выполняется трассировка метода CustomDriver::doWork и добавляются пользовательские теги. Исключения автоматически отслеживаются на спане.
<?php
\POBPTrace\trace_method(
    'CustomDriver',
    'doWork',
    function (\POBPTrace\SpanData $span, array $args, $retval, $exception) {
        // Это закрытие выполняется после инструментального вызова
        // Спан был автоматически создан до вызова инструментированного вызова
        // SpanData::$name по умолчанию устанавливается в 'ClassName.methodName' если не задано
        $span->name = 'CustomDriver.doWork';
        // SpanData::$resource по умолчанию устанавливается в SpanData::$name не задано
        $span->resource = 'CustomDriver.doWork';
        // Если исключение было выдано из неинструментированного вызова, возвращаемое значение является null
        $span->meta['doWork.size'] = $exception ? 0 : count($retval),
        // Доступ к членам объекта через $this
        $span->meta['doWork.thing'] = $this->workToDo;
        // Спан автоматически закроется
    }
);
// Для функций
\POBPTrace\trace_function(
    'doCustomDriverWork',
    function (\POBPTrace\SpanData $span, array $args, $retval, $exception) {
        // Закрытие такое же как для POBPTrace\trace_method
    }
);
?>
Доступ к активным спанам
Встроенная и пользовательская инструментация создают спаны вокруг значимых операций. Вы можете получить доступ к активному спану, чтобы включить в него значимые данные.
Текущий спан
Следующий метод возвращает объект POBPTrace\SpanData. Если трассировка отключена, возвращается null.
<?php
$span = \POBPTrace\active_span();
if ($span) {
    $span->meta['customer.id'] = get_customer_id();
}
?>
Корневой спан
Следующий метод возвращает объект POBPTrace\SpanData. Если трассировка отключена, возвращается null. Это полезно в тех случаях, когда метаданные, которые должны быть добавлены к корневому спану, не существуют на ранних этапах выполнения скрипта.
<?php
$span = \POBPTrace\root_span();
if ($span) {
    $span->meta['customer.id'] = get_customer_id();
}
?>
Добавление тегов
<p>При задании дополнительнх тегов следует избегать перезаписи существующих тегов, автоматически добавляемых основной инструментацией.</p>
Правильно:
$span->meta['mytag'] = 'value'
Неверно:
$span->meta = ['mytag' => 'value']
Локально
Добавьте теги к спану с помощью массива POBPTrace\SpanData::$meta.
<?php
\POBPTrace\trace_function(
    'myRandFunc',
    function(\POBPTrace\SpanData $span, array $args, $retval) {
        // ...
        $span->meta['rand.range'] = $args[0] . ' - ' . $args[1];
        $span->meta['rand.value'] = $retval;
    }
);
Глобально
Установите переменную окружения POBP_TAGS для автоматического добавления тегов к каждому создаваемому спану.
POBP_TAGS=key1:value1,<TAG_KEY>:<TAG_VALUE>
Ошибки
Выброшенные исключения автоматически привязываются к активному спану, если только исключение не было выброшено на более глубоком уровне стека вызовов и не было поймано до того, как оно достигло какой-либо трассируемой функции.
<?php
function doRiskyThing() {
    throw new Exception('Ой!');
}
\POBPTrace\trace_function(
    'doRiskyThing',
    function() {
        // Спан будет помечен как ошибочный, и к нему будут добавлены в качестве тегов
        // трассировка стека и сообщение исключения
    }
);
Добавьте тег error.msg, чтобы вручную отметить спан как ошибочный.
<?php
function doRiskyThing() {
    return SOME_ERROR_CODE;
}
\POBPTrace\trace_function(
    'doRiskyThing',
    function(\POBPTrace\SpanData $span, $args, $retval) {
        if ($retval === SOME_ERROR_CODE) {
            $span->meta['error.msg'] = 'Ошибка Х';
            // Опционально:
            $span->meta['error.type'] = 'CustomError';
            $span->meta['error.stack'] = (new \Exception)->getTraceAsString();
        }
    }
);
Следуйте инструкциям, приведенным на странице документации трейсера:
Скоро
Следуйте инструкциям из официальной документации OpenTelemetry для PHP: