Mengumpulkan log Google App Engine

Didukung di:

Dokumen ini menjelaskan cara menyerap log Google App Engine ke Google Security Operations menggunakan Google Cloud Storage V2.

Google App Engine adalah platform serverless yang terkelola sepenuhnya untuk membangun dan men-deploy aplikasi web dan API. App Engine secara otomatis membuat log permintaan untuk permintaan HTTP dan log aplikasi dari kode Anda. Log ini dikirim ke Cloud Logging dan dapat diekspor ke Cloud Storage untuk penyerapan ke Google Security Operations.

Sebelum memulai

Pastikan Anda memiliki prasyarat berikut:

  • Instance Google SecOps
  • Project GCP dengan Cloud Storage API diaktifkan
  • Izin untuk membuat dan mengelola bucket GCS
  • Izin untuk mengelola kebijakan IAM di bucket GCS
  • Izin untuk membuat sink Cloud Logging (roles/logging.configWriter)
  • Aplikasi App Engine yang aktif (lingkungan standar atau fleksibel)

Membuat bucket Google Cloud Storage

  1. Buka Konsol Google Cloud.
  2. Pilih project Anda atau buat project baru.
  3. Di menu navigasi, buka Cloud Storage > Buckets.
  4. Klik Create bucket.
  5. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Beri nama bucket Anda Masukkan nama yang unik secara global (misalnya, appengine-logs-export)
    Location type Pilih berdasarkan kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi (misalnya, us-central1)
    Kelas penyimpanan Standar (direkomendasikan untuk log yang sering diakses)
    Access control Seragam (direkomendasikan)
    Alat perlindungan Opsional: Aktifkan pembuatan versi objek atau kebijakan retensi
  6. Klik Create.

Mengonfigurasi Cloud Logging untuk mengekspor log App Engine ke GCS

Cloud Logging menggunakan sink log untuk merutekan entri log ke tujuan yang didukung, termasuk bucket Cloud Storage. Identitas penulis sink memerlukan peran Storage Object Creator (roles/storage.objectCreator) di bucket tujuan.

Membuat sink Cloud Logging

  1. Di Konsol Google Cloud, buka Logging > Log Router.
  2. Klik Create sink.
  3. Berikan detail konfigurasi berikut:
    • Sink name: Masukkan nama deskriptif (misalnya, appengine-to-gcs).
    • Deskripsi wastafel: Deskripsi opsional.
  4. Klik Berikutnya.
  5. Di bagian Pilih layanan sink:
    • Sink service: Pilih Bucket Cloud Storage.
    • Pilih bucket Cloud Storage: Pilih appengine-logs-export dari dropdown.
  6. Klik Berikutnya.
  7. Di bagian Choose logs to include in sink, masukkan kueri filter untuk memilih log App Engine. Jenis resource harus persis "gae_app".

    Untuk semua log App Engine (log permintaan dan aplikasi):

    resource.type="gae_app"
    

    Khusus untuk log permintaan App Engine:

    resource.type="gae_app"
    logName="projects/PROJECT_ID/logs/appengine.googleapis.com/request_log"
    

    Untuk log aplikasi App Engine (stdout/stderr):

    resource.type="gae_app"
    (logName="projects/PROJECT_ID/logs/stdout" OR logName="projects/PROJECT_ID/logs/stderr")
    

    Ganti PROJECT_ID dengan project ID GCP Anda.

  8. Klik Berikutnya.

  9. Tinjau konfigurasi, lalu klik Create sink.

Memberikan izin ke identitas penulis sink

Setelah membuat sink, Anda harus memberikan peran Storage Object Creator kepada identitas penulis sink di bucket tujuan. Identitas penulis untuk akun layanan akan terlihat seperti: serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com

  1. Di halaman Log Router, temukan sink yang baru dibuat.
  2. Klik ikon menu (tiga titik vertikal) di samping nama sink.
  3. Pilih Lihat detail sinkronisasi.
  4. Salin Identitas penulis (email akun layanan).
  5. Buka Cloud Storage > Buckets.
  6. Klik nama bucket (appengine-logs-export).
  7. Buka tab Izin.
  8. Klik Grant access.
  9. Berikan detail konfigurasi berikut:
    • Add principals: Tempel identitas penulis sink (email akun layanan).
    • Tetapkan peran: Pilih Storage Object Creator.
  10. Klik Simpan.

Mengambil akun layanan Google SecOps

Google SecOps menggunakan akun layanan unik untuk membaca data dari bucket GCS Anda. Anda harus memberi akun layanan ini akses ke bucket Anda.

Mengonfigurasi feed di Google SecOps untuk menyerap log App Engine

  1. Buka Setelan SIEM > Feed.
  2. Klik Tambahkan Feed Baru.
  3. Klik Konfigurasi satu feed.
  4. Di kolom Nama feed, masukkan nama untuk feed (misalnya, App Engine Logs).
  5. Pilih Google Cloud Storage V2 sebagai Source type.
  6. Pilih GCP_APP_ENGINE sebagai Log type.

  7. Klik Get Service Account.

  8. Email akun layanan yang unik akan ditampilkan, misalnya:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. Salin alamat email ini. Anda akan menggunakannya pada langkah berikutnya.

  10. Klik Berikutnya.

  11. Tentukan nilai untuk parameter input berikut:

    • URL bucket penyimpanan: Masukkan URI bucket GCS dengan jalur awalan:

      gs://appengine-logs-export/
      

      Cloud Logging mengatur file log yang diekspor dalam hierarki direktori menurut jenis dan tanggal log. Jenis log dapat berupa nama gabungan seperti appengine.googleapis.com/request_log. File di-shard dan diberi nama dengan jangka waktu (misalnya, 08:00:00_08:59:59_S0.json).

    • Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda:

      • Jangan pernah: Tidak pernah menghapus file apa pun setelah transfer (direkomendasikan untuk pengujian).
      • Hapus file yang ditransfer: Menghapus file setelah transfer berhasil.
      • Hapus file yang ditransfer dan direktori kosong: Menghapus file dan direktori kosong setelah transfer berhasil.
    • Usia File Maksimum: Menyertakan file yang diubah dalam beberapa hari terakhir. Defaultnya adalah 180 hari.

    • Namespace aset: Namespace aset.

    • Label penyerapan: Label yang akan diterapkan ke peristiwa dari feed ini.

  12. Klik Berikutnya.

  13. Tinjau konfigurasi feed baru Anda di layar Selesaikan, lalu klik Kirim.

Memberikan izin IAM ke akun layanan Google SecOps

Akun layanan Google SecOps memerlukan peran Storage Object Viewer di bucket GCS Anda.

  1. Buka Cloud Storage > Buckets.
  2. Klik nama bucket (appengine-logs-export).
  3. Buka tab Izin.
  4. Klik Grant access.
  5. Berikan detail konfigurasi berikut:
    • Add principals: Tempel email akun layanan Google SecOps.
    • Tetapkan peran: Pilih Storage Object Viewer.
  6. Klik Simpan.

Memahami struktur log App Engine

App Engine secara otomatis mengirimkan log permintaan dan log aplikasi ke Cloud Logging. App Engine secara otomatis memancarkan log untuk permintaan yang dikirim ke aplikasi Anda, sehingga tidak perlu menulis log permintaan. Bagian ini membahas cara menulis log aplikasi.

Log permintaan App Engine memiliki entri log yang berisi kolom protoPayload yang menyimpan objek jenis RequestLog dengan @type "type.googleapis.com/google.appengine.logging.v1.RequestLog". Jenis resource adalah "gae_app".

Secara default, payload log adalah string teks yang disimpan di kolom textPayload entri log. String ini muncul sebagai pesan di Logs Explorer dan dikaitkan dengan layanan dan versi App Engine yang menampilkannya.

Untuk menulis log terstruktur, Anda menulis log dalam bentuk satu baris JSON yang diserialisasi. Apabila Anda menyediakan log terstruktur sebagai kamus JSON, beberapa kolom khusus akan dihapus dari jsonPayload dan ditulis ke kolom yang sesuai dalam LogEntry yang dibuat. Misalnya, jika JSON Anda menyertakan properti tingkat keparahan, properti tersebut akan dihapus dari jsonPayload dan muncul sebagai tingkat keparahan entri log.

Batasan umum

Saat Anda merutekan log dari sink log ke Cloud Storage, tujuan Cloud Storage hanya berisi log permintaan. App Engine menulis log aplikasi ke folder yang berbeda.

Entri log yang dirutekan disimpan ke bucket Cloud Storage dalam batch per jam. Mungkin diperlukan waktu 2 hingga 3 jam sebelum entri pertama mulai muncul.

Di lingkungan fleksibel App Engine, logging berfungsi secara otomatis. Namun, log dikumpulkan dalam format yang berbeda. Log tidak akan dikelompokkan berdasarkan permintaan, dan log dari stdout dan stderr dikumpulkan secara terpisah.

Tabel pemetaan UDM

Kolom log Pemetaan UDM Logika
jsonPayload.logger, taskTypeName, jsonPayload.@type, jsonPayload.backendTargetProjectNumber, jsonPayload.cacheDecision, resource.labels.version_id, resource.labels.module_id, logName, spanId, trace, protoPayload.@type, labels.clone_id, operation.producer additional.fields Digabungkan dengan label nilai kunci yang dibuat dari setiap kolom
metadata metadata Diganti namanya dari metadata
receiveTimestamp metadata.collected_timestamp Diuraikan menggunakan filter tanggal dengan RFC3339
metadata.event_type Ditetapkan ke "USER_LOGIN" jika has_principal, has_target, has_principal_user; "NETWORK_CONNECTION" jika has_principal dan has_target; "USER_UNCATEGORIZED" jika tidak ada has_principal dan has_target; "STATUS_UPDATE" jika ada has_principal; "USER_UNCATEGORIZED" jika ada has_principal_user; atau "GENERIC_EVENT"
metadata.extensions.auth.type Tetapkan ke "AUTHTYPE_UNSPECIFIED" jika has_principal, has_target, has_principal_user
insertId metadata.product_log_id Nilai disalin secara langsung
httpRequest.requestMethod,protoPayload.method network.http.method Nilai dari httpRequest.requestMethod jika tidak kosong, atau protoPayload.method
httpRequest.userAgent network.http.parsed_user_agent Dikonversi ke parseduseragent
httpRequest.status network.http.response_code Dikonversi ke string, lalu ke bilangan bulat
httpRequest.userAgent network.http.user_agent Nilai disalin secara langsung
httpRequest.responseSize network.received_bytes Dikonversi ke uinteger
httpRequest.requestSize network.sent_bytes Dikonversi ke uinteger
utama utama Diganti namanya dari akun utama jika tidak kosong
protoPayload.host principal.asset.hostname Nilai disalin secara langsung
httpRequest.serverIp, protoPayload.ip principal.asset.ip Digabungkan dengan server_ip dari httpRequest.serverIp atau protoPayload.ip
protoPayload.host principal.hostname Nilai disalin secara langsung
httpRequest.serverIp, protoPayload.ip principal.ip Digabungkan dengan server_ip dari httpRequest.serverIp atau protoPayload.ip
protoPayload.appId principal.resource.attribute.labels Digabungkan dengan appId_label yang berisi kunci "appId" dan nilai dari kolom
requestUser principal.user.email_addresses Digabungkan dengan requestUser jika cocok dengan pola email
security_result security_result Digabungkan dari security_result
resource.labels.forwarding_rule_name security_result.rule_labels Digabungkan dengan rule_label yang berisi kunci "forwarding_rule_name" dan nilai dari kolom
tingkat keseriusan, security_result.severity Disetel ke tingkat keparahan jika cocok dengan (?i)ERROR|CRITICAL, INFORMATIONAL jika cocok dengan (?i)INFO, MEDIUM jika cocok dengan (?i)WARN, LOW jika cocok dengan (?i)DEBUG, atau UNKNOWN_SEVERITY jika tidak cocok
jsonPayload.statusDetails security_result.summary Nilai disalin secara langsung
target target Diganti namanya dari target jika tidak kosong
resource.labels.backend_service_name target.application Nilai disalin secara langsung
httpRequest.remoteIp, jsonPayload.remoteIp target.asset.ip Digabungkan dengan remote_ip yang diekstrak dari httpRequest.remoteIp atau jsonPayload.remoteIp
resource.labels.project_id target.cloud.project.name Nilai disalin secara langsung
httpRequest.remoteIp, jsonPayload.remoteIp target.ip Digabungkan dengan remote_ip yang diekstrak dari httpRequest.remoteIp atau jsonPayload.remoteIp
resource.labels.zone target.resource.attribute.cloud.availability_zone Nilai disalin secara langsung
resource.labels.target_proxy_name, resource.labels.url_map_name target.resource.attribute.labels Digabungkan dengan label dari setiap sumber
resource.type target.resource.type Nilai disalin secara langsung
httpRequest.requestUrl target.url Nilai disalin secara langsung
metadata.product_name Tetapkan ke "GCP_APP_ENGINE"
metadata.vendor_name Ditetapkan ke "GCP"

Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.