9.

MySQL / PostgreSQL / Laravel / Hibernate で SQL ログを出す方法まとめ

編集
この記事の要点
  • MySQL 全クエリログ: SET GLOBAL general_log = ON + general_log_file
  • スロークエリログ: slow_query_log = ON + long_query_time = 1
  • PostgreSQL: log_statement = all in postgresql.conf
  • Laravel: DB::enableQueryLog() または DB::listen()
  • Spring / Hibernate: logging.level.org.hibernate.SQL=DEBUG + BasicBinder=TRACE

MySQL のクエリログ

一般クエリログ(全 SQL 記録)

-- 現在の状態確認
SHOW VARIABLES LIKE 'general_log%';
-- general_log         | OFF
-- general_log_file    | /var/lib/mysql/host.log

-- 動的に有効化(再起動不要)
SET GLOBAL general_log_file = '/tmp/mysql_query.log';
SET GLOBAL general_log = 'ON';

-- 確認
SELECT * FROM mysql.general_log ORDER BY event_time DESC LIMIT 10;

-- ログ出力先をテーブルに(FILE / TABLE / NONE)
SET GLOBAL log_output = 'TABLE';

-- 無効化
SET GLOBAL general_log = 'OFF';

パフォーマンスに影響するので本番では一時的にのみ使用。

スロークエリログ

-- 状態確認
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

-- 1 秒以上かかるクエリを記録
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

-- インデックス未使用も記録
SET GLOBAL log_queries_not_using_indexes = 'ON';

-- 確認
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

my.cnf で恒久設定

# /etc/mysql/my.cnf or /etc/my.cnf
[mysqld]
general_log = 1
general_log_file = /var/log/mysql/general.log

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1

# 再起動が必要
# systemctl restart mysql

PostgreSQL のクエリログ

# postgresql.conf
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'

# 何をログに出すか
log_statement = 'all'        # all / ddl / mod / none
log_min_duration_statement = 1000  # ms。1秒以上のクエリ

# 詳細フォーマット
log_line_prefix = '%t [%p]: user=%u,db=%d,app=%a,client=%h '
log_duration = on            # 実行時間も記録

# 反映
# SELECT pg_reload_conf();

セッション単位での有効化

-- セッション中だけ詳細ログ
SET log_statement = 'all';
SET log_min_duration_statement = 0;

-- pg_stat_statements 拡張で集計
CREATE EXTENSION pg_stat_statements;
SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Laravel での SQL ログ

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

// 方法1: enableQueryLog + getQueryLog
DB::enableQueryLog();
User::where('id', 1)->get();
$queries = DB::getQueryLog();
// [['query' => 'select * from users where id = ?', 'bindings' => [1], 'time' => 1.23]]

// 方法2: DB::listen でリアルタイムログ
DB::listen(function ($query) {
    Log::info('[SQL] ' . $query->sql, [
        'bindings' => $query->bindings,
        'time_ms' => $query->time,
    ]);
});

// AppServiceProvider::boot() で常時有効化(開発環境のみ)
public function boot(): void
{
    if (app()->environment('local')) {
        DB::listen(function ($q) {
            $sql = vsprintf(str_replace('?', '%s', $q->sql), array_map(
                fn($v) => is_string($v) ? "'$v'" : $v,
                $q->bindings
            ));
            Log::channel('sql')->info("[{$q->time}ms] $sql");
        });
    }
}

Telescope / Debugbar 利用

# Laravel Telescope(公式デバッグツール)
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migrate
# → /telescope で全 SQL 確認可能

# Laravel Debugbar(画面下に表示)
composer require barryvdh/laravel-debugbar --dev
# .env で APP_DEBUG=true なら自動表示

Spring Boot / Hibernate での SQL ログ

# application.yml
spring:
  jpa:
    show-sql: true                  # 標準出力に SQL
    properties:
      hibernate:
        format_sql: true            # 整形
        use_sql_comments: true      # JPQL コメント付き

logging:
  level:
    org.hibernate.SQL: DEBUG                                    # SQL 本体
    org.hibernate.orm.jdbc.bind: TRACE                          # バインドパラメータ (Hibernate 6+)
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE        # バインド (Hibernate 5)
    org.springframework.jdbc.core.JdbcTemplate: DEBUG           # Spring JDBC
    org.springframework.jdbc.core.StatementCreatorUtils: TRACE  # JDBC バインド

P6Spy で更に詳細



    p6spy
    p6spy
    3.9.1
# application.properties
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/mydb
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver

Node.js (Sequelize / Prisma / TypeORM)

// Sequelize
const sequelize = new Sequelize(uri, {
  logging: console.log,  // 全 SQL を console に
  logging: (sql, time) => logger.debug({ sql, time }),
});

// TypeORM
new DataSource({
  type: 'mysql',
  logging: ['query', 'error', 'schema'],
  logger: 'advanced-console',
});

// Prisma (schema.prisma で datasource 設定後)
const prisma = new PrismaClient({
  log: [{ emit: 'event', level: 'query' }],
});
prisma.$on('query', (e) => {
  console.log('Query: ' + e.query);
  console.log('Duration: ' + e.duration + 'ms');
});

本番環境での注意

  • 全クエリログはI/O が増えて性能劣化、本番では一時的に or スロークエリのみ
  • 個人情報(メール / パスワードハッシュ)がログに乗る可能性 → アクセス権限管理を厳格に
  • ログローテーションを設定(logrotate 等)してディスク満杯を防ぐ
  • 本番で詳細ログを取るなら pg_stat_statements / performance_schema のような集計型がベター

FAQ

Q: ORM のログでバインド変数が ? のままで実値が見えない
A: フレームワーク別に詳細ログレベルが用意されています(Hibernate: BasicBinder=TRACE、Laravel: DB::listen で bindings を取れる)。

Q: クエリの実行計画も見たい
A: EXPLAIN SELECT ...(MySQL/PostgreSQL)。本番遅延調査には必須です。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 環境構築とプロジェクト/アプリの作成
  2. MVC(MVT)のそれぞれの使い方と説明
  3. データベースへの接続と操作
  4. Django Administration
  5. git管理
  6. エラー一覧
  7. バージョンの確認方法
  8. ログ出力方法
  9. SQLのログ出力方法
  10. ログのローテート設定
  11. settings.pyの定数にアクセスする方法
  12. 本番環境へのインストールとアプリのデプロイ(apache編)
  13. 本番環境へのインストールとアプリのデプロイ(nginx編)
  14. djangoアプリの本番の開始URLを変更する
  15. 静的(static)ファイルの置き場所と読み込み(画像、css、js )
  16. CSRFトークンをAjaxで使用する方法
  17. ajaxの使用例(POST編)
  18. ファイルのアップロードとファイルの名前
  19. クイックスタート/チュートリアル
  20. ログイン機能
  21. テンプレート側のログイン判定
  22. ビュー側のログイン判定
  23. 管理者ユーザーの作成/判定と管理画面
  24. モデルのjson化とレスポンス
  25. runserverでポートを指定する方法
  26. cronによるバッチ実行
  27. テンプレートで利用する共通のcontextを定義する方法
  28. プログラムが本番サーバーで反映されない場合の対処法
  29. APIの作成
  30. cron用コマンド・ファイルの作成