Upgrade to Pro — share decks privately, control downloads, hide ads and more …

STORES 決済で使っているLoggerの実装を刷新した話

k-kohey
October 20, 2022
200

STORES 決済で使っているLoggerの実装を刷新した話

k-kohey

October 20, 2022
Tweet

Transcript

  1. 背景 | STORES 決済が提供するサービス 3 - STORES 決済では決済に関するサービスを 下記の2つの形で提供している -

    STORES 決済を介して クレジットカードや電子マネー決済ができる - 決済アプリ(以降、アプリと呼ぶ) - App Storeにて 公開しているアプリ - 決済SDK(以降、SDKと呼ぶ) - 決済機能を自社アプリに組み込みたい 企業向けに公開しているSDK
  2. 背景 | ログの活用 アプリではサービス改善に役立てるため ユーザ行動やシステムの不具合をログとしてバックエンドに送信している 4 バックエン ドA バックエン ドB

    バックエン ドC ユーザ行動や不具合を蓄積するバックエンド 決済が 失敗しました 決済が 失敗しました 開発者
  3. 背景 | ログの活用 バックエンドに送信されたログから下記のような事がわかる - システムに不具合が生じていること - および不具合が発生している箇所 - ユーザがアプリに対してどのような操作を行なっているか

    これらの情報は下記のような改善に役立ちます - システムに問題が発生した際に早期に発見し修正すること - ユーザの操作からボトルネックを発見し使いやすいアプリにすること 5 ログは継続的なサービス開発において重要
  4. 背景 | SDKにおけるロギングの問題 一方でSDKは後述する理由からログを送信できておらず(※) ログの恩恵を十分に得られていない状態だった 6 バックエンド A バックエンド B

    バックエンド C ユーザ行動や不具合を蓄積するバックエンド アプリが起動 されたわよ (※)クライアントのログ情報に限った話です。バックエンドでは収集できています。
  5. 背景 | SDKにおけるロギングの問題 - アプリとSDKでは次のような外部のライブラリの利用に対して 異なる考え方で開発を進めている - SDKは外部のライブラリを利用しない方針で開発している - SDKは外部(SDKクライアント)から利用されることを前提にしている

    - SDKクライアントとSDKが同じライブラリを利用する場合に、 そのライブラリのバージョンを解決できない可能性がある - アプリは外部のライブラリを利用している - アプリにはクライアントが存在せず、SDKと同じ考えは必要ないため - アプリはFirebaseやMixpanel等の一般公開されている ライブラリを利用してログを収集している 7 SDKはアプリと同様の方法でロギングできない
  6. 背景 | SDKにおけるロギングの問題 - アプリとSDKでは次のような外部依存に対して異なる考え方で 開発を進めている - SDKは外部のライブラリを利用しない方針で開発している - SDKは外部(SDKクライアント)から利用されることを前提にしている

    - SDKクライアントとSDKが同じライブラリを利用する場合に、 そのライブラリのバージョンを解決できない可能性があるため - アプリは外部のライブラリを利用している - アプリにはクライアントが存在せず、SDKと同じ考えは必要ないため - アプリはFirebaseやMixpanel等の一般公開されている ライブラリを利用してログを収集している 8 SDKはアプリと同様の方法でロギングできない SDKでもロギングできるように ロガーの実装を刷新することに
  7. 実装 | ロガー実装の共通化 11 ログ収集SDK Firebaseや MixPanel(※)等の SDK ログ収集SDK Firebaseや

    MixPanel(※)の SDK ロガー実装 アプリから DIして参照 MixPanelの HTTPクライアント 必要に応じてSDKから DIして参照 SDKを介して参照 追加 追加 (※)弊社にて使っている分析ツール
  8. 実装 | ロガー実装の共通化 12 ロガー実装 MixPanelの HTTPクライアント SDKから DIして参照 他社

    アプリ (SDKクライアント) アプリからFirebaseや Mixpanl等のSDKの実装 をDIされない場合でも SDKのロガー実装から ログが可能 ログ収集SDK Firebaseや MixPanel等の SDK ロガー実装 アプリから DIして参照 SDKを介して参照 SDKからアプリの ロガー実装を参照 し利用できる 💡アプリとSDKのどちらの利用においても 同じインタフェース(ロガー実装)で バックエンドを意識せずログが可能に
  9. 実装 | ロガー実装の共通化 13 左のようなインタフェースで次の ように条件に応じてロガーの実装 を切り替えられるようにした - アプリからの利用時は backendBLogger

    - それ以外の時は backendALogger 注) 決済アプリは外部に公開している決済SDKとほぼ同等の機能を持つ異なるSDKを利用し ています。そのためloggerインスタンスは外部に公開されません
  10. 実装 | ログのMutation 14 { "eventName": "signin", "parameters": {} }

    { "eventName": "signin", "parameters": { "sdk_version": "1.0.0" } } { "eventName": "signin", "parameters": { "app_version": "5.5.2" } } - SDKとアプリでログのパラメータ を柔軟に変更したい - 例 - SDKの場合は全てのログ のパラメータにsdk_versionを 付与 - アプリの場合は全てのログ のパラメータにapp_versionを 付与 - ただしSDKとアプリでログ定義は 同じものを使い回したい - 同じログを2重管理はしたくない ログを変換する層が必要
  11. 実装 | ログのMutation 15 { "eventName": "signin", "parameters": {} }

    { "eventName": "signin", "parameters": { "sdk_version": "1.0.0" } } { "eventName": "signin", "parameters": { "app_version": "5.5.2" } } Mutation - ログを変化する層 Mutation を用意 - ログは必ずMutationを介して任意の形に変形されて送信される
  12. 実装 | ログのMutation 16 { "eventName": "signin", "parameters": {} }

    { "eventName": "signin", "parameters": { "os": "16.0" } } 他にも全てのログのパラメータに入るような汎用的な情報の挿入や パラメータの変換に使えます💡 { "eventName": "signin", "parameters": {} } { "eventName": "signin", "parameters": { "network": "wifi" } } { "eventName": "failed", "parameters": { "error": MyError.invalidSyntax } } { "eventName": "signin", "parameters": { "error description": "invalid syntax" } }
  13. 実装 | ログの定義を容易にする工夫 - 従来は左図のようにenumを使って ログ定義を管理しており 新規にイベントを追加する際は caseを追加して対応していた - ログを増やすとコンパイルエラーが

    発生しenumのプロパティに対して修正が 必要だった 17 enumのパターンマッチングが安全装置 として働いている一方で 拡張に対して開いていないと感じる