忙しい人向けの Explore logging in Swift - #WWDC20
冒頭
・ユーザは高品質で安定したアプリを求めている。
・再現が難しいバグは修正が難しい。
・ログは再現できないバグを修正するのに役立つ。
例として、稀にしか発生しない読み込みエラーなど。
新しいロギングAPI
Xcode 12 では統一された新しいロギング API が追加された。OSによってアーカイブされ後で端末から取得できる。パフォーマンスも良い。
サブシステムとカテゴリを指定して Logger を生成し、そのインスタンスのメソッドを呼び出して利用する。
文字列補間は print 関数と似ているが、コンパイル時にはログに最適化された型に変換され、実際にメソッドが呼び出されたタイミングで文字列に変換される。そのため実行コストが低い。
標準で多くの型に対応している。独自の型をサポートするには、CustomStringConvertible に準拠するだけでよい。
非数値型のデータはデフォルトではマスクされる。 privacy: .public を指定することでそのまま出力させることもできる。
ログの取得・確認
ターミナルから log collect コマンドを利用して取得できる。 .logarchive はダブルクリックすることで Console.app で開くことができる。
Console.app では記録されたすべてのログが表示されるが、画面右上の検索フィールドからサブシステムやその他のキーワードで絞り込める。
今回のバグが再現しづらかったのは、タイミングとネットワークエラーに依存していたため。
端末と Mac を接続している場合はリアルタイムでログを確認できる。Xcode から起動している場合はコンソールにも出力される。構造化されてフィルタしやすいので、printf の代替えとしても利用できる。
ログレベル・パフォーマンス
重要度に応じた、5つのログレベルが用意されている。Error は黄色、Fault は赤色でハイライトされる。
Logger インスタンスのメソッドを補完すると、ログレベルが確認できる。
ログの永続性は、ログレベルによって決まる。Debug は永続化されないためアプリが終了した後には取得できない。Info は数分間だけ残る。それ以外は一定期間だけ永続化される。Error と Fault は Notice より長く、一般的に数日間は残るが、ストレージ容量によっては保証されない。
また、パフォーマンスもログレベルによって異なり、重要度が低いほどパフォーマンスが高い。
Debug レベルは記録されないため、メッセージの組み立てに重い処理を利用したり、冗長なログ出力に利用しても問題ない。
フォーマット
愚直にログ出力すると、桁数が合わずに読みづらいことがある。
フォーマットを利用して、桁数や小数点の形式を指定すると・・・
このように読みやすいフォーマットで出力できる。
キレイに整形されているので、Optionキーを押しながら矩形選択をして・・・
Numbers に貼り付けてグラフ化することも簡単にできる。
フォーマットを利用しても実行時にコストは発生しない。
フォーマットオプションは、Xcode 上のコード補完でも確認できる。
プライバシー
ログ出力は、アプリがユーザの端末にインストールした後でも記録され、端末に物理的にアクセス可能であればそれを取得できることに注意。そのため、個人情報は絶対に .public にしてはいけない。
ハッシュ値としてマスクするオプションもある。これは実際のデータは分からないが、同一であることは分かるので、ログのフィルタリング時に便利。
iOS 14 からは今回紹介した新しいロギング API が利用できる。それ未満でも os_log() は printf 形式のフォーマット指定は行える。
まとめ
・新しいロギングAPI を利用すると、再現が難しいバグを調査しやすい。
・API は高いパフォーマンスと豊富なフォーマットを備えている。
・またセキュアなオプションも備えている。
・エンドユーザに影響を与えることなく安心して利用できる。
免責
・本記事は公開情報のみに基づいて作成されています。
・要約(意訳)のみなので、詳細はセッション動画をご確認ください。
役に立った記事などありましたらサポート頂けると嬉しいです。