🌐

Unityからs3にログを送って分析できる基盤を作ってみた

2021/08/22に公開

始めに

使用技術

この記事は下記のサービスを利用して最小構成の分析基盤を作ってみた話です

  • Unity
  • AWSSDK.Net
  • AWS S3
  • AWS KinesisFirehose
  • AWS Athena

最小限で作ったので、セキュリティ面などは考慮しておりません
また、料金面も詳しく調査してません(高くは無いと思います...)

クライアントからログを取る意味とは?

クライアントでしか扱わないような大量のデータを保存するために使用する想定です
例えば、
ゲーム内に高難易度のステージを実装した場合、どこが難しいのかという情報はあまりログとして取られていません
ですが、DBに保存しない大量のログを取れる場合では、クライアントのゲームでの正確な行動ログなどを取ることが出来ます。

アクションゲームでは、ステージのどの場面で死んだのか
リズムゲームでは、どの瞬間でゲームオーバーになったのか

といった明確な失敗要因をログとして残すことが可能になるかと思います

AWS側の用意

クライアントからアクセスする用のIAMの作成

とりあえずIAMを作成する

  • プログラムからアクセスできるように設定

  • firehoseへのアクセス権を指定する
    フルアクセスの必要はないので必要な分だけ設定すると良いです
    なお、今回はでは面倒臭いのでフルアクセスにしているだけです

  • あとは成り行きで進める
    この時に表示されるアクセスキーとシークレットキーは使用するのでメモしておいてください

ログを保存するためのs3の作成

二つのs3を作る必要性があります

  • firehoseで送られてきたログの集積場所
  • AthenaのDBのデータを保存するための場所
    この二つを作って行きます

firehoseで送られてきたログの集積場所

firehoseの設定時に作るので、後載となります

AthenaのDBのデータを保存するための場所

こちらも同様に特に設定することは無い

KinesisFirehoseでクライアントから送ったログをs3へ送る

  • 新規の配信ストリームを作成する
    この画面では名前以外は特に設定する必要は無し

  • s3の作成

  • 保存形式をgzipにする
    Athenaではgzip形式のjsonが読み込み対応できるので、gzipに設定する

  • ログの保存場所を設定する

Unity側の用意

AWS SDKのDLLファイルの用意

やること
1.VisualStudioで新規プロジェクト → クラスライブラリでプロジェクトを作成する
2.メニュータブのプロジェクト管理から「NuGetパッケージの管理」を選択

3.使用するパッケージを選択する
・AWSSDK.Core
・AWSSDK.KinesisFirehose

検索で「aws」と検索するとやりやすいかと思います
4.パッケージをインストール後にビルドを行う

5.「プロジェクトフォルダ\bin\Release or Debug」のフォルダ内にDLLが作成されていることを確認する
6.Unityのプロジェクトを開き、Pluginフォルダ内に生成されたDLLを入れる

↓こちらのURLを参考すると参考にするとやりやすいです
https://www.hanachiru-blog.com/entry/2019/07/07/233000

AWS KinesisFirehoseへの接続とデータの転送

1.スクリプトの作成

using System.IO;
using System.Text;
using System.Collections.Generic;
using UnityEngine;
using Amazon.KinesisFirehose;
using Amazon.KinesisFirehose.Model;


public struct Data
{
    public int id;
    public int type;
    public string message;

    public Data(int id, int type, string message)
    {
        this.id = id;
        this.type = type;
        this.message = message;
    }
}



public class Test : MonoBehaviour
{
    const string Accesskey = "IAM作成した際にメモしたアクセスキー";
    const string SecretKey = "IAM作成した際にメモしたシークレットキー";


    // Start is called before the first frame update
    void Start()
    {
        var client = new AmazonKinesisFirehoseClient(Accesskey, SecretKey, Amazon.RegionEndpoint.APNortheast1);

        //テストデータの定義
        var datas = new Data[] {
            new Data(1,2,"test"),
            new Data(2,3,"aws"),
            new Data(3,4,"kinesis"),
            new Data(4,5,"fire"),
            new Data(5,6,"hose"),
        };

        List<Record> recodes = new List<Record>();

        foreach(var data in datas)
        {
            var json = JsonUtility.ToJson(data);

            // Amazon.KinesisFirehose.Model.RecordインスタンスのDataプロパティにPUTするデータを詰める
            var record = new Record()
            {
                Data = new MemoryStream(Encoding.UTF8.GetBytes(json + "\n")) //末尾に改行を入れないとAthenaで認識されない
            };

            recodes.Add(record);
        }

        //送信
        var r = client.PutRecordBatch("Firehoseの配信ストリーム名", recodes);
        Debug.Log(r.HttpStatusCode);
    }
}

2.上記で作成したスクリプトを適当なオブジェクトにアタッチしてシーンを再生する
3.再生し「OK」というログが出てることを確認する

4.awsのs3を確認し、ログが生成されていることを確認する
・1,2分ほど時間がかかります

Athenaでs3上のログをSQLクエリで見れるようにする

Athenaの出力先のs3を選択する

「Query result location」にAthenaのDBのデータを保存するために作ったs3を指定する

Athenaでテーブルの作成をする

  • テーブルの作成を選択する

  • ログを貯めているs3を選択する

  • Jsonを選択する

  • クライアントで定義した値をカラムに定義する

  • テーブルの中身を確認してみて、クライアントから送信されたデータが確認できる

最後に

今回は最小構成で作成しました

本来の業務で使用する場合では、セキュリティ面や分析のフロント部分にBIツールを使うなどの工夫が必要になるかと思います

この記事をきっかけに、クライアントからサーバーレス且つ、大容量のログデータを保存するような仕組みを実装できたらいいなと思いました

Discussion