本文へ移動
cccskills
無料GitHub で公開

logging

codeを書く・直すときに、どこに何をどのlevelでlogへ残すかを定める。新しいscript、batch、bot、API処理、backtest、data処理を実装するとき、または不具合調査でlogが足りないと分かったときに使う。

インストール方法を見る

含まれるファイル(1)

  • SKILL.md5.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Logging

codeは最初からlogを多めに入れて書く。目的は、実行後にlogだけを読めば「何が入り、何をどう判断し、何件処理し、どこで何秒かかり、なぜ失敗したか」が分かること。後から足すのではなく、実装と同時に入れる。

必ず残すもの

種類内容例
入力起動引数、設定値、読んだfileのpathと件数・期間・hashloaded path=... rows=1440 start=... end=...
判断分岐ごとの結果と理由(閾値と実際の値)skip symbol=SOL reason=volume_below_min value=1.2e6 min=5e6
件数入力・処理・成功・skip・失敗の件数done total=120 ok=117 skipped=2 failed=1
時間処理全体と重い区間の所要時間fetch elapsed_ms=842
失敗例外の種類、message、traceback、対象のID、retry回数、最終的な扱いlogger.exception(...)
外部呼出宛先(host/endpoint)、status code、件数、retryGET host=api.example.com status=429 retry=2

level

  • DEBUG: 1件ごとの詳細、中間値。通常は出さず、調査時に有効にする。
  • INFO: 開始・終了、入力の要約、主要な判断、件数、所要時間。通常運用で読む。
  • WARNING: 続行できるが想定外のこと(欠損、fallback、retry、skip)。理由を必ず書く。
  • ERROR: その単位の処理が失敗した。logger.exception でtracebackを残す。
  • 黙って握りつぶす except: pass は書かない。続行するならWARNING以上で理由を残す。

書き方

  • module単位で logger = logging.getLogger(__name__)(または用途名)を使い、print で代用しない。
  • messageは「固定のevent名 + key=value」の形にし、grepと集計がしやすいようにする。値は %s 形式の引数で渡す。
  • 1回の実行を追えるよう、run ID・対象ID(symbol、user、file名など)を各行に含める。
  • 長い一覧やpayload全体は出さず、件数・先頭数件・hashで要約する。
  • 時刻はtimezone付き(ISO 8601)で残す。

出し先

  • 既定はstderr。長時間処理・batch・botはfileにも出す(例: logs/<name>.log、または実行記録directory内)。
  • 実験・backtestの実行記録がある場合は、その実行のdirectoryにlogを一緒に保存し、結果と対応させる。
  • logの設定(handler、level、format)は入口(main)で一度だけ行い、libraryの中では設定しない。

秘密情報を出さない

  • token、password、API key、cookie、Authorization header、private keyはlogに出さない。DEBUGでも出さない。
  • URLのquery、request header、設定dict、例外messageに秘密が混ざる場合は、出す前に伏せる(***)。
  • 設定を出すときは許可したkeyだけを出す(allowlist)。dict全体をそのまま出さない。

Pythonの例

import logging
import time
import uuid

logger = logging.getLogger("funding_sweep")

SAFE_CONFIG_KEYS = ("symbols", "start", "end", "min_volume")


def setup_logging(log_path: str, level: int = logging.INFO) -> None:
    fmt = "%(asctime)s %(levelname)s %(name)s %(message)s"
    logging.basicConfig(
        level=level,
        format=fmt,
        handlers=[logging.StreamHandler(), logging.FileHandler(log_path, encoding="utf-8")],
    )


def run(config: dict, rows_by_symbol: dict[str, list[dict]]) -> dict:
    run_id = uuid.uuid4().hex[:8]
    t0 = time.perf_counter()
    safe = {k: config.get(k) for k in SAFE_CONFIG_KEYS}
    logger.info("start run_id=%s config=%s symbols=%d", run_id, safe, len(rows_by_symbol))

    ok = skipped = failed = 0
    for symbol, rows in rows_by_symbol.items():
        volume = sum(r["volume"] for r in rows)
        if volume < config["min_volume"]:
            skipped += 1
            logger.warning(
                "skip run_id=%s symbol=%s reason=volume_below_min value=%.0f min=%.0f",
                run_id, symbol, volume, config["min_volume"],
            )
            continue
        t1 = time.perf_counter()
        try:
            result = evaluate(rows)
        except Exception:
            failed += 1
            logger.exception("evaluate_failed run_id=%s symbol=%s rows=%d", run_id, symbol, len(rows))
            continue
        ok += 1
        logger.info(
            "evaluated run_id=%s symbol=%s rows=%d result=%.4f elapsed_ms=%.0f",
            run_id, symbol, len(rows), result, (time.perf_counter() - t1) * 1000,
        )

    elapsed = time.perf_counter() - t0
    logger.info(
        "done run_id=%s total=%d ok=%d skipped=%d failed=%d elapsed_s=%.2f",
        run_id, len(rows_by_symbol), ok, skipped, failed, elapsed,
    )
    return {"ok": ok, "skipped": skipped, "failed": failed}

外部APIを呼ぶときは、tokenを含まない宛先とstatusだけを残す。

resp = session.get(url, params=params, timeout=10)
logger.info("http_get host=%s path=%s status=%d items=%d",
            urlsplit(url).hostname, urlsplit(url).path, resp.status_code, len(resp.json()))

確認

  • 実装後に一度実行し、logだけで入力・判断・件数・時間・失敗が読み取れるか見る。
  • logに秘密情報が出ていないか、rg -i "token|secret|password|authorization" などで確認する。

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

agent-cli

無料日本語概要

ある AI エージェントから別の AI CLI(devin / codex / claude / cursor-agent / opencode / gemini / grok)を非対話で呼び出すときの実行規則。print モードの 選び方、認証・権限・cwd の罠、出力フォーマット、ACP 起動の注意をまとめる。 「codex に投げて」「devin を CLI から呼んで」「別エージェントに委譲」 といった依頼で使う。ユーザーが /agent-cli と入力したら使う。

coil398/dotfiles82026年10月16日 更新

agent-skill-migrate

無料日本語概要

明示されたリポジトリのSkill・Agent・呼出し・生成配布を点検または移行する。通常の実装・レビュー・調査では起動しない。

coil398/dotfiles82026年10月16日 更新

agent-skill-migrate

無料日本語概要

明示されたCodex・CursorのSkill運用移行を、指定設計と既存点検に基づき適用する。通常の実装依頼では起動しない。

coil398/dotfiles82026年10月16日 更新

ai-design-system

無料日本語概要

プロジェクトのデザインシステムを SSOT として作成・監査・更新する。トークン、デザインシステムに関わるアクセシビリティ、Typography、Motion、aesthetic direction の作業に使う。デザインシステムに紐づかない単発UI実装や個別デザインレビューには使わない。ユーザーが /ai-design-system と入力したら使う。

coil398/dotfiles82026年10月16日 更新

ai-design-system

無料日本語概要

デザインシステムの作成・監査・保守、デザイントークンやUIの一貫性・個性・アクセシビリティの改善に使う。

coil398/dotfiles82026年10月16日 更新

ai-diary

無料日本語概要

AIに日記を書かせるスキル。会話を振り返り、AI視点の自由な日記風テキストを生成して保存する。「日記書いて」「AI日記」「日記風に振り返って」「感想を日記にして」「diary」「write a diary」といった日記・感想の依頼に使う。作業改善の振り返りは /retro、知見の記録や要約は /ai-ltm を使う。ユーザーが /ai-diary と入力したら必ずこのスキルを使う。

coil398/dotfiles82026年10月16日 更新

coil398 のスキルをすべて見る

このスキルの問題を報告する