# PHP ゼロコード計装

LLMS index: [llms.txt](/llms.txt)

---

## 要件 {#requirements}

PHP の自動計装には以下が必要です。

- PHP 8.0 以上
- [OpenTelemetry PHP エクステンション](https://github.com/open-telemetry/opentelemetry-php-instrumentation)
- [Composer オートローディング](https://getcomposer.org/doc/01-basic-usage.md#autoloading)
- [OpenTelemetry SDK](https://packagist.org/packages/open-telemetry/sdk)
- 1つ以上の[計装ライブラリ](/ecosystem/registry/?component=instrumentation&language=php)
- [設定](#configuration)

## OpenTelemetry エクステンションのインストール {#install-the-opentelemetry-extension}

> [!IMPORTANT]
>
> OpenTelemetry エクステンションをインストールするだけではトレースは生成されません。

エクステンションは pecl、[pickle](https://github.com/FriendsOfPHP/pickle)、[PIE](https://github.com/php/pie)、または [php-extension-installer](https://github.com/mlocati/docker-php-extension-installer)（Docker 専用）経由でインストールできます。
一部の Linux パッケージマネージャー向けにパッケージ化されたバージョンのエクステンションも利用できます。

### Linux パッケージ {#linux-packages}

RPM と APK パッケージは以下から提供されています。

- [Remi repository](https://blog.remirepo.net/pages/PECL-extensions-RPM-status) -
  RPM
- [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=*pecl-opentelemetry) -
  APK（現在は [_testing_ ブランチ](https://wiki.alpinelinux.org/wiki/Repositories#Testing)にあります）

   <ul class="nav nav-tabs" id="tabs-0" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"
          data-td-tp-persist="rpm" aria-controls="tabs-00-00" aria-selected="true">
        RPM
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-00-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-01" role="tab"
          data-td-tp-persist="apk" aria-controls="tabs-00-01" aria-selected="false">
        APK
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-0-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="c1">#この例は CentOS 7 向けです。</span>
</span></span><span class="line"><span class="cl"><span class="c1">#PHP バージョンは remi-&lt;version&gt; を有効にすることで変更できます。</span>
</span></span><span class="line"><span class="cl"><span class="c1">#例: &#34;yum config-manager --enable remi-php83&#34;</span>
</span></span><span class="line"><span class="cl">yum update -y
</span></span><span class="line"><span class="cl">yum install -y epel-release yum-utils
</span></span><span class="line"><span class="cl">yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
</span></span><span class="line"><span class="cl">yum-config-manager --enable remi-php81
</span></span><span class="line"><span class="cl">yum install -y php php-pecl-opentelemetry
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">php --ri opentelemetry
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-00-01" role="tabpanel" aria-labelled-by="tabs-00-01-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="c1">#執筆時点では、PHP 8.1 がデフォルトの PHP バージョンでした。</span>
</span></span><span class="line"><span class="cl"><span class="c1">#デフォルトが変更された場合、&#34;php81&#34; を変更する必要があるかもしれません。</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&#34;apk add php&lt;version&gt;&#34; で PHP バージョンを選択することもできます。</span>
</span></span><span class="line"><span class="cl"><span class="c1">#例: &#34;apk add php83&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing&#34;</span> &gt;&gt; /etc/apk/repositories
</span></span><span class="line"><span class="cl">apk add php php81-pecl-opentelemetry@testing
</span></span><span class="line"><span class="cl">php --ri opentelemetry
</span></span></code></pre></div>
    </div>
</div>


### PECL {#pecl}

1. 開発環境のセットアップ。
   ソースからのインストールには適切な開発環境といくつかの依存関係が必要です。

      <ul class="nav nav-tabs" id="tabs-1" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-01-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-00" role="tab"
          data-td-tp-persist="linux (apt)" aria-controls="tabs-01-00" aria-selected="true">
        Linux (apt)
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-01-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-01" role="tab"
          data-td-tp-persist="macos (homebrew)" aria-controls="tabs-01-01" aria-selected="false">
        macOS (homebrew)
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-1-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-01-00" role="tabpanel" aria-labelled-by="tabs-01-00-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo apt-get install gcc make autoconf
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-01-01" role="tabpanel" aria-labelled-by="tabs-01-01-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">brew install gcc make autoconf
</span></span></code></pre></div>
    </div>
</div>


2. エクステンションのビルド/インストール。
   環境をセットアップしたら、エクステンションをインストールできます。

       <ul class="nav nav-tabs" id="tabs-2" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-02-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-00" role="tab"
          data-td-tp-persist="pecl" aria-controls="tabs-02-00" aria-selected="true">
        pecl
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-02-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-01" role="tab"
          data-td-tp-persist="pickle" aria-controls="tabs-02-01" aria-selected="false">
        pickle
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-02-02-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-02" role="tab"
          data-td-tp-persist="php-extension-installer (docker)" aria-controls="tabs-02-02" aria-selected="false">
        php-extension-installer (docker)
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-2-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-02-00" role="tabpanel" aria-labelled-by="tabs-02-00-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pecl install opentelemetry
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-02-01" role="tabpanel" aria-labelled-by="tabs-02-01-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">php pickle.phar install opentelemetry
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-02-02" role="tabpanel" aria-labelled-by="tabs-02-02-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">install-php-extensions opentelemetry
</span></span></code></pre></div>
    </div>
</div>


3. エクステンションを `php.ini` ファイルに追加します。

   ```ini
   [opentelemetry]
   extension=opentelemetry.so
   ```

4. エクステンションがインストールされ、有効になっていることを確認します。

   ```sh
   php -m | grep opentelemetry
   ```

## SDK と計装ライブラリのインストール {#install-sdk-and-instrumentation-libraries}

エクステンションをインストールしたら、OpenTelemetry SDK と1つ以上の計装ライブラリをインストールします。

自動計装は、一般的に使用される多くの PHP ライブラリで利用できます。
完全なリストは、[packagist の計装ライブラリ](https://packagist.org/search/?query=open-telemetry&tags=instrumentation)を参照してください。

アプリケーションが Slim Framework と PSR-18 HTTP クライアントを使用していて、OTLP プロトコルでトレースをエクスポートするとします。

その場合、SDK、エクスポーター、および Slim Framework と PSR-18 用の自動計装パッケージをインストールします。

```shell
composer require \
    open-telemetry/sdk \
    open-telemetry/exporter-otlp \
    open-telemetry/opentelemetry-auto-slim \
    open-telemetry/opentelemetry-auto-psr18
```

## 設定 {#configuration}

OpenTelemetry SDK と組み合わせて使用する場合、環境変数または `php.ini` ファイルを使用して自動計装を設定できます。

### 環境変数による設定 {#environment-configuration}

```sh
OTEL_PHP_AUTOLOAD_ENABLED=true \
OTEL_SERVICE_NAME=your-service-name \
OTEL_TRACES_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318 \
OTEL_PROPAGATORS=baggage,tracecontext \
php myapp.php
```

### php.ini による設定 {#phpini-configuration}

以下を `php.ini`、または PHP が処理する別の `ini` ファイルに追加します。

```ini
OTEL_PHP_AUTOLOAD_ENABLED="true"
OTEL_SERVICE_NAME=your-service-name
OTEL_TRACES_EXPORTER=otlp
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
OTEL_PROPAGATORS=baggage,tracecontext
```

## アプリケーションの実行 {#run-your-application}

上記のすべてがインストールおよび設定されたら、通常どおりアプリケーションを起動します。

OpenTelemetry Collector にエクスポートされるトレースは、インストールした計装ライブラリと、アプリケーション内で実行されたコードパスによって異なります。
前の例で Slim Framework と PSR-18 の計装ライブラリを使用している場合、次のようなスパンが表示されるはずです。

- HTTP トランザクションを表すルートスパン
- 実行されたアクションのスパン
- PSR-18 クライアントが送信した各 HTTP トランザクションのスパン

PSR-18 クライアントの計装は、送信 HTTP リクエストに[分散トレーシング](/docs/concepts/context-propagation/#propagation)ヘッダーを付加することに注意してください。

## 仕組み {#how-it-works}

> [!NOTE] Optional
>
> すぐに使い始めたい場合や、アプリケーションに適した計装ライブラリがある場合は、このセクションをスキップできます。

このエクステンションは、PHP コードとしてオブザーバー関数をクラスやメソッドに対して登録し、対象メソッドの実行前後にそれらの関数を実行できるようにします。

フレームワークやアプリケーション用の計装ライブラリがない場合は、独自に作成できます。
以下の例では、計装対象のコードを示し、OpenTelemetry エクステンションを使用してそのコードの実行をトレースする方法を説明します。

```php
<?php

use OpenTelemetry\API\Instrumentation\CachedInstrumentation;
use OpenTelemetry\API\Trace\Span;
use OpenTelemetry\API\Trace\StatusCode;
use OpenTelemetry\Context\Context;

require 'vendor/autoload.php';

/* 計装対象のクラス */
class DemoClass
{
    public function run(): void
    {
        echo 'Hello, world';
    }
}

/* 自動計装コード */
OpenTelemetry\Instrumentation\hook(
    class: DemoClass::class,
    function: 'run',
    pre: static function (DemoClass $demo, array $params, string $class, string $function, ?string $filename, ?int $lineno) {
        static $instrumentation;
        $instrumentation ??= new CachedInstrumentation('example');
        $span = $instrumentation->tracer()->spanBuilder('democlass-run')->startSpan();
        Context::storage()->attach($span->storeInContext(Context::getCurrent()));
    },
    post: static function (DemoClass $demo, array $params, $returnValue, ?Throwable $exception) {
        $scope = Context::storage()->scope();
        $scope->detach();
        $span = Span::fromContext($scope->context());
        if ($exception) {
            $span->recordException($exception);
            $span->setStatus(StatusCode::STATUS_ERROR);
        }
        $span->end();
    }
);

/* 計装されたコードを実行し、トレースを生成する */
$demo = new DemoClass();
$demo->run();
```

前の例では `DemoClass` を定義し、その `run` メソッドに `pre` および `post` フック関数を登録しています。
フック関数は `DemoClass::run()` メソッドの実行前後に実行されます。
`pre` 関数はスパンを開始してアクティブにし、`post` 関数はスパンを終了します。

`DemoClass::run()` が例外をスローした場合、`post` 関数は例外の伝搬に影響を与えずに例外を記録します。

## 次のステップ {#next-steps}

アプリケーションやサービスに自動計装を設定した後は、[手動計装](/docs/languages/php/instrumentation)を追加してカスタムテレメトリーデータを収集することもできます。

その他の例については、[opentelemetry-php-contrib/examples](https://github.com/open-telemetry/opentelemetry-php-contrib/tree/main/examples) を参照してください。
