Cloud Logging を専用ゲームサーバーのロギング サーバーとして使用する

このチュートリアルでは、オンプレミスのロギング サーバーではなく Cloud Logging を使用して、アプリケーション固有のロギングを行う方法について説明します。デフォルトでは、Cloud Logging は、システムおよび多くの一般的なアプリケーションからのログを集計します。このチュートリアルでは、カスタム ワークフローや、一般的なアプリケーションのリストに表示されないアプリケーションからログを取得して Cloud Logging に送る方法について簡単に説明します。

このチュートリアルでは、専用ゲームサーバー(DGS)インスタンスに焦点を当て、Epic GamesUnreal Tournament(UT)サーバー バイナリを例として使用します。典型的な使用例の場合、仮想マシン(VM)がゲームのプラットフォーム サービスに接続されたプロビジョニング システムによって作成され、プレーヤーの要求に先立って DGS を実行します。DGS で生成されたログは 1 か所に保存されてインデックスに登録されるため、問題の特定とデバッグに大いに役立ちます。

目標

  • DGS インスタンスを作成し、そのインスタンスに Cloud Logging エージェントをインストールする。
  • Cloud Logging エージェントにログを送信するよう、DGS またはワークフローを構成します。
  • Python クライアント ライブラリを使用し、Cloud Logging にログを直接送信します。
  • Cloud Logging でログを表示、フィルタリング、検索する。
  • 長期アクセス可能なストレージに Cloud Logging からログをエクスポートします。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  3. Compute Engine API を有効にします。

    API を有効にする

  4. Cloud SDK をインストールして初期化します。
  5. gcloud beta コマンド コンポーネントをインストールします。

    gcloud components install beta
  6. デフォルトのプロジェクトを設定します。これにより、コマンドを実行するたびに --project フラグを指定する必要がなくなります。

    gcloud config set project PROJECT_ID

Compute Engine インスタンスの作成

Logging エージェントは、Compute Engine 仮想マシン(VM)と Amazon EC2 VM インスタンスで動作します。エージェントとサポートされる VM インスタンスの詳細については、Logging エージェントのドキュメントをご覧ください。このチュートリアルでは、n1-standard-8 VM タイプを使用してインスタンスを作成できます。本番環境システムでは各 VM で実行する予定の DGS インスタンスの数を決定し、それに応じてマシンタイプを選択する必要があります。

  1. Cloud Console で、[インスタンスの作成] ページに移動します。

    [インスタンスの作成] に移動

  2. [新しいインスタンスの作成] ページで、インスタンスのプロパティを入力します。 詳細構成オプションで、[管理、セキュリティ、ディスク、ネットワーク、単一テナンシー] セクションを展開します。
  3. [作成] をクリックしてインスタンスを作成します。

新しいインスタンスを作成するには、少し時間がかかります。

Compute Engine のインスタンスを構成する

スーパーユーザー権限を付与されたアカウントを使用して VM インスタンスを作成した後、ホーム ディレクトリから次の手順を行います。

  1. ターミナルで、SSH を使用してインスタンスに接続します。

    gcloud compute ssh sd-tutorial
    
  2. Logging エージェントをインストールします

  3. pip をダウンロードして、インストールします。

    sudo yum install python-pip
    
  4. Cloud Logging Python ライブラリをダウンロードしてインストールします。

    sudo pip install --upgrade google-cloud-logging
    
  5. /etc/google-fluentd/config.d ディレクトリに、次の内容で Unreal Tournament(UT)の ut.conf Logging エージェント構成ファイルを作成します。

    <source>
      @type tail
      read_from_head true
      format /^(\[(?<time>.*?):\d{3}\])?(\[[
    \d]+\])?(?<message>((?<component>\S*?):)((?<severity>\S*?):)?.*) /
      time_format %Y.%m.%d-%H.%M.%S
    
    # Log file names must be of the format ${ENV}.${VER}.${PORT}.log.
    # For example: prod.0112.8001.log
    path /home/*/LinuxServer/UnrealTournament/Saved/Logs/*.log
    exclude_path /home/*/LinuxServer/UnrealTournament/Saved/Logs/*backup*.log
    pos_file /var/lib/google-fluentd/pos/ut.pos
    tag ut.*
    </source>
    
    <filter ut.**>
      @type record_transformer
      <record>
        # Parse the log file name and add additional key:value records
        # to aid in filtering and searching logs.
        # Assumes you are following the convention in this tutorial.
       environment ${tag_parts[-4]}
       version ${tag_parts[-3]}
       port ${tag_parts[-2]}
       tag ${tag_suffix[1]} # Strip off the "ut." prefix.
    </record>
    </filter>
    

    fluentd の構成の詳細については、構成ファイルの構文をご覧ください。

  6. Logging エージェントの構成を再度読み込みます。

    sudo service google-fluentd reload
    

このチュートリアルでは、UT のビルドが標準のディレクトリ構造でユーザーのホーム ディレクトリにあることを前提しています。詳しくは、UT Wiki の Linux サーバーの設定をご覧ください。

本番環境の設定では、この構成済み VM のブートディスクをカスタム VM イメージとして保存し、パイプラインが必要に応じてこの VM を起動できるようにしておくことをおすすめします。

専用ゲームサーバーから Cloud Logging にロギングする際の考慮事項

各専用ゲームサーバーでは、それぞれ独自の形式でログ出力が生成されます。このチュートリアルでは UT DGS を使用していますが、stdout/stderr を出力する他のエンジンやアプリケーションに合わせて調整することもできます。

このチュートリアルでは、すべての DGS インスタンスに対して 1 つの fluentd 構成を使用し、プロビジョニング システムが各 DGS インスタンスの出力を検索に適した特定の形式でファイル名にリダイレクトすることを想定しています。単一の VM で複数の DGS インスタンスを実行する場合は、一意のファイル名を使用する必要があります。次のセクションで説明するこのチュートリアルのスクリプトでは、ログファイルの命名に関する制限事項が適用されますが、これらの制限は通常 Cloud Logging には適用されません。

UT ではデフォルトで、ログのディレクトリにログファイルのバックアップが自動的に作成されます。このディレクトリは Logging エージェントによって新しいファイルとして読み込まれます。Cloud Logging のログが重複しないように、本番環境ではバックアップを無効にすることをおすすめします。

専用ゲームサーバーのログファイルに名前を付ける

DGS ログの命名規則を定義するときは、スタジオで使用されているベスト プラクティスや命名規則に倣います。Cloud Logging ではリソース全体からの検索が可能であるため、一貫した命名規則を使用することにより、同じまたは類似のデータでタグ付けされた異なる DGS インスタンスから生成されたログを検索できるようになります。

このチュートリアルにおいてプロビジョニング サービスは、レンダリング ワーカー プロセスを開始する前に環境変数に次の表の値を設定します。これらの値は、ログにタグを付けるため、また、一意のファイル名を生成するために使用されます。

フィールド名 環境変数 値の例
環境 ENV prodqadev
バージョン VER 0112
ポート PORT 8001

この例では、これらの値で DGS の命名規則を構成します。

${ENV}.${VER}.${PORT}.log

ゲーム バージョン 0.1.12 の DGS 本番環境インスタンスのログには、次のようにタグが付けられます。

prod.0112.8001.log

このチュートリアルでは、インスタンス管理プロセスチームまたは運用チームがこの規則に従ってログファイル名を設定すると想定していますが、スタジオのニーズに合わせて指定されたコードを変更するのは簡単です。

構成を手動でテストする

  • DGS を実行せずに構成を確認するには、ホーム ディレクトリからテストログにサンプル ログエントリをコピーします。

    mkdir -p LinuxServer/UnrealTournament/Saved/Logs
    export ENV='testenv' VER='testver' PORT='testport'
    echo "testlogger:debug: Test log line at `date` from ${HOSTNAME}" >>
    LinuxServer/UnrealTournament/Saved/Logs/${ENV}.${VER}.${PORT}.log 

testlogger 行がログビューアに表示されます。

ログ配信を確認する

ログが Cloud Logging に配信されたことを確認するには、次の手順に従います。

  1. Cloud Console で、[ログビューア] ページに移動します。

    [ログビューア] ページに移動

    ログリストに、作成したログ名(この場合はPATH.testenv.testver.testid`)のタグが付いたエントリがあります。

  2. 出力を表示するには、ログをクリックします。

    [ログビューア] ページのログエントリ。

gcloud によるロギングの詳細については、ログエントリのドキュメントをご覧ください。

専用ゲームサーバーからログを送信する

構成が正しく設定されていることを確認したら、UT DGS コマンドを使用して Cloud Logging にログを送信できます。

  • ターミナルで DGS インスタンスを起動し、適切な名前のファイルにログ出力を送信します。

    ~/LinuxServer/Engine/Binaries/Linux/UE4Server-Linux-Shipping UnrealTournament \
    UT-Entry?Game=Lobby \
    -log=${ENV}.${VER}.${PORT}.log 

この例では、プロビジョニング レイヤによって環境変数(ENVVERDGSID)が設定されます。これらの変数はログファイルの名前を生成する際に使用されます。詳しくは、ログファイルに名前を付けるをご覧ください。

アプリケーションとワークフローから API に直接ロギングする

ほとんどの DGS デプロイ パイプラインでは、アセットの準備、ビルド、データ転送、インスタンス管理など、プログラムによるタスクを実行するために、いずれかのスクリプト言語が使用されます。クライアント ライブラリを使用して、これらのタスクの出力を Cloud Logging のログに記録できます。このチュートリアルでは、ゲーム業界で広く使用されている Python を使用しています。

Cloud Logging API を使用して、オンプレミスからも、クラウドベースのワークステーションからも Cloud Logging にログを送信できます。この方法でログを送信する場合は、Python API を介して Cloud Logging と通信するため、Logging エージェントをインストールする必要はありません。

Python ライブラリを使用して Cloud Logging にログを書き込む

Python スクリプトから Cloud Logging にログを記録するには、次の操作を行います。

  • ログメタデータを作成します。
  • 重大度を指定します。
  • ログに記録するリソースのタイプを決定します。

次の手順で Cloud Logging にログを書き込みます。

  1. GitHub から Python スクリプトをダウンロードして、次のタスクを実行します。

    • 適切な命名規則を使用していることを確認します。
    • ログデータを作成します。
    • Cloud プロジェクトのリソースレベルでログを書き込みます。
  2. オンプレミスのワークステーションまたはサーバーからログを記録する場合は、Cloud Logging へのロギングの前に認証が必要です。クラウド インスタンスからログを記録する場合は、認証はすでに完了しているので、この手順は省略できます。

    #!/usr/bin/env python
    
    from google.cloud import logging
    from google.cloud.logging.resource import Resource
    import getpass
    import os
    import socket
    
    def write(text, severity='INFO', env=None, port=None, ver=None, **kwargs):
        '''Wrapper method for assembling the payload to send to logger.log_text.'''
    
        # Extract and build log id from environment.
        # For example: 'prod.0112.8001'
        if not env:
            env = os.getenv('ENV')
        if not port:
            port = os.getenv('port')
        if not ver:
            ver = os.getenv('VER')
    
        if not env or not port or not ver:
            raise Exception('One or more log name tokens are empty. Unable to log.')
        # end if
    
        # Assemble logger name.
        logger_name = '.'.join([
            env,
            port,
            ver
        ])
    
        print '# Logging to %s...' % logger_name
    
        # Build logger object.
        logging_client = logging.Client()
        logger = logging_client.logger(logger_name)
    
        # Assemble the required log metadata.
        label_payload = {
            "username" : getpass.getuser(),
            "hostname" : socket.gethostname(),
            "env" : env,
            "ver" : ver,
            "port" : port
        }
    
        # Add optional kwargs to payload.
        label_payload.update(kwargs)
    
        # Write log.
        logger.log_text(
            text,
            resource=Resource(type='project', labels={'project_id':show}),
            severity=severity,
            labels=label_payload
        )
    
    # end write
    
  3. モジュールをパイプライン内の任意の Python スクリプトにインポートして、オンプレミス アーティスト ワークステーションまたはクラウド インスタンスで実行できます。

    import logToStackdriver as lts
    lts.write( 'This is the text to log.', env='qa', ver='0117', port='8000')
    
  4. ログを表示するには、Cloud Console で [ログビューア] ページに移動します。

    [ログビューア] ページに移動

    デフォルトでは、すべてのログが project リソースに書き込まれます。

ルーティング ログ

ログの保持期間より長くログを保持する場合は、次のいずれかの方法でログをルーティングします。

  • ログに対してビッグデータ分析を実行するには、BigQuery データセットにエクスポートします。
  • 低額で長期的なストレージを利用するには、ログを Cloud Storage バケットにエクスポートします。

いずれの場合も、まずシンクと呼ばれるオブジェクトを作成します。 シンクを使用すると、ルーティングするログエントリを選択するフィルタを作成できます。また、宛先として Cloud Storage または BigQuery を選択することもできます。シンクを作成すると、選択したログが指定のエクスポート先にエクスポートされます。

ログビューアにログをルーティングするときに、Cloud Logging API を使用することも、gcloud logging コマンドライン ツールを直接使用することもできます。

BigQuery にエクスポート

SQL セマンティクスを使用して、BigQuery に保存されたログをクエリできます。BigQuery には、多くのサードパーティ分析ツールが統合されています。

ログを BigQuery にエクスポートするには、次の手順を行います。

  1. BigQuery データセットを作成し、フィルタを含むシンクを作成して、そのテーブルにログをエクスポートします。

       gcloud beta logging sinks create dgs-errors-bq  \
        bigquery.googleapis.com/projects/PROJECT_ID/datasets/DATASET \
        --log-filter "jsonPayload.environment=dev AND \
        jsonPayload.version=0112 AND severity>=WARNING"
    

    以下のように置き換えます。

    • PROJECT_ID: Cloud プロジェクト
    • DATASET: 新しい BigQuery データセット
  2. BigQuery データセットにサービス アカウント名を追加します。

    Cloud Logging に送信されるログの中で、このフィルタに一致する次のログは、少し遅れてデータセットにエクスポートされます。詳細については、シンクの仕組みをご覧ください。

Cloud Storage にエクスポートする

ログをファイルに保存するには、それらを Cloud Storage バケットにエクスポートします。Cloud Storage バケットについては、アクセス頻度の低いファイル用の低価格のストレージ クラスを選択するか、または無料使用枠を利用できます。

Cloud Storage は、HTTP により、または他の多くの Google Cloud プロダクトとの直接統合によって簡単にアクセスできます。

ログを Cloud Storage にエクスポートするには、次の手順を行います。

  1. Cloud Storage バケットを作成し、Cloud Logging でフィルタを含むシンクを作成して、それらのログを Cloud Storage にエクスポートします。

    gcloud beta \
       logging sinks create dgs-errors-gcs \
       storage.googleapis.com/BUCKET_NAME \
       --log-filter "jsonPayload.environment=dev AND \
       jsonPayload.version=0112 AND severity>=WARNING"
    

    BUCKET-NAME を Cloud Storage バケットの一意の名前に置き換えます。

  2. Cloud Storage バケットにサービス アカウント名を追加します

    Cloud Logging に送信されるログの中で、このフィルタに一致する次のログは、少し遅れてバケット内のファイルにエクスポートされます。詳細については、シンクの仕組みをご覧ください。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトの削除

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

Compute Engine インスタンスの削除

Compute Engine インスタンスを削除するには:

  1. Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] に移動

  2. 削除するインスタンスのチェックボックスを選択します。
  3. インスタンスを削除するには、 [その他の操作] をクリックし、[削除] をクリックしてから、指示に沿って操作します。

Cloud Storage バケットの削除

Cloud Storage バケットを削除するには:

  1. Cloud Console の Cloud Storage ブラウザページに移動します。

    [ブラウザ] に移動

  2. 削除するバケットのチェックボックスをクリックします。
  3. バケットを削除するには、 [削除] をクリックして、指示に沿って操作します。

次のステップ

  • Google Cloud に関するリファレンス アーキテクチャ、図、チュートリアル、ベスト プラクティスを確認する。Cloud Architecture Center を確認します。