忙しい人向けの Explore logging in Swift - #WWDC20

画像27

冒頭

・ユーザは高品質で安定したアプリを求めている。
・再現が難しいバグは修正が難しい。
・ログは再現できないバグを修正するのに役立つ。

画像1

例として、稀にしか発生しない読み込みエラーなど。

画像2

新しいロギングAPI

Xcode 12 では統一された新しいロギング API が追加された。OSによってアーカイブされ後で端末から取得できる。パフォーマンスも良い。

画像3

サブシステムとカテゴリを指定して Logger を生成し、そのインスタンスのメソッドを呼び出して利用する。

画像4

文字列補間は print 関数と似ているが、コンパイル時にはログに最適化された型に変換され、実際にメソッドが呼び出されたタイミングで文字列に変換される。そのため実行コストが低い。

画像5

標準で多くの型に対応している。独自の型をサポートするには、CustomStringConvertible に準拠するだけでよい。

画像6

非数値型のデータはデフォルトではマスクされる。 privacy: .public を指定することでそのまま出力させることもできる。

画像7

ログの取得・確認

ターミナルから log collect コマンドを利用して取得できる。 .logarchive はダブルクリックすることで Console.app で開くことができる。

画像8

Console.app では記録されたすべてのログが表示されるが、画面右上の検索フィールドからサブシステムやその他のキーワードで絞り込める。

画像9

今回のバグが再現しづらかったのは、タイミングとネットワークエラーに依存していたため。

画像10

端末と Mac を接続している場合はリアルタイムでログを確認できる。Xcode から起動している場合はコンソールにも出力される。構造化されてフィルタしやすいので、printf の代替えとしても利用できる。

画像11

ログレベル・パフォーマンス

重要度に応じた、5つのログレベルが用意されている。Error は黄色、Fault は赤色でハイライトされる。

画像12

Logger インスタンスのメソッドを補完すると、ログレベルが確認できる。

画像13

ログの永続性は、ログレベルによって決まる。Debug は永続化されないためアプリが終了した後には取得できない。Info は数分間だけ残る。それ以外は一定期間だけ永続化される。ErrorFaultNotice より長く、一般的に数日間は残るが、ストレージ容量によっては保証されない。

画像14

また、パフォーマンスもログレベルによって異なり、重要度が低いほどパフォーマンスが高い。

画像15

Debug レベルは記録されないため、メッセージの組み立てに重い処理を利用したり、冗長なログ出力に利用しても問題ない。

画像16

フォーマット

愚直にログ出力すると、桁数が合わずに読みづらいことがある。

画像17

フォーマットを利用して、桁数や小数点の形式を指定すると・・・

画像18

このように読みやすいフォーマットで出力できる。

画像19

キレイに整形されているので、Optionキーを押しながら矩形選択をして・・・

画像20

Numbers に貼り付けてグラフ化することも簡単にできる。

画像21

フォーマットを利用しても実行時にコストは発生しない。

画像22

フォーマットオプションは、Xcode 上のコード補完でも確認できる。

画像23

プライバシー

ログ出力は、アプリがユーザの端末にインストールした後でも記録され、端末に物理的にアクセス可能であればそれを取得できることに注意。そのため、個人情報は絶対に .public にしてはいけない。

画像24

ハッシュ値としてマスクするオプションもある。これは実際のデータは分からないが、同一であることは分かるので、ログのフィルタリング時に便利。

画像25

iOS 14 からは今回紹介した新しいロギング API が利用できる。それ未満でも os_log() は printf 形式のフォーマット指定は行える。

画像26

まとめ

・新しいロギングAPI を利用すると、再現が難しいバグを調査しやすい。
・API は高いパフォーマンスと豊富なフォーマットを備えている。
・またセキュアなオプションも備えている。
・エンドユーザに影響を与えることなく安心して利用できる。

免責

・本記事は公開情報のみに基づいて作成されています。
・要約(意訳)のみなので、詳細はセッション動画をご確認ください。


役に立った記事などありましたらサポート頂けると嬉しいです。