Cloud Logging als Logging-Server für dedizierte Spieleserver

In dieser Anleitung wird erläutert, wie Sie Cloud Logging anstelle eines lokalen Logging-Servers für das anwendungsspezifische Logging verwenden. Cloud Logging aggregiert standardmäßig Logs vom System und von vielen gängigen Anwendungen. In dieser Anleitung wird beschrieben, wie Logs zu benutzerdefinierten Workflows oder Anwendungen, die nicht in der Liste der allgemeinen Anwendungen aufgeführt sind, an Cloud Logging gesendet werden.

Der Schwerpunkt dieser Anleitung liegt auf Instanzen dedizierter Spieleserver (Dedicated Game Server, DGS). Als Beispiel dient das Serverbinärprogramm des Spiels Unreal Tournament (UT) von Epic Games. In einem typischen Anwendungsfall wird eine virtuelle Maschine (VM) von einem Bereitstellungssystem erstellt, das mit den Plattformdiensten des Spiels verbunden ist, um zur Abdeckung der Player-Anforderung einen DGS vorauslaufen zu lassen. Der DGS generiert Logs. Deren zentrale Speicherung und Indexierung sind bei der Identifizierung und Behebung von Fehlern von erheblichem Vorteil.

Ziele

  • DGS-Instanz erstellen und den Cloud Logging-Agent auf der Instanz installieren
  • DGS oder Workflow so konfigurieren, dass Logs an den Cloud Logging-Agent gesendet werden
  • Logs mithilfe der Python-Clientbibliothek direkt an Cloud Logging senden
  • Logs in Cloud Logging ansehen, filtern und durchsuchen
  • Logs aus Cloud Logging in langfristig verfügbaren Speicher exportieren

Kosten

In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Vorbereitung

  1. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  2. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

  3. Aktivieren Sie die Compute Engine API.

    Aktivieren Sie die API

  4. Installieren und initialisieren Sie das Cloud SDK.
  5. Installieren Sie die gcloud beta-Befehlskomponente:

    gcloud components install beta
  6. Legen Sie Ihr Standardprojekt so fest, dass Sie das Flag --project nicht bei jedem Befehl angeben müssen:

    gcloud config set project PROJECT_ID

Compute Engine-Instanz erstellen

Der Logging-Agent kann auf VM-Instanzen von Compute Engine und Amazon EC2 ausgeführt werden. Weitere Informationen zum Agent und den unterstützten VM-Instanzen finden Sie in der Produktdokumentation unter Informationen zum Logging-Agent. Für diese Anleitung können Sie eine Instanz mit dem VM-Typ n1-standard-8 erstellen. In einem Produktionssystem legen Sie den Maschinentyp danach fest, wie viele DGS-Instanzen auf jeder VM ausgeführt werden sollen.

  1. Rufen Sie in der Google Cloud Console die Seite Instanz erstellen auf.

    Zur Seite „Instanz erstellen“

  2. Geben Sie auf der Seite Neue Instanz erstellen die Attribute für Ihre Instanz ein. Maximieren Sie für erweiterte Konfigurationsoptionen den Bereich Verwaltung, Sicherheit, Laufwerke, Netzwerke, einzelne Mandanten.
  3. Klicken Sie auf Erstellen, um die VM zu erstellen.

Das Erstellen der neuen Instanz dauert einen Moment.

Compute Engine-Instanz konfigurieren

Nachdem Sie die VM-Instanz mithilfe eines Kontos mit Superuser-Berechtigungen erstellt haben, führen Sie vom Basisverzeichnis aus die folgenden Schritte durch:

  1. Stellen Sie in Ihrem Terminal über SSH eine Verbindung zur Instanz her:

    gcloud compute ssh sd-tutorial
    
  2. Installieren Sie den Logging-Agent.

  3. Als Nächstes laden Sie pip herunter und installieren es:

    sudo yum install python-pip
    
  4. Laden Sie die Cloud Logging-Python-Bibliothek herunter und installieren Sie sie:

    sudo pip install --upgrade google-cloud-logging
    
  5. Erstellen Sie im Verzeichnis /etc/google-fluentd/config.d die Logging-Agent-Konfigurationsdatei ut.conf für Unreal Tournament (UT) mit folgendem Inhalt:

    <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>
    

    Weitere Informationen zur fluentd-Konfiguration finden Sie unter Syntax der Konfigurationsdatei.

  6. Aktualisieren Sie die Logging-Agent-Konfiguration:

    sudo service google-fluentd reload
    

In dieser Anleitung wird davon ausgegangen, dass der UT-Build in der Standardverzeichnisstruktur des Nutzers in dessen Basisverzeichnis ist. Weitere Informationen finden Sie im UT-Wiki im Abschnitt zum Einrichten des Linux-Servers.

In einer Produktionsumgebung wird empfohlen, das Bootlaufwerk der konfigurierten VM als benutzerdefiniertes VM-Image zu speichern, das bei Bedarf von Ihrer Pipeline gestartet werden kann.

Überlegungen zum Logging in Cloud Logging von einem dedizierten Spieleserver

Jeder dedizierte Spieleserver generiert seine eigene Logausgabe in einem eigenen Format. In dieser Anleitung wird zwar der UT-DGS verwendet, aber Sie können die Anleitung auch an andere Engines oder Anwendungen anpassen, die Ausgaben an den Standard-Stream stdout/stderr erzeugen.

In dieser Anleitung wird eine einzige fluentd-Konfiguration für alle DGS-Instanzen verwendet und es wird davon ausgegangen, dass Ihr Bereitstellungssystem die Ausgabe jeder DGS-Instanz an einen Dateinamen mit einem bestimmten, suchfreundlichen Format weiterleitet. Wenn Sie mehrere DGS-Instanzen auf einer einzelnen VM ausführen, müssen Sie eindeutige Dateinamen verwenden. Die im folgenden Abschnitt erläuterten Skripts in dieser Anleitung erzwingen Einschränkungen für die Benennung von Logdateien. Aber keine dieser Einschränkungen gilt allgemein für Cloud Logging.

Standardmäßig werden von UT automatisch Sicherungen von Log-Dateien im Log-Verzeichnis erstellt. Der Logging-Agent liest diese als neue Dateien. Wir empfehlen, diese Option in der Produktionsphase zu deaktivieren, um doppelte Logs in Cloud Logging zu vermeiden.

Dateien für dedizierten Spieleserver benennen

Befolgen Sie zum Definieren der Namenskonvention für Ihre DGS-Logs die Best Practices oder Namenskonventionen Ihres Unternehmens. Cloud Logging kann ressourcenübergreifend suchen. Die Verwendung einheitlicher Namenskonventionen hilft bei der Suche nach Logs, die von verschiedenen DGS-Instanzen generiert wurden, die mit den gleichen oder ähnlichen Daten versehen sind.

In dieser Anleitung werden vor dem Start des Render-Worker-Prozesses vom Bereitstellungsdienst die in der folgenden Tabelle aufgeführten Werte in Umgebungsvariablen eingefügt. Diese finden anschließend zum Kennzeichnen der Logs und zum Generieren eines eindeutigen Dateinamens Anwendung:

Feldname Umgebungsvariable Beispielwerte
Umgebung ENV prod, qa, dev
Version VER 0112
Port PORT 8001

In diesem Beispiel werden die Werte in einer DGS-Namenskonvention zusammengefasst:

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

Die in einer Produktionsumgebung verwendeten Logs einer DGS-Instanz der Spieleversion 0.1.12 würden wie folgt gekennzeichnet:

prod.0112.8001.log

In dieser Anleitung wird davon ausgegangen, dass das für die Instanzverwaltung oder Betriebsabläufe zuständige Team den Log-Dateinamen gemäß dieser Konvention festlegt. Sie können den Code jedoch auch auf einfache Weise an Ihre Unternehmensanforderungen anpassen.

Die Konfiguration manuell testen

  • Kopieren Sie einen Beispiellogeintrag in ein Testlog, um die Konfiguration ohne Verwendung eines DGS zu prüfen:

    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 

Die Zeile testlogger sollte nach kurzer Zeit in der Loganzeige erscheinen.

Logzustellung bestätigen

So prüfen Sie, ob das Log an Cloud Logging zugestellt wurde:

  1. Rufen Sie in der Google Cloud Console die Seite Loganzeige auf.

    Loganzeige aufrufen

    In der Logliste ist ein Eintrag mit dem von Ihnen erstellten Lognamen gekennzeichnet, in diesem Fall PATH.testenv.testver.testid`.

  2. Klicken Sie auf das Log, um die Ausgabe anzuzeigen:

    Logeintrag auf der Seite &quot;Loganzeige&quot;.

Weitere Informationen zum gcloud-Logging finden Sie in der Dokumentation zu Logeinträgen.

Logs von einem dedizierten Spieleserver senden

Wenn die Konfiguration korrekt eingerichtet und geprüft ist, können Sie mit einem UT-DGS-Befehl Logs an Cloud Logging senden.

  • Starten Sie in Ihrem Terminal die DGS-Instanz und senden Sie die Logausgabe an eine entsprechend benannte Datei:

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

In diesem Beispiel gibt die Bereitstellungsebene die zum Generieren des Lognamens verwendeten Umgebungsvariablen ENV, VER und DGSID an. Weitere Informationen finden Sie oben im Abschnitt Logdateien benennen.

Logs von Anwendungen und Workflows direkt an die API senden

Die meisten Pipelines für DGS-Bereitstellungen führen programmgesteuerte Aufgaben wie die Asset-Vorbereitung, Build-Erstellung, Datenübertragung oder Instanzverwaltung unter Verwendung einer Skriptsprache aus. Sie können die Ausgabe dieser Aufgaben mithilfe einer Clientbibliothek in Cloud Logging protokollieren. In dieser Anleitung wird die in der Spielebranche gängige Python-Clientbibliothek verwendet.

Mit der Cloud Logging API können Sie Logs sowohl von lokalen als auch von cloudbasierten Workstations an Cloud Logging senden. Wenn Sie Logs auf diese Weise übertragen, müssen Sie keinen Logging-Agent installieren, weil die Cloud Logging-Kommunikation über die Python API läuft.

Logs mithilfe der Python-Bibliothek an Cloud Logging senden

Gehen Sie so vor, um ein Log von einem Python-Skript an Cloud Logging zu senden:

  • Erstellen Sie die Logmetadaten erstellen.
  • Geben Sie die Wichtigkeitsstufe an.
  • Legen Sie fest, an welche Art von Ressource Logs gesendet werden sollen.

So senden Sie ein Log an Cloud Logging:

  1. Laden Sie das Python-Skript von GitHub herunter, um die folgenden Aufgaben auszuführen:

    • Prüfen Sie, ob Sie die richtigen Namenskonventionen verwenden.
    • Stellen Sie die Logdaten zusammen.
    • Schreiben Sie das Log auf Ressourcenebene des Cloud-Projekts.
  2. Beim Logging über eine lokale Workstation oder einen lokalen Server müssen Sie sich vor dem Logging in Cloud Logging authentifizieren. Bei dem Logging von einer Cloud-Instanz aus ist die Authentifizierung bereits erfolgt. Sie können diesen Schritt überspringen.

    #!/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. Sie können das Modul in jedes Python-Skript Ihrer Pipeline importieren und entweder auf einer lokalen Grafikworkstation oder einer Cloudinstanz ausführen:

    import logToStackdriver as lts
    lts.write( 'This is the text to log.', env='qa', ver='0117', port='8000')
    
  4. Um die Logs anzusehen, rufen Sie in der Cloud Console die Seite Loganzeige auf.

    Loganzeige aufrufen

    Standardmäßig werden alle Logs in die Ressource project geschrieben.

Routing-Logs

Wenn Sie Ihre Logs über die Aufbewahrungsdauer hinaus behalten möchten, sollten Sie sie weiterleiten. Verwenden Sie dazu eine der folgenden Methoden:

  • Wenn Big Data-Analysen daran durchgeführt werden sollen, exportieren Sie die Logs in ein BigQuery-Dataset.
  • Wenn Sie eine kostengünstige, langfristige Speicherung wünschen, exportieren Sie Ihre Logs in Cloud Storage-Buckets.

In beiden Fällen erstellen Sie zuerst ein Objekt, das als Senke bezeichnet wird. Mit der Senke können Sie einen Filter für die weiterzuleitenden Logeinträge erstellen und Cloud Storage oder BigQuery als Ziel wählen. Wenn Sie eine Senke erstellen, werden die ausgewählten Logs an das ausgewählte Ziel exportiert.

Sie können Logs auch in der Loganzeige über die Cloud Logging API oder direkt über das gcloud logging-Befehlszeilentool weiterleiten.

Nach BigQuery exportieren

Sie können in BigQuery gespeicherte Logs mit SQL-Semantik abfragen. Viele Analysetools von Drittanbietern sind in BigQuery eingebunden.

So exportieren Sie Logs nach BigQuery:

  1. Erstellen Sie ein BigQuery-Dataset und erstellen Sie die Senke mit einem Filter, um Logs in diese Tabelle zu exportieren.

       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"
    

    Dabei gilt:

    • PROJECT_ID: ist ihr Cloudprojekt
    • DATASET: ist ihr neues BigQuery-Dataset
  2. Fügen Sie dem BigQuery-Dataset den Namen des Dienstkontos hinzu.

    Das nächste an Cloud Logging gesendete Log, das mit diesem Filter übereinstimmt, wird mit einer geringen Verzögerung in das Dataset exportiert. Weitere Informationen finden Sie in der Dokumentation zur Funktionsweise von Senken.

Nach Cloud Storage exportieren

Zum Speichern Ihrer Logs in einer Datei exportieren Sie sie in einen Cloud Storage-Bucket. Bei Cloud Storage-Buckets können Sie für Dateien, auf die seltener zugegriffen wird, eine kostengünstigere Speicherklasse auswählen oder das kostenlose Kontingent in Anspruch nehmen.

Cloud Storage bietet einfachen Zugriff entweder über HTTP oder durch direkte Einbindung in viele andere Google Cloud-Produkte.

So exportieren Sie Logs nach Cloud Storage:

  1. Erstellen Sie in Cloud Logging einen Cloud Storage-Bucket und eine Senke mit einem Filter, um diese Logs nach Cloud Storage zu exportieren:

    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"
    

    Ersetzen Sie BUCKET-NAME durch einen eindeutigen Namen für den Cloud Storage-Bucket.

  2. Fügen Sie den Dienstkontonamen zu Ihrem Cloud Storage-Bucket hinzu.

    Das nächste an Cloud Logging gesendete Log, das mit diesem Filter übereinstimmt, wird nach einer kurzen Verzögerung in eine Datei im Bucket exportiert. Weitere Informationen finden Sie unter Funktionsweise von Senken.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten durch Löschen des für die Anleitung erstellten Projekts.

So löschen Sie das Projekt:

  1. Wechseln Sie in der Cloud Console zur Seite Ressourcen verwalten.

    Zur Seite „Ressourcen verwalten“

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.

Compute Engine-Instanzen löschen

So löschen Sie eine Compute Engine-Instanz:

  1. Öffnen Sie in der Cloud Console die Seite VM-Instanzen.

    Zu „VM-Instanzen“

  2. Klicken Sie auf das Kästchen für die Die Instanz, die Sie löschen möchten.
  3. Klicken Sie zum Löschen der Instanz auf Weitere Aktionen, dann auf Löschen und folgen Sie der Anleitung.

Cloud Storage-Bucket löschen

So löschen Sie einen Cloud Storage-Bucket:

  1. Wechseln Sie in der Cloud Console zum Cloud Storage-Browser.

    Browser aufrufen

  2. Klicken Sie auf das Kästchen neben dem Bucket, der gelöscht werden soll.
  3. Klicken Sie zum Löschen des Buckets auf Löschen und folgen Sie der Anleitung.

Nächste Schritte

  • Referenzarchitekturen, Diagramme, Anleitungen und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center