006: ポストモーテム¶
難易度: ☆☆
問題¶
関数 log_error_summary(root) を書いてください。
この関数は、指定されたディレクトリ以下にある .log ファイルを再帰的に探し、ERROR 行を集計します。
対象になる ERROR 行は、次の形式です。
CODE は英大文字、数字、アンダースコアからなる文字列です。
戻り値は、次のキーを持つ辞書にしてください。
"files":ERROR行を1つ以上含んだログファイルの相対パス一覧"codes":エラーコードごとの件数を表す辞書"errors":(relative_path, line_number, code, message)のリスト
ファイルとエラー行は、相対パスの昇順、同じファイル内では行番号の昇順で並べます。
"codes" のキーは、コード名の昇順にしてください。
制約¶
pathlib.Pathを使ってください。reを使ってERROR行を解析してください。- エラーコードの件数集計には
collections.Counterを使ってください。 rootは文字列またはPathとします。- ファイルはUTF-8として読んでください。
- 相対パスの区切りは
/にしてください。 - 形式に合わない行は無視してください。
例¶
>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> with TemporaryDirectory() as d:
... root = Path(d)
... (root / "app.log").write_text("INFO start\nERROR DB down\nERROR API timeout\n", encoding="utf-8")
... (root / "old.txt").write_text("ERROR DB ignored\n", encoding="utf-8")
... (root / "sub").mkdir()
... (root / "sub" / "worker.log").write_text("WARN slow\nERROR DB locked\n", encoding="utf-8")
... log_error_summary(root)
{'files': ['app.log', 'sub/worker.log'], 'codes': {'API': 1, 'DB': 2}, 'errors': [('app.log', 2, 'DB', 'down'), ('app.log', 3, 'API', 'timeout'), ('sub/worker.log', 2, 'DB', 'locked')]}
発展¶
WARNING 行も対象にし、レベルごとに件数を分けて返してください。