Suddividere le voci del log di controllo

Questo documento descrive come Cloud Logging suddivide gli audit log di grandi dimensioni e fornisce indicazioni su come ricomporre questi elementi e suddividere gli audit log.

Quando una singola voce di log di controllo supera il limite di dimensioni, Cloud Logging suddivide questa voce e distribuisce i dati contenuti nel voce dell'audit log originale in diverse voci. Gli utenti potrebbero voler riassemblare gli audit log suddivisi poiché le singole voci di log di suddivisione non contengono tutti dell'audit log originale.

Riconoscere le voci degli audit log suddivisi

Le voci del log suddivise contengono informazioni sulla voce originale da cui sono state suddivise. Se una voce di log contiene un campo split, la voce è il risultato della suddivisione di una voce di log originale più grande. split è un LogSplit contenente le informazioni necessarie per identificare i log split correlati le voci corrispondenti.

Ogni voce di log suddiviso contiene i seguenti campi:

  • split.uid: un identificatore univoco per il gruppo di voci di log che sono state suddivise da una voce di log originale comune. Il valore di questo campo è lo stesso per tutte le voci suddivise dalla voce di log originale.

  • split.index: la posizione di questa voce nella serie di voci suddivise. La la prima voce della suddivisione ha l'indice 0. split.index viene aggiunto anche al campo LogEntry.insertId.

  • split.totalSplits: il numero di voci di log in cui è stata suddivisa la voce di log originale. Il valore di questo campo è lo stesso per tutte le voci suddivise dalla voce di log originale.

Come viene suddivisa una voce di log

Quando una voce di audit log di grandi dimensioni viene suddivisa, i campi vengono distribuiti tra risultanti delle voci di log di suddivisione come segue:

  • Tutti i campi, tranne il campo protoPayload, vengono duplicati in ogni suddivisione .

  • I seguenti campi secondari protoPayload possono essere suddivisi tra più voci:

    • protoPayload.metadata
    • protoPayload.request
    • protoPayload.response
  • Tutti gli altri campi secondari protoPayload sono inclusi in tutte le voci di suddivisione.

  • Per i campi secondari protoPayload.metadata, protoPayload.request e protoPayload.response, i seguenti tipi di campi possono essere suddivisi in più voci:

Se un campo è un membro di un campo suddividibile, ma non è uno dei tipi di campi suddividibili, è presente solo in uno dei log di suddivisione.

Ad esempio, un campo booleano nel sottocampo protoPayload.request può solo vengono visualizzati in una voce di log suddivisa, ma in un campo stringa nella riga protoPayload.request può avere il contenuto suddiviso tra più voci di log suddivise.

Per un esempio di suddivisione di una voce lunga, consulta Esempio di voce di log log.

Campi ripetuti con molti valori

Quando il valore di protoPayload.metadata, protoPayload.request o Il campo protoPayload.response contiene un elenco di valori ripetuti, l'elenco potrebbe possono essere suddivisi e distribuiti su più voci di log suddivise.

Ad esempio, l'elenco di valori ["foo", "bar", "baz"] potrebbe essere suddiviso in due elenchi: ["foo", "ba"] e ["", "r", "baz"]. Il primo elenco è la voce con il valore split.index di 0 e il secondo elenco è nella voce con il valore split.index di 1. Il secondo elenco inizia con una stringa vuota per mantenere le posizioni di gli elementi nell'elenco e per indicare che gli elementi che si trovano nelle stesse posizioni i diversi elenchi devono essere uniti. Nell'esempio, ba è il secondo elemento di elenco nella voce 0, mentre r è il secondo elemento di elenco nella voce 1, vengono ricombinate nell'ordine bar durante il riassemblaggio dell'elenco originale.

Campi di grandi dimensioni non ripetuti

Quando i campi Struct e string di grandi dimensioni e non ripetuti vengono suddivisi, questi campi vengono gestiti come segue:

  • Un campo string viene suddiviso a livello di carattere e non a livello di byte. Pertanto, i caratteri multibyte non vengono alterati.

  • LogEntry.split.index controlla l'ordinamento dei contenuti dei campi suddivisi e non ripetuti.

Riassemblare la voce di log suddivisa

Per riassemblare un set di tronchi suddivisi:

  1. Ordina l'insieme di audit log suddivisi per LogEntry.split.index in ordine crescente.

  2. Crea una copia del primo log di suddivisione, dove LogEntry.split.index == 0. Questa copia è l'inizio del log riassemblato.

  3. Per le voci di log rimanenti, ripeti tutti i campi suddivisibili di protoPayload e completa i seguenti passaggi per ogni campo:

    1. Se il campo esiste già nel log riassemblato, aggiungi il contenuto di quel campo nel log riassemblato.

    2. Se il campo non esiste nel log riassemblato, copialo il tronco riassemblato

      Quando vengono suddivisi, i campi ripetuti mantengono l'indice dei suoi elementi, così puoi applica questi passaggi a livello di elemento quando riassembli un campo ripetuto.

  4. Dopo aver eseguito l'iterazione dei campi suddividibili, cancella LogEntry.split del log ricomposto.

  5. Rimuovi il suffisso .0 da LogEntry.insert_id del log riassemblato.

Query di esempio

Per trovare tutte le voci di log divise dalla stessa voce di log originale, esegui la seguente query Esplora log, che sostituisce il UID con il valore desiderato:

split.uid="UID"

Ad esempio:

split.uid="abc123"

Per trovare tutte le voci di log che fanno parte di qualsiasi suddivisione, esegui la seguente query:

split:*

Filtra audit log suddivisi

Puoi escludere tutti i log di controllo suddivisi da una query utilizzando il seguente filtro:

split.totalSplits = 0

Puoi anche includere solo la prima voce di un audit log suddiviso ed escludere il parametro le altre voci utilizzando il seguente filtro:

split.index = 0

Esempio di suddivisione della voce di log

L'esempio seguente mostra una voce di audit log prima di essere suddivisa in quattro nuove le voci di log. Le nuove voci mostrano come vengono gestiti i diversi campi nell'operazione di suddivisione.

Voce di log di controllo di dimensioni eccessive prima della suddivisione

{
  "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"},
      ]
    }
  }
}

Voce di log di controllo sovradimensionata dopo la suddivisione

La voce del log originale è suddivisa nelle seguenti voci. Tieni presente che ogni voce include l'oggetto split con un valore uid e un valore totalSplits pari a 4. Ogni voce ha un valore split.index di 0, 1, 2 o 3, che indica l'ordine delle voci del log suddiviso.

Voce di log suddivisa, indice 0

Ecco la prima voce di log suddiviso, con un valore split.index pari a 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 ",
    }
  }
}

Voce di log divisa, indice 1

Ecco la voce del log di suddivisione successiva, con un valore split.index pari a 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 ",
      }
    }
  }
}

Voce di log della suddivisione, indice 2

Ecco la prossima voce di log di suddivisione, con un valore split.index pari a 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.
      ]
    }
  }
}

Voce di log divisa, indice 3

Ecco la voce finale del log suddiviso, con un valore split.index pari a 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"},
      ]
    }
  }
}