Skip to content
Open
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
38 changes: 30 additions & 8 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[English](README.md)

CakePHP 5 アプリケーションに OpenTelemetry 計装を追加するプラグイン。`ext-opentelemetry` の `zend_observer` フックを利用し、コード変更なしで Controller / Table のスパンを自動生成する
CakePHP 5 アプリケーションに OpenTelemetry 計装を追加するプラグインです。`ext-opentelemetry` の `zend_observer` フックを利用し、コード変更なしで Controller / Table のスパンを自動生成します

## 要件

Expand All @@ -18,7 +18,7 @@ CakePHP 5 アプリケーションに OpenTelemetry 計装を追加するプラ
composer require kaz29/otel-instrumentation
```

`config/bootstrap.php` または `Application::bootstrap()` でプラグインを読み込む:
`config/bootstrap.php` または `Application::bootstrap()` でプラグインを読み込みます:

```php
$this->addPlugin('OtelInstrumentation');
Expand All @@ -45,15 +45,15 @@ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

## OtelErrorLoggingMiddleware

500系例外を OpenTelemetry ログレコードとして送信する PSR-15 ミドルウェア。ログは現在のスパンに自動で紐づくため、トレースバックエンド(Jaeger / Grafana Tempo など)のトレース画面から関連エラーをそのまま参照できる
500系例外を OpenTelemetry ログレコードとして送信する PSR-15 ミドルウェアです。ログは現在のスパンに自動で紐づくため、トレースバックエンド(Jaeger / Grafana Tempo など)のトレース画面から関連エラーをそのまま参照できます

- `HttpException` でステータスコード 500 以上: 送信
- `HttpException` でステータスコード 400 系 (例: 404): 送信しない
- `HttpException` 以外の例外(予期しないエラー): 500 として送信
- `HttpException` でステータスコード 500 以上: 送信します
- `HttpException` でステータスコード 400 系 (例: 404): 送信しません
- `HttpException` 以外の例外(予期しないエラー): 500 として送信します

### 設定

`Application::middleware()` で `ErrorHandlerMiddleware` の**後**(内側)に配置する:
`Application::middleware()` で `ErrorHandlerMiddleware` の**後**(内側)に配置してください:

```php
use OtelInstrumentation\Middleware\OtelErrorLoggingMiddleware;
Expand All @@ -70,12 +70,34 @@ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue

## TraceAwareLogger

PSR-3 LoggerInterface の Decorator。ログの `context` に `trace_id` / `span_id` を自動付与する
PSR-3 LoggerInterface の Decorator です。ログの `context` に `trace_id` / `span_id` を自動付与します

```php
$logger = new \OtelInstrumentation\Log\TraceAwareLogger($existingPsr3Logger);
```

## デモアプリケーション (testapp)

`testapp/` ディレクトリにサンプル CakePHP アプリケーションを同梱しています。Posts/Comments の CRUD アプリにプラグインを組み込み済みで、PostgreSQL と Jaeger を Docker Compose で提供します。

### 起動方法

```bash
cd testapp
docker compose up -d
docker compose exec app composer install
docker compose exec app bin/cake migrations migrate
```

- アプリ: http://localhost:8080
- Jaeger UI: http://localhost:16686

アプリにアクセスした後、Jaeger UI を開くとプラグインが生成したトレースを確認できます。

### 仕組み

testapp の `composer.json` は Composer の `path` リポジトリを使い、親ディレクトリのプラグインをシンボリックリンクでインストールします。プラグインのソースを変更すると再インストールなしで即座に反映されます。

## ライセンス

MIT
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,28 @@ A PSR-3 LoggerInterface decorator that automatically injects `trace_id` / `span_
$logger = new \OtelInstrumentation\Log\TraceAwareLogger($existingPsr3Logger);
```

## Demo Application (testapp)

A sample CakePHP application is included in the `testapp/` directory. It provides a Posts/Comments CRUD app with the plugin pre-configured, along with PostgreSQL and Jaeger via Docker Compose.

### Quick Start

```bash
cd testapp
docker compose up -d
docker compose exec app composer install
docker compose exec app bin/cake migrations migrate
```

- App: http://localhost:8080
- Jaeger UI: http://localhost:16686

Access the app, then open Jaeger UI to see the traces generated by the plugin.

### How It Works

The testapp's `composer.json` uses a Composer `path` repository to install the plugin from the parent directory as a symlink. Any changes you make to the plugin source are reflected immediately without reinstalling.

## License

MIT
52 changes: 52 additions & 0 deletions testapp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# CakePHP specific files #
##########################
/config/app_local.php
/config/.env
/logs/*
/tmp/*
/vendor/*

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
# Icon must end with two \r
Icon
ehthumbs.db
Thumbs.db
.directory

# Tool specific files #
#######################
# PHPUnit
.phpunit.cache
tests.sqlite
# vim
*~
*.swp
*.swo
# sublime text & textmate
*.sublime-*
*.stTheme.cache
*.tmlanguage.cache
*.tmPreferences.cache
# Eclipse
.settings/*
# JetBrains, aka PHPStorm, IntelliJ IDEA
.idea/*
# NetBeans
nbproject/*
# Visual Studio Code
.vscode
# nova
.nova
# Sass preprocessor
.sass-cache/
# node
/node_modules/*
# yarn
yarn-debug.log
yarn-error.log
Expand Down
39 changes: 39 additions & 0 deletions testapp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ---- Build stage ----
FROM php:8.3-fpm AS build

RUN apt-get update && apt-get install -y \
git unzip libpq-dev libicu-dev \
&& docker-php-ext-install intl pdo_pgsql opcache

# OpenTelemetry extension
RUN pecl install opentelemetry && docker-php-ext-enable opentelemetry

# Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-interaction

COPY . .
Comment on lines +16 to +18
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build stage runs composer install before the application source (including src/Console/Installer.php and config/app_local.example.php) is copied into the image. Because composer.json defines post-install-cmd as App\Console\Installer::postInstall, this is very likely to fail (class/file not found) or skip generating config/app_local.php.

Consider either copying the minimal app files needed by the scripts (e.g., src/Console/Installer.php + config/app_local.example.php) before composer install, or running composer install --no-scripts in the cached layer and executing the necessary setup steps after COPY . ..

Suggested change
RUN composer install --no-dev --optimize-autoloader --no-interaction
COPY . .
RUN composer install --no-dev --optimize-autoloader --no-interaction --no-scripts
COPY . .
RUN composer run-script post-install-cmd --no-interaction

Copilot uses AI. Check for mistakes.

# ---- Runtime stage ----
FROM php:8.3-fpm

RUN apt-get update && apt-get install -y \
nginx libpq-dev libicu-dev supervisor \
&& docker-php-ext-install intl pdo_pgsql opcache \
&& pecl install opentelemetry && docker-php-ext-enable opentelemetry \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

COPY --from=build /app /var/www/html
COPY docker/nginx/default.conf /etc/nginx/sites-available/default
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/php/php-production.ini /usr/local/etc/php/conf.d/99-production.ini
COPY docker/php/www-overrides.conf /usr/local/etc/php-fpm.d/zz-overrides.conf

RUN chown -R www-data:www-data /var/www/html/tmp /var/www/html/logs

EXPOSE 80

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
21 changes: 21 additions & 0 deletions testapp/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Development Dockerfile - source is volume-mounted
FROM php:8.3-fpm

RUN apt-get update && apt-get install -y \
git unzip libpq-dev libicu-dev nginx supervisor \
&& docker-php-ext-install intl pdo_pgsql opcache \
&& pecl install opentelemetry && docker-php-ext-enable opentelemetry \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

COPY docker/nginx/default.conf /etc/nginx/sites-available/default
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/php/www-overrides.conf /usr/local/etc/php-fpm.d/zz-overrides.conf

EXPOSE 80

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
80 changes: 80 additions & 0 deletions testapp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# CakePHP OTel Test App

[kaz29/cakephp-otel-plugin](https://github.com/kaz29/cakephp-otel-plugin) を Azure 環境にデプロイし、OpenTelemetry によるトレース・ログ収集を検証するためのテストアプリケーション。

## ローカル開発

```bash
docker compose up -d
```

`http://localhost:8765` でアクセス。
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documented local URL doesn’t match the Docker Compose port mapping. compose.yaml publishes the app on http://localhost:8080, but this README says http://localhost:8765.

Please update the README to reflect the actual exposed port (or adjust compose.yaml if 8765 is intended).

Suggested change
`http://localhost:8765` でアクセス。
`http://localhost:8080` でアクセス。

Copilot uses AI. Check for mistakes.

## Azure インフラデプロイ

### 前提

- Azure CLI (`az`) がインストール済みであること
- `az login` でログイン済みであること

### 環境変数の設定

```bash
export RESOURCE_GROUP=rg-otel-test
export DB_ADMIN_PASSWORD='<PostgreSQL管理者パスワード>'
```

### 1. リソースグループ作成

```bash
az group create --name "$RESOURCE_GROUP" --location japaneast
```

### 2. インフラデプロイ (初回)

初回はコンテナイメージがまだ無いため、Container App 以外のリソースを構築します。

```bash
az deployment group create \
--resource-group "$RESOURCE_GROUP" \
--template-file bicep/main.bicep \
--parameters bicep/parameters.bicepparam
```

### 3. コンテナイメージのビルド & プッシュ

```bash
ACR_NAME=$(az acr list --resource-group "$RESOURCE_GROUP" --query '[0].name' -o tsv)

az acr build \
--registry "$ACR_NAME" \
--image cakephp-otel-test-app:latest \
.
```

### 4. Container App のデプロイ

```bash
ACR_LOGIN_SERVER=$(az acr show --name "$ACR_NAME" --query loginServer -o tsv)

CONTAINER_IMAGE_NAME="${ACR_LOGIN_SERVER}/cakephp-otel-test-app:latest" \
az deployment group create \
--resource-group "$RESOURCE_GROUP" \
--template-file bicep/main.bicep \
--parameters bicep/parameters.bicepparam
```

### 5. デプロイ確認

```bash
az deployment group show \
--resource-group "$RESOURCE_GROUP" \
--name main \
--query properties.outputs
```

### リソース削除

```bash
az group delete --name "$RESOURCE_GROUP" --yes --no-wait
```
Loading
Loading