🐕

GoogleAnalyticsの行動ログ送信の実装漏れ・定義ズレを防ぐ

2022/12/12に公開

この記事はLuup Advent Calendarの12日目の記事です。

データエンジニアリングチームとサーバーチームの t-kurimura です。

今回はアプリ開発に欠かせないユーザーの行動ログ分析において、実装漏れや仕様の認識不足によるログ欠損を防ぐためのアイデアをご紹介します。

背景課題

行動ログの分析までの過程で以下のような問題が起きたことはありませんか?

  • 分析のためのイベントの実装をし忘れてしまっている
  • イベントの実装が特定のパターンでのみ送られないようになっていて分析・調査・修正に時間を要する
  • 実装したイベントの形式がデータチームの認識と異なっている

このようにイベント実装の受け渡しで問題が発生しまうことは珍しくないと思います。
Luupでもこうした問題がわずかながら発生していました。

解決策を考える

こうした作業の過程はいくつかのフェーズで分けられます。

Luup-port-picture

場合によっては同一人物がこなす作業もあるかもしれませんが、多くの場合フェーズによって主な担当者が変わってきます。

アプリ開発の場合、AndroidとiOSのそれぞれ開発者がいるので、さらに伝言ゲームの難易度は上がります。

こうした開発においては組織横断・越境した連携やドキュメント形式を整備しておくことも重要ですが、今回は開発者が実装に入ったあとリリースまでに、開発者以外がログの正確性を確認しづらいことに着目しました。

ログへのアクセシビリティ改善

開発者は、Debug Consoleやlogcatなどを確認することでログの正確性の確認は難しくありませんが、それ以外のメンバーには無理ではないにしても環境整備・ビルド・エミュレーター起動など簡単ではありませんし、毎回やると時間効率も低下します。

PM・QAチーム・分析者などアプリの開発者以外が、ログの形式やタイミングをリリースより前に簡単に確認できるようにします。

LUUPアプリでの行動ログにはGoogleAnalytics for Firebaseを利用しています。またサーバーサイドにはCloudFunctionsも採用しているため、GoogleAnalyticsトリガーを利用することで簡単にアプリのイベントを拾うことができます。

このトリガーで検知したイベントを開発環境に限ってSlackの専用チャネルに垂れ流してみることにしました。

実装

実装は公式ドキュメントにもあるサンプルコードを参考にすればそう難しいものはないと思います。

Slackへの通知は @slack/web-api を利用して作成したBotユーザーから送信します。

export const appLoggchecker = functions.analytics
  .event("app_conversion")
  .onLog(async (event: AnalyticsEvent, _: EventContext) => {
    // Slackに投下
    const client = new WebClient(config.bot_token)
    await client.chat.postMessage({
      channel: "C01XXXXXXXX",
      text: `${user.id} logged event ${event.params["type"]} on ${event.user.appInfo.appPlatform}(${event.user.appInfo.appVersion})`,
    });
  })
);

関数・イベント設計の注意点

https://github.com/firebase/firebase-functions/blob/ffa3a574087e12e0fd866d504328b6a6e3d7f344/src/v1/function-builder.ts#L419-L428

このようにFirebaseのFuctions用のTypeScriptのライブラリーであるfirebase-functionsの実装では1つのevent_nameに対して、1関数が必要です。

関数が増えることで費用が急上昇する可能性は低いですが、イベントの種類が追加されるごとに関数を追加するのは運用が面倒です。

また、GoogleAnalyticsのevent_nameの種類数には制限があります。

500 per app instance
Automatically collected events such as first_open and in_app_purchase do not count toward the limit.

https://support.google.com/firebase/answer/9237506?hl=en

この記事内では、過去のイベントのarchiveやFirebaseのプランアップグレードによるこの制限の拡張も否定されています。

上限は大きいとはいえ、不可逆変更なので、そもそもevent_nameの種類を増やしていくこと自体あまり得策とは言えないでしょう。

そのためevent_nameではなく、イベントパラメーターで "どの行動か" を表現するのが最適だと考えています。

(例)

種類 event_name event_parameter.key event_parameter.value
登録 app_custom_log type registration
メアド更新 app_custom_log type update_email
LP閲覧 app_custom_log type view_lp
購入 app_custom_log type purchase

イベント詳細

サンプルコードでも一部記載していますが、イベントパラメータやユーザー定義(ディメンション)以外にも、

  • アプリのバージョン
  • OSのバージョン
  • 端末情報(機種)
  • アクセス地域(最詳で市区町村)
  • IDFA on iOS
  • AdId on Android

などにアクセスが可能です。

このトリガー関数は今回のログ確認の用途以外にも有用で、実際にLUUPではプロダクション環境でも一部このトリガーを利用してユーザーの利用環境と行動の情報連携をしています。

終わりに

最近は、PMやデータチーム主導でイベント仕様の網羅的な管理を図っていることもあり、分析環境やログはかなり改善してきています。

職能を横断して連携すること自体は大切で楽しいものですが、重要ではない部分の連携負担は軽くできればと考えています。

今回のアイデアが分析や分析のための開発環境改善のお役に立てれば幸いです。

Luup Developers Blog

Discussion