Memisahkan entri log audit

Dokumen ini menjelaskan cara Cloud Logging memisahkan entri log audit yang berukuran besar dan memberikan panduan tentang cara menyusun ulang log audit yang dipisah ini.

Jika satu entri log audit melebihi batas ukuran, Cloud Logging akan memisahkan entri tersebut dan mendistribusikan data yang terdapat dalam entri log audit asli ke beberapa entri. Pengguna mungkin ingin menyusun ulang log audit yang terpisah karena setiap entri log terpisah tidak berisi semua kolom dari log audit asli.

Mengenali entri log audit terpisah

Entri log terpisah berisi informasi tentang entri asli tempat entri tersebut dibagi. Jika entri log berisi kolom split, entri tersebut adalah hasil pemisahan entri log asli yang lebih besar. Kolom split adalah objek LogSplit yang berisi informasi yang diperlukan untuk mengidentifikasi entri log pemisahan terkait.

Setiap entri log terpisah berisi kolom berikut:

  • split.uid: ID unik untuk grup entri log yang dipisahkan dari entri log asli yang umum. Nilai kolom ini sama untuk semua entri yang dipisahkan dari entri log asli.

  • split.index: posisi entri ini dalam serangkaian entri terpisah. Entri pertama dari pemisahan memiliki indeks 0. split.index juga ditambahkan ke kolom LogEntry.insertId.

  • split.totalSplits: jumlah entri log yang menjadi bagian dari entri log asli. Nilai kolom ini sama untuk semua entri yang dibagi dari entri log asli.

Cara entri log dibagi

Saat entri log audit yang berukuran besar dibagi, kolom akan didistribusikan di antara entri log terpisah yang dihasilkan sebagai berikut:

  • Semua kolom kecuali kolom protoPayload diduplikasi ke setiap entri pemisahan.

  • Subkolom protoPayload berikut dapat dibagi menjadi beberapa entri:

    • protoPayload.metadata
    • protoPayload.request
    • protoPayload.response
  • Semua subkolom protoPayload lainnya disertakan dalam semua entri pemisahan.

  • Untuk subkolom protoPayload.metadata, protoPayload.request, dan protoPayload.response, jenis kolom berikut dapat dibagi di beberapa entri:

Jika kolom adalah anggota kolom yang dapat dipisah, tetapi bukan salah satu jenis kolom yang dapat dipisah, kolom tersebut hanya ada di salah satu log pemisahan.

Misalnya, kolom boolean di subkolom protoPayload.request hanya dapat muncul dalam satu entri log terpisah, tetapi kolom string di subkolom protoPayload.request dapat memiliki konten yang dibagi di beberapa entri log terpisah.

Untuk contoh cara pemisahan entri yang panjang, lihat Contoh pemisahan entri log.

Kolom berulang dengan banyak nilai

Jika nilai kolom protoPayload.metadata, protoPayload.request, atau protoPayload.response berisi daftar nilai berulang, daftar tersebut mungkin dibagi dan didistribusikan di beberapa entri log terpisah.

Misalnya, daftar nilai ["foo", "bar", "baz"] dapat dibagi menjadi 2 daftar: ["foo", "ba"] dan ["", "r", "baz"]. Daftar pertama adalah entri dengan split.index dari 0, dan daftar kedua ada dalam entri dengan split.index dari 1. Daftar kedua dimulai dengan string kosong untuk mempertahankan posisi elemen dalam daftar dan untuk menunjukkan bahwa elemen dalam posisi yang sama di daftar yang berbeda harus digabungkan. Dalam contoh, ba adalah elemen daftar kedua dalam entri 0, dan r adalah elemen daftar kedua dalam entri 1, sehingga elemen tersebut digabungkan kembali dalam urutan bar saat menyusun ulang daftar asli.

Kolom besar yang tidak berulang

Saat kolom Struct dan string yang besar dan tidak berulang dibagi, kolom ini ditangani sebagai berikut:

  • Kolom string dibagi pada tingkat karakter, bukan pada tingkat byte. Jadi, karakter multibyte tidak diubah.

  • LogEntry.split.index mengontrol pengurutan konten kolom terpisah, yang tidak berulang.

Merakit ulang entri log yang terpecah

Untuk menyusun ulang kumpulan log yang terpisah, selesaikan langkah-langkah berikut:

  1. Urutkan kumpulan log audit terpisah menurut LogEntry.split.index dalam urutan mengalami kenaikan.

  2. Buat salinan log pemisahan pertama, dengan LogEntry.split.index == 0. Salinan ini adalah awal log yang disusun ulang.

  3. Untuk entri log yang tersisa, iterasi melalui semua kolom yang dapat dipisah dari protoPayload dan selesaikan langkah-langkah berikut untuk setiap kolom:

    1. Jika kolom sudah ada dalam log yang disusun ulang, tambahkan konten kolom tersebut ke dalam log yang disusun ulang.

    2. Jika kolom tidak ada dalam log yang disusun ulang, salin kolom tersebut ke dalam log yang disusun ulang

      Saat dipisah, kolom berulang akan mempertahankan indeks elemennya, sehingga Anda dapat menerapkan langkah-langkah ini di tingkat elemen saat menyusun ulang kolom berulang.

  4. Setelah melakukan iterasi pada kolom yang dapat dipisah, hapus LogEntry.split dari log yang disusun ulang.

  5. Hapus akhiran .0 dari LogEntry.insert_id log yang disusun ulang.

Sampel kueri

Untuk menemukan semua entri log yang dipisahkan dari entri log asli yang sama, jalankan kueri berikut di Logs Explorer, dengan mengganti variabel UID dengan nilai yang diinginkan:

split.uid="UID"

Contoh:

split.uid="abc123"

Untuk menemukan semua entri log yang merupakan bagian dari pemisahan, jalankan kueri berikut:

split:*

Memfilter log audit terpisah

Anda dapat mengecualikan semua log audit terpisah dari kueri menggunakan filter berikut:

split.totalSplits = 0

Anda juga dapat menyertakan hanya entri pertama dari log audit terpisah dan mengecualikan entri lainnya menggunakan filter berikut:

split.index = 0

Contoh pemisahan entri log

Contoh berikut menunjukkan entri log audit sebelum dibagi menjadi empat entri log baru. Entri baru menunjukkan cara berbagai kolom ditangani dalam operasi pemisahan.

Entri log audit yang terlalu besar sebelum pemisahan

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

Entri log audit yang terlalu besar setelah pemisahan

Entri log asli dibagi menjadi entri berikut. Perhatikan bahwa setiap entri menyertakan objek split dengan uid dan nilai totalSplits dari 4. Setiap entri memiliki nilai split.index 0, 1, 2, atau 3, yang menunjukkan urutan entri log terpisah.

Entri log terpisah, indeks 0

Berikut adalah entri log pemisahan pertama, dengan nilai split.index 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 ",
    }
  }
}

Entri log terpisah, indeks 1

Berikut adalah entri log pemisahan berikutnya, dengan nilai split.index 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 ",
      }
    }
  }
}

Entri log terpisah, indeks 2

Berikut adalah entri log pemisahan berikutnya, dengan nilai split.index 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.
      ]
    }
  }
}

Entri log terpisah, indeks 3

Berikut adalah entri log pemisahan akhir, dengan nilai split.index 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"},
      ]
    }
  }
}