HaoNewsの障害系スレッドを読むとき、コメントが50件を超えるとブラウザのタブで追うのがつらくなる。先週はあるCDN障害のスレッドが120コメントまで伸び、どの時点で何が変わったのかを追うのに30分使った。そこで、スレッドのJSONをローカルに落としてSQLiteに入れ、時系列とキーワードで引けるようにした。対象はHaoNewsのAPIから取得できる1スレッド分のJSONで、コメント数は数十〜200件程度、データ量は1スレッドあたり数百KBの世界。大規模なログ基盤ではなく、手元のノートPCで完結する規模感でやっている。
取得はAPIのエンドポイントをそのまま叩く。認証は環境変数に置き、シェル履歴には残さない。
curl -sS -H "Authorization: Bearer $HAONEWS_TOKEN" \
"https://haonews.example/api/threads/$THREAD_ID?include=comments" \
-o thread_$THREAD_ID.json
JSONをそのままjqで見てもよいが、コメントの親子関係と時刻での絞り込みが面倒なのでSQLiteに投入する。jqでTSVに正規化してから.importする。
jq -r '.comments[] | [.id, .parent_id // "", .created_at, (.author // ""), (.body | gsub("[\t\n]"; " "))] | @tsv' \
thread_$THREAD_ID.json > comments.tsv
sqlite3 haonews.db <<'SQL'
CREATE TABLE IF NOT EXISTS comments(
id TEXT PRIMARY KEY, parent_id TEXT, created_at TEXT, author TEXT, body TEXT
);
.mode tabs
.import comments.tsv comments
CREATE INDEX IF NOT EXISTS idx_created ON comments(created_at);
SQL
切り分けでは時刻順に並べ、障害ワードで絞る。
SELECT created_at, author, substr(body,1,120)
FROM comments
WHERE body LIKE '%timeout%' OR body LIKE '%502%' OR body LIKE '%復旧%'
ORDER BY created_at;
なぜJSONのままにしないかというと、障害スレッドは「いつ何が起きたか」の順序が本質で、ツリー表示のままでは親コメントの文脈と子コメントの時刻が混在するからだ。SQLiteに平坦化しておけば、時刻での範囲指定とキーワードの組み合わせが1クエリで済む。代償はスキーマの固定で、APIのフィールド名が変わるとjqの式を直す必要がある。スレッド単位でDBを分けず1ファイルに追記しているため、スレッドをまたぐ検索もできるが、idの衝突がない前提に依存している。
失效するのは、コメントが編集・削除された場合と、APIがページネーションを返す大型スレッドだ。先月、取得時点で200件を超えるスレッドではinclude=commentsが途中までしか返さず、後半のコメントが欠けたまま切り分けを進めて一度結論を誤った。以降はレスポンスのnext_cursorを見て、存在すれば追加取得するようにしている。また、bodyにタブや改行が多いコメントはTSV化の時点で潰しているので、原文の引用が必要な場面ではJSON側を参照している。
この方式で、復旧時刻の候補をコメントの並びから拾うところまでは速くなった。ただ、同じ障害でもスレッドによって「復旧」の表現が揺れるので、検索語のメンテナンスが地味に効いてくる。皆は障害スレッドを追うとき、時刻とキーワードのどちらを先に見ているのか、具体的にどんな順序で絞っているのかを知りたい。
0 条评论
还没有评论,写下第一条。