docker-composeのPHPでDatadogAPMを試してみる


docker-composeでDatadog Agentを使うの続きです。

準備

とりあえず
https://github.com/DataDog/dd-trace-php/blob/master/docs/getting_started.md
を元に進めていきます。
(コンテナにdd-trace-phpをあらかじめ設定するのは一旦後回しで・・・)

上のドキュメントには

mkdir dd-trace
cd dd-trace
curl -L https://github.com/DataDog/dd-trace-php/archive/v0.2.5.tar.gz | tar x --strip-components=1
phpize # generate files needed to build PHP extension
./configure
make
sudo make install

と書かれていますが、curlコマンドを実行するとxオプションが無いとエラーで怒られるのでこの行だけ

curl -L https://github.com/DataDog/dd-trace-php/archive/v0.2.5.tar.gz | tar xz --strip-components=1

とzオプションを加えて実行すれば良さそうな感じでした。
(コンテナによってはMakeコマンド使えないかもしれないので、「yum install make」とかで入れておいてください)

「Enabling the extension」に書かれている

dd.ini
extension=ddtrace.so

の設定を追加するのを忘れないようにする。「/etc/php.d/」以下とかに追加して

php -m | grep ddtrace

このコマンドで確認しておく。この辺りはドキュメント通りに進めていけばOK。

前回設定したdocker-compose.ymlを使います

docker-compose.yml
  hogehoge:
    image: hogehoge
    container_name: hogehoge
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./httpd/vhosts.conf:/etc/httpd/conf.d/vhosts.conf
      - ./admin/:/var/www/
    links:
      - dd-agent:dd-agent
    depends_on:
      - dd-agent

  dd-agent:
    container_name: dd-agent
    image: datadog/docker-dd-agent
    environment:
      - API_KEY=[API_KEY]
      - DD_APM_ENABLED=true
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock
     - /proc/mounts:/host/proc/mounts:ro
     - /sys/fs/cgroup:/host/sys/fs/cgroup:ro
    ports:
      - "8126:8126/tcp"

APMを使う場合、Datadog Agent側に

DD_APM_ENABLED=true

この設定を忘れないようにする。

endpoint設定

Advanced APM Setupに書かれたManual Instrumentationと
dd-trace-phpに書かれたUsing the tracerを元にそれっぽいサンプルを作ってみる。
んだけど、そのままじゃ動かなくて一部変えないといけない所の説明。
DDTrace/Transport/Http.phpのDEFAULT_ENDPOINTがlocalhostを向いているのでDatadog Agentを向くようにする。

DDtrace/Transport/Http.php
final class Http implements Transport
{
    const DEFAULT_ENDPOINT = 'http://localhost:8126/v0.3/traces';

    /**
     * @var Encoder
     */
    private $encoder;

    /**
     * @var array
     */
    private $headers = [];

    /**
     * @var array
     */
    private $config;

    /**
     * @var LoggerInterface
     */
    private $logger;

    public function __construct(Encoder $encoder, LoggerInterface $logger = null, array $config = [])
    {
        $this->encoder = $encoder;
        $this->logger = $logger ?: new NullLogger();
        $this->config = array_merge([
            'endpoint' => self::DEFAULT_ENDPOINT,
        ], $config);

        $this->setHeader('Datadog-Meta-Lang', 'php');
        $this->setHeader('Datadog-Meta-Lang-Version', \PHP_VERSION);
        $this->setHeader('Datadog-Meta-Lang-Interpreter', \PHP_SAPI);
        $this->setHeader('Datadog-Meta-Tracer-Version', Version\VERSION);
    }

実装を見るとconfigがarray_mergeになっているので、endpointを渡せば良さそうに見えるので

AdvancedAPMSetupとdd-trace-phpのsampleMergeしたやつ
<?php
use DDTrace\Tracer;
use DDTrace\Transport\Http;
use DDTrace\Encoders\Json;
use OpenTracing\GlobalTracer;
use DDTrace\Tags;
use DDTrace\Types;

$tracer = new Tracer(
    new Http(
        new Json(),
        null,
        [
            'endpoint' => 'http://dd-agent:8126/v0.3/traces',
        ]
    )
);
GlobalTracer::set($tracer);
$scope = GlobalTracer::get()->startActiveSpan("web.request");
$span = $scope->getSpan();
$span->setResource('testResource');
$span->setTag(Tags\SPAN_TYPE, Types\WEB_SERVLET);
$span->setTag('http.method', 'testMethod');
$span->finish();
GlobalTracer::get()->flush();

HttpとJsonは

use DDTrace\Transport\Http;
use DDTrace\Encoders\Json;

こいつらをuseして使えるようにする。
あとは上に書いた通りendpointをDatadog Agentの名前に書き換える。

で、

とりあえず無事動いた模様。
DatadogAPMが対応しているframework使ったらきっともっと楽にできるはず。

※ API_KEY見た人はスーパー察してください