con un clic
log-design
ログ設計の妥当性チェック。一般的なログ基準と日本国内法的要件(電子帳簿保存法・個人情報保護法等)に基づき、ログ設計・実装を検証する。
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
ログ設計の妥当性チェック。一般的なログ基準と日本国内法的要件(電子帳簿保存法・個人情報保護法等)に基づき、ログ設計・実装を検証する。
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
プッシュ前に必ず実行。静的チェック・テスト・統合レビュー含む6ペルソナレビューを最低2サイクル実施し、自己改善確認後のみpush可能。
Git worktree を使った並列開発時に使用。配置・ポート割当・環境コピー・クリーンアップを標準化する。
Use when completing tasks, implementing major features, or before merging to verify work meets requirements
作業完了前にセッション内の改善ポイントを抽出し、ユーザー承認後にルール・スキル・ドキュメントへ反映する。
開発サーバー・E2E・ブラウザ検証時に使用。既存プロセスを停止してからプロジェクト指定ポートで起動し、作業後に必ず停止する。
Use when creating new skills, editing existing skills, or verifying skills work before deployment
| name | log-design |
| description | ログ設計の妥当性チェック。一般的なログ基準と日本国内法的要件(電子帳簿保存法・個人情報保護法等)に基づき、ログ設計・実装を検証する。 |
プロジェクトのログ設計が一般的な基準と法的要件を満たしているか体系的にチェックし、不足があれば実装パターンを提示する。
参照: セキュリティ関連のログルールは
documents/development/coding-rules/common-rules.mdSection 4 も併せて確認すること。
Step 1: 現状分析(既存のログ設定・出力を確認)
↓
Step 2: 一般的ログ基準チェック
↓
Step 3: 法的要件チェック
↓
Step 4: 不足箇所の実装パターン提示
↓
Step 5: レポート出力
以下を確認する:
| レベル | 用途 | 例 |
|---|---|---|
| ERROR | システム異常、復旧不可能なエラー | DB接続失敗、外部API障害、未処理例外 |
| WARN | 想定内だが注意が必要な事象 | リトライ発生、閾値超過、非推奨API使用 |
| INFO | ビジネス上重要なイベント | ユーザーログイン/ログアウト、決済完了、重要な状態遷移 |
| DEBUG | 開発・調査用の詳細情報 | リクエスト/レスポンス詳細、SQL実行詳細(本番では無効化) |
Spring Boot + Logback (JSON形式):
// logback-spring.xml で net.logstash.logback.encoder.LogstashEncoder を使用
// または logback-spring.xml で JSON パターンを定義
// 出力例:
// {
// "timestamp": "2025-01-08T10:00:00.000+09:00",
// "level": "INFO",
// "logger": "com.example.service.PaymentService",
// "message": "Payment completed",
// "traceId": "abc123",
// "userId": "user-001",
// "action": "PAYMENT_COMPLETE",
// "amount": 10000,
// "paymentId": "pay-001"
// }
@Slf4j
@Service
public class PaymentService {
public void completePayment(Payment payment) {
// MDC にトレース情報をセット
MDC.put("action", "PAYMENT_COMPLETE");
MDC.put("paymentId", payment.getId().toString());
log.info("Payment completed: amount={}", payment.getAmount());
MDC.clear();
}
}
Next.js (API Routes / Server Actions):
// lib/logger.ts - 構造化ログユーティリティ
import pino from 'pino';
export const logger = pino({
level: process.env.LOG_LEVEL || 'info',
formatters: {
level: (label) => ({ level: label }),
},
timestamp: pino.stdTimeFunctions.isoTime,
});
// 使用例: API Route
export async function POST(request: Request) {
const body = await request.json();
logger.info(
{ action: 'ORDER_CREATED', orderId: body.id, userId: session.userId },
'Order created'
);
}
ログに出力してはいけない情報:
マスキング実装例 (Java):
public class PiiMasker {
public static String maskEmail(String email) {
if (email == null) return "***";
int atIndex = email.indexOf('@');
if (atIndex < 0) return "***"; // @がない場合は全マスク
if (atIndex <= 1) return "***@" + email.substring(atIndex + 1);
return email.charAt(0) + "***@" + email.substring(atIndex + 1);
}
public static String maskPhone(String phone) {
if (phone == null || phone.length() < 4) return "****";
return "****" + phone.substring(phone.length() - 4);
}
public static String maskCardNumber(String cardNumber) {
if (cardNumber == null) return "****";
String digits = cardNumber.replaceAll("[^0-9]", "");
if (digits.length() < 4) return "****";
return "****-****-****-" + digits.substring(digits.length() - 4);
}
public static String maskMyNumber(String myNumber) {
// マイナンバーは12桁の数字。全桁マスクが原則(部分表示も不可)
if (myNumber == null) return "************";
return "************";
}
}
ユーザー入力をログ出力する際、改行コード(CR/LF)を含む文字列がそのまま出力されると、偽のログ行が挿入される(ログインジェクション/ログフォージング)。監査ログの信頼性を損なうため、必ずサニタイズする。
public static String sanitizeForLog(String input) {
if (input == null) return "";
return input.replaceAll("[\\r\\n]", " ");
}
// 使用例
log.info("User search: query={}", sanitizeForLog(userInput));
function sanitizeForLog(input: string): string {
return input.replace(/[\r\n]/g, ' ');
}
フロントエンド (Server-side only):
// 機密情報をクライアントサイドに送信しない
// - API RouteやServer Actionのログにのみ詳細情報を記録
// - クライアントには汎用エラーメッセージのみ返す
// - console.log/console.error は本番ビルドで除去する(eslint no-console)
| カテゴリ | ログ対象 | レベル |
|---|---|---|
| 認証 | ログイン成功/失敗、ログアウト、トークンリフレッシュ | INFO |
| 認可 | 権限不足によるアクセス拒否 | WARN |
| データ変更 | 重要データのCRUD操作(誰が・いつ・何を) | INFO |
| 決済 | 決済開始・完了・失敗 | INFO/ERROR |
| 外部連携 | 外部API呼び出し(リクエスト/レスポンス概要) | INFO |
| エラー | 未処理例外、システム障害 | ERROR |
該当条件: 電子的に授受した取引情報(注文書、請求書、領収書、見積書等に相当するデータ)を扱う場合
チェックリスト:
監査ログ実装パターン:
// 監査ログテーブル設計例
// audit_logs テーブル
// - id: UUID (PK)
// - entity_type: VARCHAR (対象エンティティ種別)
// - entity_id: UUID (対象エンティティID)
// - action: VARCHAR (CREATE/UPDATE/DELETE)
// - actor_id: UUID (操作者ID)
// - before_value: JSONB (変更前の値、NULLable)
// - after_value: JSONB (変更後の値)
// - created_at: TIMESTAMP WITH TIME ZONE (操作日時)
// Spring AOP で自動記録する実装パターン
@Aspect
@Component
@RequiredArgsConstructor
public class AuditLogAspect {
private final AuditLogRepository auditLogRepository;
@AfterReturning("@annotation(Auditable)")
public void logAudit(JoinPoint joinPoint) {
// 操作内容を自動記録
}
}
// 使用例
@Auditable
@Transactional
public OrderResponse createOrder(CreateOrderRequest request) {
// 注文作成処理
}
該当条件: 個人情報(氏名、メールアドレス、住所、電話番号等)を取り扱う場合
チェックリスト:
個人情報アクセスログ実装パターン:
// アクセスログ出力例
log.info("Personal data accessed: entity={}, entityId={}, fields={}, actor={}",
"Student", studentId, "name,email,phone", currentUserId);
該当条件: 広告・宣伝目的の電子メールを送信する場合
チェックリスト:
チェック結果に基づき、不足箇所について上記の実装パターンをプロジェクトのスタックに合わせて提示する。
チェック結果をMarkdownチェックリスト形式でコンソールに出力する:
## Log Design Check Report
### 一般的ログ基準
- [x] ログレベル基準が定義されている
- [ ] 構造化ログが導入されていない -> 実装パターンを提示
- [x] 機密情報マスキングが実装されている
### 法的要件(電子帳簿保存法)
- [x] 該当: 取引データを扱う
- [ ] タイムスタンプ要件: 未対応 -> 実装パターンを提示
- [x] 改ざん防止: 監査ログ実装済み
### 法的要件(個人情報保護法)
- [x] 該当: 個人情報を扱う
- [x] マスキング: 実装済み
- [ ] アクセスログ: 未実装 -> 実装パターンを提示
### 法的要件(特定電子メール法)
- [ ] 非該当(メール送信機能なし)
### Summary
- チェック項目: 12件
- 対応済み: 8件
- 要対応: 4件(実装パターン提示済み)