0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#0200(2025/07/25)スタックトレース完全入門

Posted at

スタックトレース完全入門

スタックトレースは「エラーが辿ってきた道筋」を可視化するデバッグの羅針盤である。


1. スタックトレースとは何か

  • 定義: 例外が発生した瞬間の 呼び出し階層 (stack frame) を上から順に文字列化したもの。

  • 含まれる情報

    • ファイルパス・行番号
    • 関数/メソッド名
    • 呼び出し順序(上位 → 下位)
  • 得られるメリット

    • バグ再現の最短手掛かり
    • 影響範囲の特定 (自前コード or ライブラリ?)
    • パフォーマンス・責務分割のヒント
Traceback (most recent call last):
  File "/app/api/user.py", line 45, in get_user
    user = await service.get_user_by_id(user_id)
  File "/app/service/user_service.py", line 88, in get_user_by_id
    raise NotFoundError(f"User {user_id} not found")
NotFoundError: User 123 not found

2. Web API におけるスタックトレースの重要性

  • マイクロサービス時代のデバッグ: API 境界を越えると再現が難しい → サーバー側のトレースが生命線。

  • 可観測性 (Observability) 三種の神器

    1. メトリクス: 量的変化を監視
    2. ログ: 状態変化を時系列で記録
    3. トレース (分散トレーシング) / スタックトレース: 失敗パスを可視化
  • セキュリティ注意点: 本番レスポンスに露出するとファイル構成やパッケージバージョンが漏洩 ➜ マスキング or カスタムエラー が必須。


3. Docker × FastAPI + Uvicorn でのスタックトレース制御

3-1 運用ポリシー

  • 開発: すぐ見たい → debug=True + 制限なし
  • 本番: ユーザーには隠し、ログには残す

3-2 主要スイッチ

レイヤ 設定例 効果
FastAPI app = FastAPI(debug=False) HTTP 500 で詳細非表示
Uvicorn --log-level info 標準出力の詳細度
Python PYTHONFAULTHANDLER=1
sys.tracebacklimit = 5
致命的例外時に強制ダンプ / 深さ制限
Gunicorn --log-level info Worker 全体のログ深度

3-3 Dockerfile スニペット

# ---------- build ----------
FROM python:3.11-slim AS runner
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

# ---------- runtime ----------
ENV PYTHONFAULTHANDLER=1 \
    TRACEBACKLIMIT=0        # 本番では 0 でフレーム非表示

CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", \
     "main:app", "-b", "0.0.0.0:8000", "--log-level", "info"]

4. Node.js (Express / NestJS) でのスタックトレース制御

4-1 運用ポリシー

  • 開発: NODE_ENV=development + Error.stackTraceLimit = Infinity
  • 本番: NODE_ENV=production で自動的に stack 隠蔽 → さらに独自 middleware で完全マスク

4-2 設定比較表

レイヤ 開発 (dev) 本番 (prod)
V8 Error.stackTraceLimit = Infinity デフォルト (10)
Node flags node --trace-uncaught --abort-on-uncaught-exception
Express MW JSON で err.stack 返す 固定メッセージ "Internal Server Error"
Env 変数 ERROR_STACKS=true ERROR_STACKS=false

4-3 Middleware 例

app.use((err, req, res, next) => {
  const expose = process.env.ERROR_STACKS === 'true';
  console.error(err);                 // サーバー側には常に出力
  res.status(500).send(
    expose ? err.stack : 'Internal Server Error'
  );
});

5. 明日から使うレシピ

  1. IDE ジャンプ: VS Code / PyCharm でスタック行をクリック → 該当ソースへ。

  2. APM 連携: Sentry、Datadog を導入し、“エラーごとの fingerprint” でハッシュ化集約。

  3. サンプラー: 🔧 py-spy (Python) / clinic flame (Node) で実行中プロセスに安全 attach。

  4. CI テスト失敗時の自動収集:

    • pytest -vv --log-cli-level=ERROR でトレース全文を GitHub Actions アーティファクトへ保存。
  5. 再発防止: 似た stackhash が 3 回以上上がったら警告 → Jira チケット自動生成。


6. まとめ

  • 概念: スタックトレース = 例外が通った“呼び出し履歴”。
  • 重要性: Web API では多層構造ゆえ、再現よりトレースが解析の鍵。
  • FastAPI: debugTRACEBACKLIMIT を切り替え、ログは常にフル出力。
  • Node.js: NODE_ENV と middleware でレスポンス露出を完全制御。
  • 運用: "ユーザーには隠し、ログと APM には詳細を残す" が鉄則。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?