英文:
Dependencies do not show with OpenTelemetry automatic instrumentation for PHP
问题
我有一个非常简单的PHP堆栈,包括PHP + Otel自动化仪器 + Elastic APM + Prometheus。
我的堆栈从我的php应用程序中获取跟踪和度量信息。
我的跟踪被转发到弹性云,我在那里使用APM。我的度量信息发送到Prometheus。
我发现我的跟踪只部分工作,因为我看不到依赖关系。在这种情况下,依赖关系将是我的外部API。
我的堆栈的基础部分:(我没有附加php.ini和**.htaccess**文件,因为我认为这不相关。)
> index.php
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use DI\Container;
use GuzzleHttp\Client;
require __DIR__ . '/vendor/autoload.php';
$container = new Container();
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('<h3>RANDOM API</h3>
<p>O que você gostaria de ver?</p>
<ul>
<li>Random dogs? <a href="/dogs">Clique</li>
</ul>');
return $response;
});
$app->get('/healthcheck', function (Request $request, Response $response) {
return $response->withStatus(204);
});
$app->get('/dogs', function (Request $request, Response $response) {
$client = new Client();
try {
$apiResponse = $client->get('https://dog.ceo/api/breeds/image/random');
$dogData = json_decode($apiResponse->getBody());
$response->getBody()->write('<img src="' . $dogData->message . '" alt="random dog" style="max-width: 500px"/>');
} catch (\Exception $e) {
$response->getBody()->write($e->getMessage());
return $response->withStatus(500);
}
return $response;
});
$app->run();
> Dockerfile
FROM php:8.2
RUN set -xe; \
apt-get update; \
apt-get -y install g++ zlib1g-dev build-essential zlib1g-dev gcc make autoconf m4 perl git; \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer; \
pecl install grpc && docker-php-ext-enable grpc; \
pecl install opentelemetry-beta && docker-php-ext-enable opentelemetry
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV OTEL_PHP_AUTOLOAD_ENABLED=true
ENV OTEL_SERVICE_NAME=your-service-name
ENV OTEL_TRACES_EXPORTER=console
ENV OTEL_METRICS_EXPORTER=otlp
ENV OTEL_EXPORTER_OTLP_PROTOCOL=grpc
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
ENV OTEL_PROPAGATORS=baggage,tracecontext
WORKDIR /usr/src/myapp
COPY composer.json composer.lock* /usr/src/myapp/
RUN composer install --no-dev --no-scripts --no-autoloader
COPY . /usr/src/myapp
RUN composer dump-autoload --optimize --classmap-authoritative; \
composer require slim/slim:^4 slim/psr7:^1; \
composer require open-telemetry/exporter-otlp php-http/guzzle7-adapter; \
composer require open-telemetry/transport-grpc; \
composer config allow-plugins.php-http/discovery false; \
composer require open-telemetry/sdk open-telemetry/opentelemetry-auto-slim; \
php --ri opentelemetry
COPY php.ini /usr/local/etc/php/php.ini
CMD [ "php", "-S", "0.0.0.0:8080" ]
> docker-compose.yml
services:
otel_collector:
networks:
- backend
image: otel/opentelemetry-collector-contrib:latest
volumes:
- "./otel-collector-config.yml:/etc/otelcol/otel-collector-config.yml"
command: --config /etc/otelcol/otel-collector-config.yml
ports:
- "14278:14278"
- "65535:65535"
- "55677:55677"
- "12345:12345"
- "4318:4318"
- "4317:4317"
- "8889:8889"
prometheus:
networks:
- backend
image: prom/prometheus:latest
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
ports:
- "9090:9090"
app-php:
build: ./php
image: app-php
ports:
- 8083:8080
container_name: app-php
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel_collector:4317
OTEL_SERVICE_NAME: app-php
OTEL_TRACES_EXPORTER: otlp
networks:
- backend
networks:
backend:
> composer.json
{
"require": {
"slim/slim": "4.*",
"php-di/php-di": "^6.3",
"guzzlehttp/guzzle": "^7.3",
"open-telemetry/api": "^1.0.0",
"open-telemetry/sdk": "^1.0.0"
},
"minimum-stability": "dev"
}
> otel-collector-config.yml
receivers:
otlp:
protocols:
grpc: {}
http: {}
exporters
<details>
<summary>英文:</summary>
I have a very simple stack of PHP + Otel auto instrumetation + Elastic APM + Prometheus.
My stack gets tracing and metrics information from my php app.
My tracings are forwarded to the elastic cloud, where I use APM. My metrics go to Prometheus.
I see that my tracing is partially working as I can't see the dependencies. Which in this case would be my external api.
[![enter image description here][1]][1]
[![enter image description here][2]][2]
**The base of my stack:** (*I didn't attach the **php.ini** and **.htaccess** files as I don't think it's relevant.*)
> index.php
~~~php
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use DI\Container;
use GuzzleHttp\Client;
require __DIR__ . '/vendor/autoload.php';
$container = new Container();
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('<h3>RANDOM API</h3>
<p>O que você gostaria de ver?</p>
<ul>
<li>Random dogs? <a href="/dogs">Clique</li>
</ul>');
return $response;
});
$app->get('/healthcheck', function (Request $request, Response $response) {
return $response->withStatus(204);
});
$app->get('/dogs', function (Request $request, Response $response) {
$client = new Client();
try {
$apiResponse = $client->get('https://dog.ceo/api/breeds/image/random');
$dogData = json_decode($apiResponse->getBody());
$response->getBody()->write('<img src="' . $dogData->message . '" alt="random dog" style="max-width: 500px"/>');
} catch (\Exception $e) {
$response->getBody()->write($e->getMessage());
return $response->withStatus(500);
}
return $response;
});
$app->run();
~~~
> Dockerfile
```dockerfile
FROM php:8.2
RUN set -xe; \
apt-get update; \
apt-get -y install g++ zlib1g-dev build-essential zlib1g-dev gcc make autoconf m4 perl git; \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer; \
pecl install grpc && docker-php-ext-enable grpc; \
pecl install opentelemetry-beta && docker-php-ext-enable opentelemetry
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV OTEL_PHP_AUTOLOAD_ENABLED=true
ENV OTEL_SERVICE_NAME=your-service-name
ENV OTEL_TRACES_EXPORTER=console
ENV OTEL_METRICS_EXPORTER=otlp
ENV OTEL_EXPORTER_OTLP_PROTOCOL=grpc
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
ENV OTEL_PROPAGATORS=baggage,tracecontext
WORKDIR /usr/src/myapp
COPY composer.json composer.lock* /usr/src/myapp/
RUN composer install --no-dev --no-scripts --no-autoloader
COPY . /usr/src/myapp
RUN composer dump-autoload --optimize --classmap-authoritative; \
composer require slim/slim:^4 slim/psr7:^1; \
composer require open-telemetry/exporter-otlp php-http/guzzle7-adapter; \
composer require open-telemetry/transport-grpc; \
composer config allow-plugins.php-http/discovery false; \
composer require open-telemetry/sdk open-telemetry/opentelemetry-auto-slim; \
php --ri opentelemetry
COPY php.ini /usr/local/etc/php/php.ini
CMD [ "php", "-S", "0.0.0.0:8080" ]
> docker-compose.yml
services:
otel_collector:
networks:
- backend
image: otel/opentelemetry-collector-contrib:latest
volumes:
- "./otel-collector-config.yml:/etc/otelcol/otel-collector-config.yml"
command: --config /etc/otelcol/otel-collector-config.yml
ports:
- "14278:14278"
- "65535:65535"
- "55677:55677"
- "12345:12345"
- "4318:4318"
- "4317:4317"
- "8889:8889"
prometheus:
networks:
- backend
image: prom/prometheus:latest
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
ports:
- "9090:9090"
app-php:
build: ./php
image: app-php
ports:
- 8083:8080
container_name: app-php
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel_collector:4317
OTEL_SERVICE_NAME: app-php
OTEL_TRACES_EXPORTER: otlp
networks:
- backend
networks:
backend:
> composer.json
{
"require": {
"slim/slim": "4.*",
"php-di/php-di": "^6.3",
"guzzlehttp/guzzle": "^7.3",
"open-telemetry/api": "^1.0.0",
"open-telemetry/sdk": "^1.0.0"
},
"minimum-stability": "dev"
}
> otel-collector-config.yml
receivers:
otlp:
protocols:
grpc: {}
http: {}
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
logging:
verbosity: detailed
otlp/elastic:
endpoint: "xxx-xxx-xxx"
headers:
Authorization: "xxx-xxx-xxx"
processors:
batch: {}
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus, logging]
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/elastic, logging]
>prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: aggregated-trace-metrics
static_configs:
- targets: ['otel_collector:8889']
答案1
得分: 3
看起来你的Slim框架应用程序的路由正在被跟踪并在elastic中可见,但你缺少对https://dog.ceo的http调用的跟踪。
Slim框架的自动仪器化不会仪器化外部的http调用。如果你正在使用的$client
是一个PSR-18 http客户端,那么可以通过安装open-telemetry/opentelemetry-auto-psr18
包来进行自动仪器化。请注意,$client->get()
不是PSR-18规范的一部分,只有sendRequest()
是。如果你正在使用的http客户端通过代理get()
来调用sendRequest()
,那么它应该能够工作。否则,可以使用PSR-18的方法创建请求并发送它:
$request = new Request('GET', 'https://dog.ceo/api/breeds/image/random');
$client->sendRequest($request);
英文:
It looks like your routes for the Slim Framework application are being traced and are visible in elastic, but you are missing spans for the http calls to https://dog.ceo
The slim framework auto-instrumentation does not instrument outgoing http calls. If the $client
that you are using is a PSR-18 http client, then it can be auto-instrumented by installing the open-telemetry/opentelemetry-auto-psr18
package. Do note that $client->get()
is not part of the PSR-18 spec, only sendRequest()
is. If the http client you are using proxies get()
through to sendRequest()
, then it should work. Otherwise, create the request and send it using the PSR-18 method:
$request = new Request('GET', 'https://dog.ceo/api/breeds/image/random');
$client->sendRequest($request);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论