Audit-Logeinträge aufteilen

In diesem Dokument wird beschrieben, wie in Cloud Logging zu große Audit-Logeinträge aufgeteilt werden. Außerdem erhalten Sie eine Anleitung zum Zusammensetzen dieser aufgeteilten Audit-Logs.

Wenn ein einzelner Audit-Logeintrag die Größenbeschränkung überschreitet, teilt Cloud Logging diesen Eintrag auf und verteilt die im ursprünglichen Audit-Logeintrag enthaltenen Daten auf mehrere Einträge. Nutzer können die geteilten Audit-Logs wieder zusammensetzen, da die einzelnen geteilten Logeinträge nicht alle Felder aus dem ursprünglichen Audit-Log enthalten.

Aufgeteilte Audit-Logeinträge erkennen

Geteilte Logeinträge enthalten Informationen zum ursprünglichen Eintrag, aus dem sie stammen. Wenn ein Logeintrag das Feld split enthält, ist er das Ergebnis der Aufteilung eines größeren ursprünglichen Logeintrags. Das Feld split ist ein LogSplit-Objekt, das die Informationen enthält, die zum Identifizieren zugehöriger aufgeteilter Logeinträge erforderlich sind.

Jeder geteilte Logeintrag enthält die folgenden Felder:

  • split.uid: Eine eindeutige Kennung für die Gruppe von Logeinträgen, die aus einem gemeinsamen ursprünglichen Logeintrag aufgeteilt wurden. Der Wert dieses Felds ist für alle Einträge identisch, die aus dem ursprünglichen Logeintrag aufgeteilt wurden.

  • split.index: die Position dieses Eintrags in der Reihe der aufgeteilten Einträge. Der erste Eintrag der Aufteilung hat den Index 0. split.index wird auch an das Feld LogEntry.insertId angehängt.

  • split.totalSplits: Die Anzahl der Logeinträge, in die der ursprüngliche Logeintrag aufgeteilt wurde. Der Wert dieses Felds ist für alle Einträge identisch, die aus dem ursprünglichen Logeintrag aufgeteilt wurden.

So wird ein Logeintrag aufgeteilt

Wenn ein zu großer Audit-Logeintrag aufgeteilt wird, werden die Felder auf die resultierenden aufgeteilten Logeinträge wie folgt verteilt:

  • Alle Felder mit Ausnahme des Felds protoPayload werden in jedem aufgeteilten Eintrag dupliziert.

  • Die folgenden untergeordneten Felder von protoPayload können auf mehrere Einträge aufgeteilt werden:

    • protoPayload.metadata
    • protoPayload.request
    • protoPayload.response
  • Alle anderen protoPayload-Unterfelder sind in allen aufgeteilten Einträgen enthalten.

  • Für die Unterfelder protoPayload.metadata, protoPayload.request und protoPayload.response können die folgenden Feldtypen auf mehrere Einträge aufgeteilt werden:

Wenn ein Feld zu einem teilbaren Feld gehört, aber nicht zu den teilbaren Feldtypen, ist es nur in einem der geteilten Logs vorhanden.

Ein boolesches Feld im Unterfeld protoPayload.request kann beispielsweise nur in einem geteilten Logeintrag vorkommen. Der Inhalt eines Stringfelds im Unterfeld protoPayload.request kann jedoch auf mehrere geteilte Logeinträge aufgeteilt werden.

Ein Beispiel für die Aufteilung eines langen Eintrags finden Sie unter Beispiel für die Aufteilung eines Logeintrags.

Wiederkehrende Felder mit vielen Werten

Wenn der Wert des Felds protoPayload.metadata, protoPayload.request oder protoPayload.response eine Liste mit wiederholten Werten enthält, wird die Liste möglicherweise auf mehrere geteilte Protokolleinträge aufgeteilt.

Die Werteliste ["foo", "bar", "baz"] kann beispielsweise in zwei Listen aufgeteilt werden: ["foo", "ba"] und ["", "r", "baz"]. Die erste Liste ist der Eintrag mit der split.index von 0 und die zweite Liste ist im Eintrag mit der split.index von 1. Die zweite Liste beginnt mit einem leeren String, um die Positionen der Elemente in der Liste beizubehalten und anzugeben, dass Elemente an denselben Positionen in den verschiedenen Listen zusammengeführt werden müssen. Im Beispiel ist ba das zweite Listenelement im Eintrag 0 und r das zweite Listenelement im Eintrag 1. Sie werden also in der Reihenfolge bar wieder zusammengesetzt, wenn die ursprüngliche Liste wiederhergestellt wird.

Große, nicht wiederkehrende Felder

Wenn große, nicht wiederholte Struct- und string-Felder aufgeteilt werden, werden diese Felder so behandelt:

  • Ein string-Feld wird auf Zeichenebene und nicht auf Byteebene aufgeteilt. Mehrere Byte umfassende Zeichen werden also nicht geändert.

  • Mit LogEntry.split.index wird die Reihenfolge der Inhalte in geteilten, nicht wiederholten Feldern gesteuert.

Aufgeteilten Logeintrag wieder zusammenführen

So können Sie mehrere geteilte Protokolle wieder zusammenführen:

  1. Sortieren Sie die aufgeteilten Audit-Logs in aufsteigender Reihenfolge nach LogEntry.split.index.

  2. Erstellen Sie eine Kopie des ersten geteilten Logs, wobei LogEntry.split.index == 0. Diese Kopie ist der Beginn des neu zusammengesetzten Logs.

  3. Gehen Sie für die verbleibenden Logeinträge alle teilbaren Felder von protoPayload durch und führen Sie für jedes Feld die folgenden Schritte aus:

    1. Wenn das Feld bereits im zusammengesetzten Protokoll vorhanden ist, fügen Sie den Inhalt dieses Felds an das zusammengesetzte Protokoll an.

    2. Wenn das Feld im zusammengesetzten Protokoll nicht vorhanden ist, kopieren Sie es in das zusammengesetzte Protokoll.

      Bei der Aufteilung von wiederholten Feldern bleibt der Index ihrer Elemente erhalten. Sie können diese Schritte also auf Elementebene anwenden, wenn Sie ein wiederholtes Feld wieder zusammensetzen.

  4. Nachdem Sie die teilbaren Felder durchgegangen sind, löschen Sie LogEntry.split aus dem zusammengesetzten Protokoll.

  5. Entfernen Sie das Suffix .0 aus dem LogEntry.insert_id des zusammengesetzten Protokolls.

Beispielabfragen

Wenn Sie alle Logeinträge finden möchten, die aus demselben ursprünglichen Logeintrag aufgeteilt wurden, führen Sie die folgende Abfrage im Log-Explorer aus und ersetzen Sie die Variable UID durch den gewünschten Wert:

split.uid="UID"

Beispiel:

split.uid="abc123"

Mit der folgenden Abfrage können Sie alle Logeinträge finden, die zu einer Aufteilung gehören:

split:*

Aufgeteilte Audit-Logs herausfiltern

Mit dem folgenden Filter können Sie alle gesplitteten Audit-Logs aus einer Abfrage ausschließen:

split.totalSplits = 0

Sie können auch nur den ersten Eintrag eines aufgeteilten Audit-Logs einbeziehen und den Rest ausschließen. Verwenden Sie dazu den folgenden Filter:

split.index = 0

Beispiel für einen aufgeteilten Logeintrag

Das folgende Beispiel zeigt einen Audit-Logeintrag, bevor er in vier neue Logeinträge aufgeteilt wird. Die neuen Einträge zeigen, wie verschiedene Felder bei der Aufteilung behandelt werden.

Übergroßer Audit-Logeintrag vor dem Aufteilen

{
  "insertId": "567",
  "logName": "projects/1234/logs/cloudaudit.googleapis.com%2Fdata_access",
  "resource": {
    "type": "audited_resource"
  },
  "protoPayload": {
    "serviceName": "example.googleapis.com",
    "methodName": "google.cloud.example.ExampleMethod",
    "resourceName": "projects/1234/resources/123",
    "status": {
      "code": 0
    },
    "authenticationInfo": {
      "principalEmail": "user@example_company.com"
    },
    "authorizationInfo": [
      {
        "resource": "example.googleapis.com/projects/1234/resources/123",
        "permission": "examples.get",
        "granted": "true"
      }
    ],
    "request" {
      "boolField": true,
      "numberField": 123,
      "stringField": "Very long string that needs 2 log entries.",
      "structField": {
        "nestedNumberField": 1337,
        "nestedStringField": "Another long string that needs 2 log entries.",
      },
      "listField" [
        {"value": "short 1"},
        {"value": "Yet another long string."},
        {"value": "short 2"},
        {"value": "short 3"},
      ]
    }
  }
}

Übergroßer Audit-Logeintrag nach dem Aufteilen

Der ursprüngliche Logeintrag wird in die folgenden Einträge unterteilt. Jeder Eintrag enthält das split-Objekt mit einem uid- und einem totalSplits-Wert von 4. Jeder Eintrag hat den split.index-Wert 0, 1, 2 oder 3, der die Reihenfolge der geteilten Logeinträge angibt.

Logeintrag aufteilen, Index 0

Hier ist der erste Split-Logeintrag mit dem split.index-Wert 0.

{
  "insertId": "567.0",
  "logName": "projects/1234/logs/cloudaudit.googleapis.com%2Fdata_access",
  "resource": {
    "type": "audited_resource"
  },
  "split": { 
    "uid": "789+2022-02-22T12:22:22.22+05:00",
    "index": 0,
    "totalSplits": 4,
  },
  "protoPayload": {
    // The following fields are included in all split entries
    "serviceName": "example.googleapis.com",
    "methodName": "google.cloud.example.ExampleMethod",
    "resourceName": "projects/1234/resources/123",
    "status": {
      "code": 0
    },
    "authenticationInfo": {  // small size; included in all split entries
      "principalEmail": "user@example_company.com"
    },
   // The following field is included in this split entry only.
   "authorizationInfo": [
      {
        "resource": "spanner.googleapis.com/projects/1234/datasets/123",
        "permission": "databases.read",
        "granted": "true"
      }
    ],
    // The following field is split across all the split entries
    "request" { 
      // boolField and numberField can only be in one split.
      "boolField": true,
      "numberField": 123,
      // Split with the next LogEntry.
      "stringField": "Very long string that ",
    }
  }
}

Logeintrag aufteilen, Index 1

Hier ist der nächste Split-Logeintrag mit dem split.index-Wert 1.

{
  "insertId": "567.1",
  "logName": "projects/1234/logs/cloudaudit.googleapis.com%2Fdata_access",
  "resource": {
    "type": "audited_resource"
  },
  "split": { 
    "uid": "567+2022-02-22T12:22:22.22+05:00",
    "index": 1,
    "totalSplits": 4,
  },
  "protoPayload": { 
    "serviceName": "example.googleapis.com",
    "methodName": "google.cloud.example.ExampleMethod",
    "resourceName": "projects/1234/resources/123",
    "status": {
      "code": 0
    },
    "authenticationInfo": {
      "principalEmail": "user@example_company.com"
    },
    "request" { 
      // boolField and numberField aren't present
      // Continued from the previous entry.
      "stringField": "needs 2 log entries.",
      "structField": { 
        "nestedNumberField": 1337,
        // Split with the next LogEntry.
        "nestedStringField": "Another long string ",
      }
    }
  }
}

Logeintrag aufteilen, Index 2

Hier ist der nächste Split-Logeintrag mit dem Wert split.index für 2.

{
  "insertId": "567.2",
  "logName": "projects/1234/logs/cloudaudit.googleapis.com%2Fdata_access",
  "resource": {
    "type": "audited_resource"
  },
  "split": { 
    "uid": "567+2022-02-22T12:22:22.22+05:00",
    "index": 2,
    "totalSplits": 4,
  },
  "protoPayload": { 
    "serviceName": "example.googleapis.com",
    "methodName": "google.cloud.example.ExampleMethod",
    "resourceName": "projects/1234/resources/123",
    "status": {
      "code": 0
    },
    "authenticationInfo": {
      "principalEmail": "user@example_company.com"
    },
    request { 
      "structField": { 
        // Continued from the previous entry.
        "nestedStringField": "that needs 2 log entries.",
      }
      "listField" [ 
         {"value": "short 1"},
         {"value": "Yet another "}, // Split with the next LogEntry.
        // Missing two values, split with the next LogEntry.
      ]
    }
  }
}

Logeintrag aufteilen, Index 3

Hier ist der letzte Split-Logeintrag mit dem Wert split.index für 3.

{
  "insertId": "567.3",
  "logName": "projects/1234/logs/cloudaudit.googleapis.com%2Fdata_access",
  "resource": {
    "type": "audited_resource"
  },
  "split": { 
    "uid": "567+2022-02-22T12:22:22.22+05:00",
    "index": 3,
    "totalSplits": 4,
  },
  "protoPayload": { 
    "serviceName": "example.googleapis.com",
    "methodName": "google.cloud.example.ExampleMethod",
    "resourceName": "projects/1234/resources/123",
    "status": {
      "code": 0
    },
    "authenticationInfo": {
      "principalEmail": "user@example_company.com"
    },
    "request" { 
      "listField" [ 
        {}, // Padding to ensure correct positioning of elements in split repeated fields.
         {"value": "long string."}, // Continuation of the second repeated field.
         {"value": "short 2"},
         {"value": "short 3"},
      ]
    }
  }
}