運用ガイダンス
idp-server 固有の運用知識とトラブルシューティング手順。
📌 本ドキュメントの責任範囲
✅ 本ドキュメントで扱う内容
- ヘルスチェック: Actuator エンドポイント、テナント固有ヘルスチェック
- ログ運用: JSON構造化ログ、MDCフィールド、リクエストデバッグログ
- アプリケーションライフサイクル: Graceful Shutdown、マルチインスタンス運用
- 定期メンテナンスタスク: pg_cron ジョブの監視
- トラブルシューティング: 起動失敗、Redis障害、RLS問題、パフォーマンス
❌ 本ドキュメントで扱わない内容(利用者の責任範囲)
- インフラ監視: CloudWatch、Datadog等の監視ツール設定
- アラート設計: 閾値設定、通知チャネル設計
- ログ収集基盤: Fluentd、CloudWatch Logs等のログ転送設定
- 性能チューニング: OS・JVM・データベースレベルの最適化
1. ヘルスチェック
1.1 Actuator エンドポイント
idp-server は Spring Boot Actuator を使用してヘルスチェックエンドポイントを提供します。Actuator はアプリケーションと同じポート(デフォルト: 8080)で動作します。
| エンドポイント | 用途 | チェック対象 |
|---|---|---|
GET /actuator/health | 総合ヘルスチェック | DB + Redis + その他すべて |
GET /actuator/health/readiness | Readiness Probe | DB接続、Redis接続 |
GET /actuator/health/liveness | Liveness Probe | アプリケーション生存確認(ping) |
レスポンス例:
正常時:
{
"status": "UP"
}
異常時:
{
"status": "DOWN"
}
有効な Actuator エンドポイント:
application.yaml の設定により、公開されるエンドポイントは health と info のみです。
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true
show-details: when-authorized
health:
readiness-state:
enabled: true
liveness-state:
enabled: true
1.2 テナント固有ヘルスチェック
Actuator とは別に、テナント単位のヘルスチェックエンドポイントが提供されています。テナントごとのデータベース接続を検証できます。
GET /{tenant-id}/v1/health
レスポンス例:
正常時(HTTP 200):
{
"status": "UP"
}
異常時(HTTP 503):
{
"status": "DOWN"
}
用途: 特定テナントに対するリクエストが正常に処理可能かを確認する際に使用します。テナント設定の問題やRLS接続の確認に有効です。
1.3 Kubernetes 設定例
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: idp-server
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
failureThreshold: 3
ポイント:
readinessProbeはDB・Redisへの接続を検証するため、initialDelaySecondsをアプリケーション起動完了まで十分に設定してくださいlivenessProbeはアプリケーションの生存のみを確認するため、readinessProbeより長い間隔で問題ありません
2. ログ運用
2.1 JSON 構造化ログ
idp-server は Logback + LogstashEncoder を使用し、すべてのログをJSON形式で出力します。プロファイルによる出力形式の切り替えはなく、常にJSON出力です。
<!-- logback-spring.xml -->
<configuration>
<appender name="JSON_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>true</includeContext>
<includeMdc>true</includeMdc>
<timestampPattern>yyyy-MM-dd HH:mm:ss.SSS</timestampPattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="JSON_CONSOLE"/>
</root>
</configuration>
出力例:
{
"@timestamp": "2025-01-15 10:30:45.123",
"@version": "1",
"message": "Authorization request processed",
"logger_name": "org.idp.server.core.oidc",
"thread_name": "http-nio-8080-exec-1",
"level": "INFO",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "tenant-abc-123",
"client_id": "my-client",
"user_id": "user-xyz-789"
}
2.2 MDC フィールド一覧
すべてのログエントリに自動付与されるMDC(Mapped Diagnostic Context)フィールドです。ログ検索・フィルタリングに活用してください。
| MDCキー | 説明 | 設定タイミング |
|---|---|---|
request_id | リクエスト固有のUUID | リクエスト受信時に自動生成 |
tenant_id | テナント識別子 | テナント解決後 |
client_id | OAuthクライアントID | クライアント認証後 |
user_id | ユーザー内部ID | ユーザー認証後 |
user_ex_sub | ユーザー外部サブジェクト | ユーザー認証後 |
user_name | ユーザー名 | ユーザー認証後 |
セキュリティイベントログでは、StructuredJsonLogFormatter が独自のJSON構造に log_type フィールドを直接付与します(MDC経由ではありません)。
log_type 値 | 出力元 | 説明 |
|---|---|---|
security_event | StructuredJsonLogFormatter | 認証成功/失敗、OAuth操作等のセキュリティイベント |
ログ検索例(jq):
# 特 定テナントのエラーログを抽出
cat app.log | jq 'select(.tenant_id == "tenant-abc-123" and .level == "ERROR")'
# 特定リクエストのトレース
cat app.log | jq 'select(.request_id == "550e8400-e29b-41d4-a716-446655440000")'
# セキュリティイベントのみ抽出
cat app.log | jq 'select(.log_type == "security_event")'
# 認証失敗イベントの抽出
cat app.log | jq 'select(.log_type == "security_event" and (.tags | index("failure")))'
2.3 ログレベル設定
パッケージ単位でログレベルを環境変数で制御できます。
| 環境変数 | 対象 | デフォルト |
|---|---|---|
LOGGING_LEVEL_ROOT | アプリケーション全体 | info |
LOGGING_LEVEL_WEB | Spring Web | info |
LOGGING_LEVEL_IDP_SERVER_PLATFORM | プラットフォーム基盤 | info |
LOGGING_LEVEL_IDP_SERVER_AUTHENTICATION_INTERACTORS | 認証インタラクション | info |
LOGGING_LEVEL_IDP_SERVER_CONTROL_PLANE | 管理API | info |
LOGGING_LEVEL_IDP_SERVER_CORE_OIDC | OIDC コア処理 | info |
LOGGING_LEVEL_IDP_SERVER_CORE_OPENID | OpenID コア処理 | info |
LOGGING_LEVEL_IDP_SERVER_CORE_ADAPTERS | アダプター層 | info |
LOGGING_LEVEL_IDP_SERVER_CORE_EXTENSION | コア拡張 | info |
LOGGING_LEVEL_IDP_SERVER_EMAIL_AWS | AWS メール送信 | info |
LOGGING_LEVEL_IDP_SERVER_FEDERATION | 外部IdP連携 | info |
LOGGING_LEVEL_IDP_SERVER_NOTIFICATION_PUSH_FCM | FCM プッシュ通知 | info |
LOGGING_LEVEL_IDP_SERVER_SECURITY_EVENT_HOOK_SSF | SSF セキュリティイベントフック | info |
LOGGING_LEVEL_IDP_SERVER_SECURITY_EVENT_HOOKS | セキュリティイベントフック | info |
LOGGING_LEVEL_IDP_SERVER_ADAPTERS_SPRING_BOOT | Spring Boot アダプター | info |
LOGGING_LEVEL_IDP_SERVER_USECASES | ユースケース層 | info |
LOGGING_LEVEL_IDP_SERVER_AUTHENTICATORS_WEBAUTHN4J | WebAuthn4J 認証器 | info |
LOGGING_LEVEL_IDP_SERVER_HTTP_REQUEST_EXECUTOR | 外部HTTP通信 | info |
LOGGING_LEVEL_REQUEST_RESPONSE_LOGGING_FILTER | リクエスト/レスポンスログ | info |
本番環境推奨: info(デフォルト)。debug への変更は一時的な調査時のみ使用し、調査完了後に戻してください。
2.4 リクエスト/レスポンスデバッグログ
OAuth/OIDC エンドポイントのHTTPリクエスト・レスポンスの詳細をログ出力する機能です。外部サービスとの連携問題を調査する際に使用します。
デフォルトでは無効 です。有効化するには以下の2つの設定が必要です。
1. プロパティ有効化:
IDP_LOGGING_REQUEST_RESPONSE_ENABLED=true
2. ログレベルを DEBUG に設定:
LOGGING_LEVEL_REQUEST_RESPONSE_LOGGING_FILTER=debug
設定パラメータ:
| 環境変数 | 説明 | デフォルト |
|---|---|---|
IDP_LOGGING_REQUEST_RESPONSE_ENABLED | 有効/無効 | false |
IDP_LOGGING_REQUEST_RESPONSE_MASK_TOKENS | トークンマスク | true |
IDP_LOGGING_REQUEST_RESPONSE_MAX_BODY_SIZE | 最大ボディサイズ(バイト) | 10000 |
IDP_LOGGING_REQUEST_RESPONSE_ENDPOINTS | 対象エンドポイント | /v1/tokens,/v1/authorizations,/v1/backchannel/authentications,/v1/userinfo |
自動マスク対象パラメータ:
access_token,refresh_token,id_token,client_secret,password
⚠️ 注意: この機能はリクエスト・レスポンスの全ボディをログに記録します。本番環境での常時有効化は推奨しません。問題調査時に一時的に有効化し、調査完了後に無効に戻してください。
2.5 監査ログ
idp-server は認証・認可操作の監査ログを非同期で記録します。
非同期処理の仕様:
- 監査ログは
ThreadPoolTaskExecutorにより非同期で処理されます - キューが満杯になった場合、リトライキューに退避されます
リトライ仕様:
- リトライ間隔: 60秒
- 最大リトライ回数: 3回
- 最大リトライ超過時: ログ出力して破棄
関連する環境変数:
| 環境変数 | 説明 | デフォルト |
|---|---|---|
AUDIT_LOG_CORE_POOL_SIZE | コアスレッド数 | 5 |
AUDIT_LOG_MAX_POOL_SIZE | 最大スレッド数 | 30 |
AUDIT_LOG_QUEUE_CAPACITY | キュー容量 | 5000 |
Graceful Shutdown 時の動作: アプリケーション停止時、リトライキューに残っている監査ログのフラッシュを試みます。ただし、DB接続がすでに切断されている場合、すべてのログの処理は保証されません。
3. アプリケーションライフサイクル
3.1 Graceful Shutdown
idp-server は Kubernetes 環境での安全なシャットダウンのために、4段階のGraceful Shutdown機構を実装しています。
シャットダウンシーケンス:
SIGTERM受信
├── 1. GracefulShutdownLifecycle(5秒)
│ ├── Readiness Probe が DOWN に遷移
│ └── Kubernetes が Service エンドポイントから Pod を削除するのを待機
├── 2. Tomcat GracefulShutdown(最大30秒)
│ └── 処理中の HTTP リクエスト完了を待機
├── 3. ThreadPoolTaskExecutor シャットダウン(各最大30秒)
│ └── 3つの executor(セキュリティイベント/監査ログ/ユーザーライフサイクル)が順次停止
│ 各タスクは通常数ms で完了するため、実測では数秒以内に終了
└── 4. RetryScheduler @PreDestroy
└── リトライキューに残っているイベントのフラッシュを試行
(DB接続が切断済みの場合、処理は保証されない)
設定パラメータ:
| 設定 | 環境変数 | デフォルト | 説明 |
|---|---|---|---|
| シャットダウンディレイ | IDP_SERVER_SHUTDOWN_DELAY | 5s | K8sエンドポイント削除待機時間 |
| Tomcat グレースフル停止タイムアウト | — | 30s | 処理中リクエストの完了待機時間 |
| 非同期タスク完了待機 | — | 各30s | ThreadPoolTaskExecutor のタスク完了待機時間(3つの executor が順次停止、理論上最大90秒だが通常は数秒で完了) |
Kubernetes 設定例:
spec:
terminationGracePeriodSeconds: 70 # delay(5s) + tomcat-graceful(30s) + executor-await(30s) + margin(5s)
containers:
- name: idp-server
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"] # shutdown delay と一致させる
ポイント:
terminationGracePeriodSecondsは「シャットダウンディレイ(5s) + Tomcat グレースフル停止タイムアウト(30s) + 非同期タスク完了待機(30s) + マージン」以上に設定してくださいpreStopのsleep値はIDP_SERVER_SHUTDOWN_DELAYと一致させてください
3.2 マルチインスタンスデプロイ
idp-server はステートレス設計のため、複数インスタンスの並行稼働が可能です。
アーキテクチャ:
┌──────────────────┐
│ Load Balancer │
└──────┬───────────┘
┌─────────┼─────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Pod 1 │ │ Pod 2 │ │ Pod 3 │
│idp-server│ │idp-server│ │idp-server│
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
┌──────┴───────────┴───────────┴──────┐
│ Redis (セッション共有) │
└─────────────────────────────────────┘
┌──────┴───────────┴───────────┴──────┐
│ PostgreSQL (データ共有/RLS) │
└─────────────────────────────────────┘
設計上の特徴:
- セッション: Redis に格納されるため、全インスタンスで共有
- データ: PostgreSQL + RLS によりテナント分離を維持
- スティッキーセッション: 不要(ロードバランサーでのセッション固定は不要)
- スケーリング: HPA(Horizontal Pod Autoscaler)による自動スケール可能
4. 定期メンテナンスタスク
4.1 pg_cron ジョブ一覧
idp-server では PostgreSQL の pg_cron 拡張を使用して定期タスクを実行しています。
| ジョブ名 | スケジュール | 対象DB | 処理内容 |
|---|---|---|---|
partman-maintenance | 毎日 02:00 UTC | idpserver | パーティション作成・削除(pg_partman) |
archive-processing | 毎日 03:00 UTC | idpserver | アーカイブパーティションの外部エクスポート |
実行順序の設計:
partman-maintenance(02:00)が先に実行され、保持期間を超えたパーティションをアーカイブスキーマに退避archive-processing(03:00)が1時間後に実行され、アーカイブスキーマのテーブルを外部ストレージにエクスポート- エクスポート成功後にテーブルを削除、失敗時は翌日リトライ
📝 Note: デフォルトではエクスポート関数はスタブ実装(常に
FALSEを返す)のため、アーカイブスキーマにテーブルが蓄積されます。クラウド環境に応じたエクスポートロジックの実装が必要です。詳細は データベース設定 を参照してください。
4.2 ジョブ監視
ジョブ登録状態の確認:
-- pg_cron ジョブ一覧(postgres DBで実行)
SELECT jobid, jobname, schedule, command, database, username, active
FROM cron.job
WHERE username = CURRENT_USER;
ジョブ実行履歴の確認:
-- 直近の実行結果(postgres DBで実行)
SELECT jobid, runid, job_pid, database, username, command,
status, return_message,
start_time, end_time
FROM cron.job_run_details
ORDER BY start_time DESC
LIMIT 20;
-- 失敗したジョブのみ抽出
SELECT jobid, runid, status, return_message, start_time
FROM cron.job_run_details
WHERE status = 'failed'
ORDER BY start_time DESC
LIMIT 10;
アラート用クエリ:
idp-server にはジョブ失敗時の通知機構は含まれていません。監視ツール(Datadog、CloudWatch 等)のカスタムクエリ監視で以下のクエリを定期実行し、failed_count > 0 でアラートを発出してください。
-- 直近24時間のジョブ失敗検出(postgres DBで実行)
SELECT COUNT(*) AS failed_count
FROM cron.job_run_details d
JOIN cron.job j ON d.jobid = j.jobid
WHERE j.jobname IN ('partman-maintenance', 'archive-processing')
AND d.status = 'failed'
AND d.start_time > now() - interval '24 hours';
パーティション一覧の確認:
-- 現在のパーティション一覧(idpserver DBで実行)
SELECT parent_table, partition_tablename, partition_range
FROM partman.show_partitions('public.audit_log')
ORDER BY partition_range;
-- アーカイブスキーマのテーブル蓄積確認
SELECT table_name, pg_size_pretty(pg_total_relation_size('archive.' || table_name))
FROM information_schema.tables
WHERE table_schema = 'archive'
ORDER BY table_name;