From 51eacbcd3557d110ce3bbae7b1d8a35b5b108fd5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 12:18:16 +0000 Subject: [PATCH 1/6] =?UTF-8?q?README.md=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit プロジェクト概要、構成、インストール手順、設定、使い方、 PHP関数リファレンス、ログ形式をまとめたREADMEを追加。 https://claude.ai/code/session_014xLvguaiUykzwTi2VzaA6g --- README.md | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6989456 --- /dev/null +++ b/README.md @@ -0,0 +1,140 @@ +# MariaDB Profiler for PHP + +PHP拡張モジュールとして動作するMariaDB/MySQLクエリプロファイラです。PHPの`mysqlnd`ドライバにフックし、実行される全SQLクエリをインターセプトして記録・分析します。 + +PDO、mysqli、Laravel Eloquentなど、mysqlndを利用するすべてのデータベースアクセス方法に対応しています。 + +## 構成 + +| コンポーネント | 概要 | +|---|---| +| `ext/mariadb_profiler/` | PHP拡張モジュール (C言語) | +| `cli/` | CLIプロファイラ管理ツール (PHP) | +| `demo/` | Docker環境のWebデモ (Laravel + WebSocket) | +| `jetbrains-plugin/` | JetBrains IDEプラグイン (Kotlin) | + +## 機能 + +- **クエリインターセプト** — mysqlndレベルで全SQLクエリをキャプチャ +- **コンテキストタグ** — スタック型タグでクエリをビジネスロジック単位にグループ化 +- **PHPバックトレース** — 任意の深さでコールスタックを記録 +- **プリペアドステートメント対応** — バインドパラメータも記録 (PHP 7.0+) +- **SQL解析** — テーブル名・カラム名の自動抽出 +- **ジョブ管理** — 複数プロファイリングセッションの同時実行・親子関係管理 +- **クロスプラットフォーム** — Linux / macOS / Windows対応 + +## 要件 + +| コンポーネント | 要件 | +|---|---| +| PHP拡張 | PHP 5.3 〜 8.4+、mysqlnd | +| CLIツール | PHP 5.3+、Composer | +| デモ | Docker、Docker Compose | + +## インストール + +### PHP拡張のビルド + +```bash +cd ext/mariadb_profiler +phpize +./configure --enable-mariadb_profiler +make +sudo make install +``` + +php.iniに以下を追加: + +```ini +extension=mariadb_profiler.so +mariadb_profiler.enabled=1 +mariadb_profiler.log_dir=/var/log/mariadb_profiler +``` + +### CLIツール + +```bash +composer install +``` + +## 設定 (php.ini) + +```ini +mariadb_profiler.enabled = 1 ; 拡張の有効化 +mariadb_profiler.log_dir = /tmp/mariadb_profiler ; ログ出力先 +mariadb_profiler.raw_log = 1 ; テキスト形式のログ出力 +mariadb_profiler.job_check_interval = 1 ; jobs.jsonのチェック間隔 (秒) +mariadb_profiler.trace_depth = 0 ; バックトレースの深さ (0=無効) +``` + +## 使い方 + +### プロファイリングジョブの操作 + +```bash +# ジョブの開始 +php cli/mariadb_profiler.php job start [] + +# ジョブの終了 +php cli/mariadb_profiler.php job end + +# ジョブ一覧 +php cli/mariadb_profiler.php job list + +# 解析済みクエリの表示 +php cli/mariadb_profiler.php job show [--tag=] + +# 生ログの表示 +php cli/mariadb_profiler.php job raw + +# JSON形式でエクスポート +php cli/mariadb_profiler.php job export + +# タグ別サマリー +php cli/mariadb_profiler.php job tags + +# 呼び出し元サマリー +php cli/mariadb_profiler.php job callers + +# 完了済みジョブの削除 +php cli/mariadb_profiler.php job purge +``` + +### PHPコード内でのタグ付け + +```php +// タグをプッシュ +mariadb_profiler_tag('checkout_flow'); + +// ここで実行されるクエリに 'checkout_flow' タグが付与される +$db->query('SELECT * FROM orders WHERE user_id = ?'); + +// 現在のタグを取得 +$tag = mariadb_profiler_get_tag(); // 'checkout_flow' + +// タグをポップ +mariadb_profiler_untag(); +``` + +### デモ環境 + +```bash +cd demo +docker compose up --build +# http://localhost:8080 にアクセス +``` + +## PHP関数リファレンス + +| 関数 | 説明 | +|---|---| +| `mariadb_profiler_tag(string $tag): void` | コンテキストタグをスタックにプッシュ | +| `mariadb_profiler_untag(?string $tag = null): ?string` | タグをポップ (指定タグまで巻き戻し可) | +| `mariadb_profiler_get_tag(): ?string` | 現在のタグを取得 (未設定時はnull) | + +## ログ形式 + +ジョブごとに2種類のファイルが生成されます: + +- `{job_key}.raw.log` — 1行1クエリのテキスト形式 (タイムスタンプ、ステータス、タグ、トレース付き) +- `{job_key}.jsonl` — テーブル名・カラム名を含む解析済みJSON形式 From 0c30887a95aa863715c0e06a492743a171f44b2d Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 12:20:52 +0000 Subject: [PATCH 2/6] Rewrite README in English https://claude.ai/code/session_014xLvguaiUykzwTi2VzaA6g --- README.md | 116 +++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 6989456..558720a 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,39 @@ # MariaDB Profiler for PHP -PHP拡張モジュールとして動作するMariaDB/MySQLクエリプロファイラです。PHPの`mysqlnd`ドライバにフックし、実行される全SQLクエリをインターセプトして記録・分析します。 +A MariaDB/MySQL query profiler that runs as a PHP extension. It hooks into PHP's `mysqlnd` driver to intercept, record, and analyze all executed SQL queries. -PDO、mysqli、Laravel Eloquentなど、mysqlndを利用するすべてのデータベースアクセス方法に対応しています。 +Works with any database access method that uses mysqlnd, including PDO, mysqli, and Laravel Eloquent. -## 構成 +## Components -| コンポーネント | 概要 | +| Component | Description | |---|---| -| `ext/mariadb_profiler/` | PHP拡張モジュール (C言語) | -| `cli/` | CLIプロファイラ管理ツール (PHP) | -| `demo/` | Docker環境のWebデモ (Laravel + WebSocket) | -| `jetbrains-plugin/` | JetBrains IDEプラグイン (Kotlin) | +| `ext/mariadb_profiler/` | PHP extension (C) | +| `cli/` | CLI profiler management tool (PHP) | +| `demo/` | Docker-based web demo (Laravel + WebSocket) | +| `jetbrains-plugin/` | JetBrains IDE plugin (Kotlin) | -## 機能 +## Features -- **クエリインターセプト** — mysqlndレベルで全SQLクエリをキャプチャ -- **コンテキストタグ** — スタック型タグでクエリをビジネスロジック単位にグループ化 -- **PHPバックトレース** — 任意の深さでコールスタックを記録 -- **プリペアドステートメント対応** — バインドパラメータも記録 (PHP 7.0+) -- **SQL解析** — テーブル名・カラム名の自動抽出 -- **ジョブ管理** — 複数プロファイリングセッションの同時実行・親子関係管理 -- **クロスプラットフォーム** — Linux / macOS / Windows対応 +- **Query interception** — Captures all SQL queries at the mysqlnd level +- **Context tags** — Stack-based tags to group queries by business logic +- **PHP backtrace** — Records call stacks at configurable depth +- **Prepared statement support** — Logs bound parameters (PHP 7.0+) +- **SQL analysis** — Automatic extraction of table and column names +- **Job management** — Concurrent profiling sessions with parent-child relationships +- **Cross-platform** — Linux / macOS / Windows -## 要件 +## Requirements -| コンポーネント | 要件 | +| Component | Requirements | |---|---| -| PHP拡張 | PHP 5.3 〜 8.4+、mysqlnd | -| CLIツール | PHP 5.3+、Composer | -| デモ | Docker、Docker Compose | +| Extension | PHP 5.3 – 8.4+, mysqlnd | +| CLI tool | PHP 5.3+, Composer | +| Demo | Docker, Docker Compose | -## インストール +## Installation -### PHP拡張のビルド +### Building the Extension ```bash cd ext/mariadb_profiler @@ -43,7 +43,7 @@ make sudo make install ``` -php.iniに以下を追加: +Add the following to php.ini: ```ini extension=mariadb_profiler.so @@ -51,90 +51,90 @@ mariadb_profiler.enabled=1 mariadb_profiler.log_dir=/var/log/mariadb_profiler ``` -### CLIツール +### CLI Tool ```bash composer install ``` -## 設定 (php.ini) +## Configuration (php.ini) ```ini -mariadb_profiler.enabled = 1 ; 拡張の有効化 -mariadb_profiler.log_dir = /tmp/mariadb_profiler ; ログ出力先 -mariadb_profiler.raw_log = 1 ; テキスト形式のログ出力 -mariadb_profiler.job_check_interval = 1 ; jobs.jsonのチェック間隔 (秒) -mariadb_profiler.trace_depth = 0 ; バックトレースの深さ (0=無効) +mariadb_profiler.enabled = 1 ; Enable the extension +mariadb_profiler.log_dir = /tmp/mariadb_profiler ; Log output directory +mariadb_profiler.raw_log = 1 ; Write raw text logs +mariadb_profiler.job_check_interval = 1 ; Interval to check jobs.json (seconds) +mariadb_profiler.trace_depth = 0 ; Backtrace depth (0 = disabled) ``` -## 使い方 +## Usage -### プロファイリングジョブの操作 +### Managing Profiling Jobs ```bash -# ジョブの開始 +# Start a job php cli/mariadb_profiler.php job start [] -# ジョブの終了 +# End a job php cli/mariadb_profiler.php job end -# ジョブ一覧 +# List jobs php cli/mariadb_profiler.php job list -# 解析済みクエリの表示 +# Show parsed queries php cli/mariadb_profiler.php job show [--tag=] -# 生ログの表示 +# Show raw log php cli/mariadb_profiler.php job raw -# JSON形式でエクスポート +# Export as JSON php cli/mariadb_profiler.php job export -# タグ別サマリー +# Show tag summary php cli/mariadb_profiler.php job tags -# 呼び出し元サマリー +# Show caller summary php cli/mariadb_profiler.php job callers -# 完了済みジョブの削除 +# Purge completed jobs php cli/mariadb_profiler.php job purge ``` -### PHPコード内でのタグ付け +### Tagging Queries in PHP ```php -// タグをプッシュ +// Push a tag mariadb_profiler_tag('checkout_flow'); -// ここで実行されるクエリに 'checkout_flow' タグが付与される +// Queries executed here are tagged with 'checkout_flow' $db->query('SELECT * FROM orders WHERE user_id = ?'); -// 現在のタグを取得 +// Get the current tag $tag = mariadb_profiler_get_tag(); // 'checkout_flow' -// タグをポップ +// Pop the tag mariadb_profiler_untag(); ``` -### デモ環境 +### Demo ```bash cd demo docker compose up --build -# http://localhost:8080 にアクセス +# Open http://localhost:8080 ``` -## PHP関数リファレンス +## PHP Function Reference -| 関数 | 説明 | +| Function | Description | |---|---| -| `mariadb_profiler_tag(string $tag): void` | コンテキストタグをスタックにプッシュ | -| `mariadb_profiler_untag(?string $tag = null): ?string` | タグをポップ (指定タグまで巻き戻し可) | -| `mariadb_profiler_get_tag(): ?string` | 現在のタグを取得 (未設定時はnull) | +| `mariadb_profiler_tag(string $tag): void` | Push a context tag onto the stack | +| `mariadb_profiler_untag(?string $tag = null): ?string` | Pop a tag (optionally unwind to a specific tag) | +| `mariadb_profiler_get_tag(): ?string` | Get the current tag (null if none) | -## ログ形式 +## Log Formats -ジョブごとに2種類のファイルが生成されます: +Two files are generated per job: -- `{job_key}.raw.log` — 1行1クエリのテキスト形式 (タイムスタンプ、ステータス、タグ、トレース付き) -- `{job_key}.jsonl` — テーブル名・カラム名を含む解析済みJSON形式 +- `{job_key}.raw.log` — One query per line in text format (with timestamp, status, tag, and trace) +- `{job_key}.jsonl` — Parsed JSON format with extracted table and column names From 1b9446b20544ef2f093c916bf13f46d05ebbb3cf Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 12:25:44 +0000 Subject: [PATCH 3/6] Skip CI when PR has no_run label Add job-level condition to tests, demo-e2e, plugin-build, and windows-build workflows so they are skipped when the pull request carries the "no_run" label. Push events are unaffected. https://claude.ai/code/session_014xLvguaiUykzwTi2VzaA6g --- .github/workflows/demo-e2e.yml | 1 + .github/workflows/plugin-build.yml | 1 + .github/workflows/tests.yml | 2 ++ .github/workflows/windows-build.yml | 1 + 4 files changed, 5 insertions(+) diff --git a/.github/workflows/demo-e2e.yml b/.github/workflows/demo-e2e.yml index 8ac71f8..f312d31 100644 --- a/.github/workflows/demo-e2e.yml +++ b/.github/workflows/demo-e2e.yml @@ -19,6 +19,7 @@ on: jobs: demo-e2e: + if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') name: Demo E2E (Docker + Selenium) runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/plugin-build.yml b/.github/workflows/plugin-build.yml index 0c56b54..df2ba0c 100644 --- a/.github/workflows/plugin-build.yml +++ b/.github/workflows/plugin-build.yml @@ -14,6 +14,7 @@ on: jobs: build: + if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') name: Build & Test Plugin runs-on: ubuntu-latest diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 62d0d0e..495c5d2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,6 +8,7 @@ on: jobs: test-cli: + if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') name: CLI Tests (PHP ${{ matrix.php-version }}) runs-on: ubuntu-latest strategy: @@ -42,6 +43,7 @@ jobs: run: php tests/test_integration.php build-extension: + if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') name: Build Extension (PHP ${{ matrix.php-version }}) runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 021c59c..e78252e 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -14,6 +14,7 @@ on: jobs: build-windows: + if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') name: Windows - PHP ${{ matrix.php }} ${{ matrix.ts }} ${{ matrix.arch }} runs-on: windows-${{ matrix.os }} defaults: From 14b765e21d9d460cce34c816ac722118f9c30edb Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 12:33:45 +0000 Subject: [PATCH 4/6] Auto-cancel superseded workflow runs on same branch Add concurrency groups to tests, demo-e2e, plugin-build, and windows-build workflows. When a new push arrives while a previous run is still in progress, the older run is automatically cancelled. https://claude.ai/code/session_014xLvguaiUykzwTi2VzaA6g --- .github/workflows/demo-e2e.yml | 4 ++++ .github/workflows/plugin-build.yml | 4 ++++ .github/workflows/tests.yml | 4 ++++ .github/workflows/windows-build.yml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/.github/workflows/demo-e2e.yml b/.github/workflows/demo-e2e.yml index f312d31..0a1950d 100644 --- a/.github/workflows/demo-e2e.yml +++ b/.github/workflows/demo-e2e.yml @@ -17,6 +17,10 @@ on: - '.github/workflows/demo-e2e.yml' workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: demo-e2e: if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') diff --git a/.github/workflows/plugin-build.yml b/.github/workflows/plugin-build.yml index df2ba0c..6727228 100644 --- a/.github/workflows/plugin-build.yml +++ b/.github/workflows/plugin-build.yml @@ -12,6 +12,10 @@ on: - 'jetbrains-plugin/**' - '.github/workflows/plugin-build.yml' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 495c5d2..96bf54a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,6 +6,10 @@ on: pull_request: branches: ['**'] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test-cli: if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index e78252e..4b946d2 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -12,6 +12,10 @@ on: - 'ext/**' - '.github/workflows/windows-build.yml' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build-windows: if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'no_run') From dff105d530c3b763edece9240ee53f0f9b8eacfc Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 12:43:55 +0000 Subject: [PATCH 5/6] Add JetBrains Plugin to release workflow Build the JetBrains plugin and include the .zip in release assets alongside the Linux .so and Windows .dll files. https://claude.ai/code/session_014xLvguaiUykzwTi2VzaA6g --- .github/workflows/release.yml | 37 +++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8bb165e..87a0717 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -160,12 +160,45 @@ jobs: name: php_mariadb_profiler-php${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }} path: dist\*.dll + # --------------------------------------------------------------------------- + # JetBrains Plugin build + # --------------------------------------------------------------------------- + build-plugin: + name: JetBrains Plugin + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Run tests + working-directory: jetbrains-plugin + run: ./gradlew test + + - name: Build plugin + working-directory: jetbrains-plugin + run: ./gradlew buildPlugin + + - uses: actions/upload-artifact@v4 + with: + name: mariadb-profiler-viewer-plugin + path: jetbrains-plugin/build/distributions/*.zip + if-no-files-found: error + # --------------------------------------------------------------------------- # Create GitHub Release # --------------------------------------------------------------------------- release: name: Create Release - needs: [build-linux, build-windows] + needs: [build-linux, build-windows, build-plugin] runs-on: ubuntu-latest permissions: contents: write @@ -181,7 +214,7 @@ jobs: - name: Collect release assets run: | mkdir -p release - find artifacts -type f \( -name "*.so" -o -name "*.dll" \) -exec cp {} release/ \; + find artifacts -type f \( -name "*.so" -o -name "*.dll" -o -name "*.zip" \) -exec cp {} release/ \; echo "=== Release assets ===" ls -lh release/ From c19cd34d82fdcf86fed1a25aa9b4e65f64c38cb0 Mon Sep 17 00:00:00 2001 From: kouhei Date: Tue, 17 Feb 2026 21:54:07 +0900 Subject: [PATCH 6/6] Add IntelliJ Plugin section to README Added section about IntelliJ plugin compatibility with images. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 558720a..ac20968 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ A MariaDB/MySQL query profiler that runs as a PHP extension. It hooks into PHP's Works with any database access method that uses mysqlnd, including PDO, mysqli, and Laravel Eloquent. +## IntelliJ Plugin Ready +ss0
+ss1
+ss2 + + + ## Components | Component | Description |