Skip to content

Log Types & Ingestion Pipeline

Tại sao phân loại log quan trọng trong production

Cloud Logging nhận log từ nhiều nguồn khác nhau, và mỗi nguồn có hành vi, chi phí, và cơ chế điều khiển khác nhau. Lỗi phổ biến nhất là xem tất cả log như nhau — cùng cách exclude, cùng cách query, cùng expectation về latency.

Thực tế, có những log không thể tắt (Admin Activity Audit Logs, System Event Audit Logs), có những log tốn tiền nếu bật (Data Access Audit Logs), và có những log mặc định bật với volume khổng lồ (VPC Flow Logs, GKE system logs). Biết log nào thuộc loại nào là bước đầu tiên để kiểm soát được hệ thống.


Internal Model: Kiến Trúc Ingestion Pipeline

Dòng chảy của một log entry

Khi một service GCP tạo ra một log entry — dù là GKE tạo container log, IAM ghi một audit event, hay ứng dụng của bạn gọi Cloud Logging API — entry đó đi qua một pipeline trước khi xuất hiện trong Logs Explorer:

Log Source (GCP Service / Application / Ops Agent)


Cloud Logging Ingestion API

         ▼ (timestamp validation, size check)
Log Router (mỗi project/folder/org có một instance)

         ├── Sink 1: _Required (luôn nhận audit logs cụ thể)
         ├── Sink 2: _Default (nhận tất cả còn lại)
         └── Sink N: Custom sinks (user-defined)


Log Buckets / BigQuery / Cloud Storage / Pub/Sub

Log Router là thành phần trung tâm — nó không phải một service riêng biệt mà là một component logic tồn tại ở mỗi resource level (project, billing account, folder, organization). Log Router tạm thời buffer log entries để bảo vệ khỏi disruption, sau đó evaluate từng entry qua các sinks.

Ingestion point: Cloud Logging API

Tất cả log entries đều đi qua Cloud Logging Ingestion API, bao gồm:

  • Platform logs: GCP services tự gọi Logging API nội bộ (ví dụ: Cloud Run ghi container logs, GKE ghi kubelet logs)
  • Ops Agent: Agent chạy trên VM, đọc /var/log/ và stdout/stderr của process, gọi Logging API
  • Structured logging: Application gọi trực tiếp logging.googleapis.com/v2/entries:write
  • Client libraries: gcloud SDK, Python google-cloud-logging, Java cloud-logging, etc. — đều wrap API này

Vì mọi thứ đi qua cùng một API endpoint, API rate limit áp dụng chung. Mặc định mỗi project có quota 60,000 log entries/phút. Nếu nhiều services đồng thời spike (ví dụ: deploy đồng loạt gây error storm), entries có thể bị từ chối với lỗi RESOURCE_EXHAUSTED.

Timestamp validation: tại sao quan trọng

Cloud Logging không chấp nhận entries có timestamp quá cũ hoặc quá mới:

  • Entries có timestamp > 24 giờ trong tương lai bị từ chối
  • Entries có timestamp ngoài retention window của bucket bị từ chối (ví dụ: bucket giữ 30 ngày, entry có timestamp cách đây 45 ngày sẽ không được ghi)

Điều này ảnh hưởng đến backfilling log. Nếu bạn muốn import log lịch sử từ external system vào Cloud Logging, entry timestamp phải nằm trong retention window của bucket đích. Đây là lý do một số team chọn BigQuery làm điểm cuối cho historical log thay vì Cloud Logging buckets.


Phân Loại Log — Bốn Nhóm Chính

1. Platform Logs

Platform logs là log được GCP services tự ghi để phản ánh hoạt động của service đó. Người dùng không cần cấu hình gì — log xuất hiện tự động khi service hoạt động.

Ví dụ thực tế:

  • GKE cluster logs: kubelet restart events, node cordon events, pod eviction logs
  • Cloud Run logs: container stdout/stderr, request logs, instance lifecycle
  • Cloud SQL logs: slow query logs, error logs, connection logs
  • Cloud Load Balancing: access logs từ backend HTTP(S) requests
  • VPC Flow Logs: network traffic flow records (cần bật explicitly, nhưng tự động stream sau đó)

Platform logs không đồng nhất về chi phí. Phần lớn là miễn phí để ingest, nhưng storage sau 30 ngày tính phí. Một số loại như VPC Flow Logs và Cloud Load Balancing access logs có thể tạo ra volume rất lớn cần exclusion filter hoặc aggregation để kiểm soát.

Đặc tính kỹ thuật: Platform logs thường có structured format với các fields chuẩn. GKE container logs có kubernetes.labels, kubernetes.namespace_name, kubernetes.pod_name. Cloud Run có httpRequest object. Sử dụng các fields này trong query để filter hiệu quả.

2. User-Written Logs (Application Logs)

User-written logs là log do ứng dụng của bạn ghi vào Cloud Logging. Đây là nguồn log bạn hoàn toàn kiểm soát được về volume và format.

Ba cách ghi log từ application:

a) Ops Agent (cho VM/GCE): Ops Agent là successor của Stackdriver Logging Agent cũ. Nó đọc log files từ filesystem (mặc định /var/log/syslog, /var/log/auth.log, stdout/stderr của services) và streaming vào Cloud Logging. Cũng thu thập metrics cho Cloud Monitoring.

yaml
# ops-agent config (mặc định path)
logging:
  receivers:
    syslog:
      type: files
      include_paths: ["/var/log/syslog"]
  service:
    pipelines:
      default:
        receivers: [syslog]

b) Cloud Logging API trực tiếp:

python
from google.cloud import logging as cloud_logging

client = cloud_logging.Client()
logger = client.logger("my-application")

# Structured log entry
logger.log_struct({
    "message": "Payment processed",
    "user_id": "u-12345",
    "amount": 99.99,
    "currency": "USD"
}, severity="INFO")

c) Standard logging với auto-detection (GKE/Cloud Run): Trên GKE và Cloud Run, nếu container ghi JSON-formatted log ra stdout, Cloud Logging tự động parse nó thành structured entry. Đây là cách được khuyến nghị — không cần thêm library, platform handle log routing.

json
{
  "severity": "ERROR",
  "message": "Database connection failed",
  "trace": "projects/my-project/traces/abc123",
  "span_id": "def456",
  "error": {
    "type": "ConnectionTimeout",
    "code": "ETIMEOUT"
  }
}

Structured logging vs unstructured logging: Cloud Logging phân biệt hai dạng. Unstructured log (plain text) được lưu trong field textPayload. Structured log (JSON object) được lưu trong field jsonPayload và có thể được query theo từng field. Luôn dùng structured logging nếu bạn cần filter, alert, hoặc tạo metric từ log.

3. Security Logs

Security logs bao gồm hai subcategories chính:

Cloud Audit Logs (chi tiết ở File 02): Ghi lại mọi administrative action và data access trong GCP. Đây là loại log quan trọng nhất cho security compliance và forensics.

Access Transparency Logs: Ghi lại những hành động mà Google Cloud staff thực hiện trên infrastructure của bạn — ví dụ khi Google SRE truy cập vào dữ liệu khách hàng theo yêu cầu support. Access Transparency Logs chỉ available với một số tier dịch vụ (cần Premium Support hoặc Enterprise tier, hoặc dùng với Cloud KMS/CMEK). Đây là cơ chế transparency, không phải cơ chế security enforcement.

# Access Transparency Log entry example
{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.v1.TransparencyAuditLog",
    "accesses": [{
      "methodName": "ReadObject",
      "resourceName": "projects/_/buckets/my-bucket/objects/sensitive-data.csv"
    }],
    "reasons": [{
      "type": "CUSTOMER_INITIATED_SUPPORT",
      "detail": "Support case #12345678"
    }]
  }
}

4. Component Logs

Component logs là log được tạo bởi Google-managed software chạy trên infrastructure của bạn — khác với Platform logs (do GCP service infrastructure tạo ra). Ví dụ:

  • GKE system components: kube-apiserver, kube-scheduler, kube-controller-manager (chỉ available trong một số cluster configurations)
  • GKE node system logs: containerd logs, kubelet startup logs
  • Fluent Bit logging agent trên GKE nodes

Sự phân biệt giữa Platform logs và Component logs đôi khi không rõ ràng trong thực tế, nhưng quan trọng khi troubleshoot: Component logs phản ánh behavior của software layer trung gian, không phải GCP service layer hay application layer.


Log Entry Structure — Anatomy of an Entry

Mọi log entry trong Cloud Logging đều có chung một schema cơ bản (LogEntry proto):

LogEntry {
  logName:      string    // "projects/PROJECT_ID/logs/LOG_ID"
  resource:     MonitoredResource {
    type:       string    // "gce_instance", "k8s_container", "cloud_run_revision"
    labels:     map       // resource-specific labels: project_id, location, etc.
  }
  timestamp:    Timestamp // thời gian entry được tạo
  receiveTimestamp: Timestamp // thời gian Cloud Logging nhận được
  severity:     LogSeverity // DEFAULT, DEBUG, INFO, WARNING, ERROR, CRITICAL
  insertId:     string    // unique ID dùng cho deduplication
  httpRequest:  HttpRequest // (optional) HTTP request metadata
  labels:       map       // custom key-value labels
  operation:    LogEntryOperation // (optional) operation context
  trace:        string    // (optional) Cloud Trace ID
  spanId:       string    // (optional) trace span ID
  
  // Payload — một trong ba dạng
  textPayload:  string    // unstructured text
  jsonPayload:  Struct    // structured JSON
  protoPayload: Any       // protobuf (dùng cho audit logs)
}

resource.type là field quan trọng nhất cho routing và querying. Nó xác định loại resource tạo ra entry, và là field được index nhanh nhất trong Logs Explorer. Khi viết exclusion filter, luôn filter theo resource.type trước để tăng efficiency.

insertId được dùng cho server-side deduplication: nếu cùng một entry được gửi nhiều lần (do retry), Cloud Logging chỉ lưu một lần dựa trên insertId trong một khoảng thời gian ngắn (~24 giờ). Điều này quan trọng khi implement reliable log delivery — set insertId deterministically dựa trên nội dung entry.

tracespanId: Khi application propagate trace context theo W3C Trace Context standard hoặc OpenTelemetry, Cloud Logging tự động link log entries với Cloud Trace spans. Đây là cơ sở của "correlate logs across services" — một request trace ID cho phép tìm tất cả logs liên quan dù chúng đến từ 5 microservices khác nhau.


Structured Logging và Automatic Field Extraction

Cloud Logging không chỉ lưu raw JSON — nó tự động extract một số fields kỳ thực từ jsonPayload nếu chúng theo convention:

Field trong JSONCloud Logging xử lý
severityMap sang LogSeverity enum
message hoặc msgHiển thị làm summary text
time hoặc timestampOverride timestamp nếu hợp lệ
logging.googleapis.com/traceLink sang Cloud Trace
logging.googleapis.com/spanIdAssociate với trace span
logging.googleapis.com/labelsMerge vào entry labels
httpRequestParse thành HttpRequest object

Convention này quan trọng vì nó ảnh hưởng đến cách entry hiển thị trong Logs Explorer và cách severity-based filtering hoạt động. Một entry có jsonPayload.severity = "ERROR" nhưng không map vào LogEntry.severity sẽ hiển thị với severity DEFAULT — và các alerting policy filter theo severity sẽ không bắt được nó.


Giới Hạn và Constraints Kỹ Thuật

Tham sốGiá trị
Kích thước tối đa một log entry256 KB
Tốc độ ingestion (mặc định)60,000 entries/phút/project
Timestamp future tolerance+24 giờ
Timestamp past toleranceBị giới hạn bởi bucket retention
HTTP request API max batch1,000 entries/request
insertId deduplication window~24 giờ

Khi ứng dụng phải xử lý error storm và cần log nhiều entries trong thời gian ngắn, batch API calls là bắt buộc. Gọi entries.write với một array 1,000 entries hiệu quả hơn nhiều so với gọi 1,000 lần API với 1 entry mỗi lần — cả về quota lẫn latency.


Quan hệ giữa Log Types và Chi Phí

Không phải mọi log đều tính tiền theo cùng một cách:

Loại logIngestionStorage (>30 ngày)Ghi chú
Platform logs (hầu hết)Miễn phí$0.01/GB/thángBao gồm GKE, Cloud Run system logs
User-written logs$0.50/GB sau 50GB free$0.01/GB/tháng
Admin Activity Audit LogsMiễn phí, luôn luônMiễn phí trong _RequiredKhông tắt được
Data Access Audit Logs$0.50/GB sau 50GB free$0.01/GB/thángMặc định tắt, trừ BigQuery
System Event Audit LogsMiễn phíMiễn phí trong _RequiredKhông tắt được
Policy Denied Audit Logs$0.50/GB$0.01/GB/thángCó thể exclude
VPC Flow Logs$0.50/GB sau 50GB free$0.01/GB/thángVolume cao nhất, cần sampling

Theo Google Cloud Observability Pricing, free tier 50 GB/tháng áp dụng cho toàn bộ project tính gộp, không phải per-service. Một project có nhiều services đạt 50 GB nhanh hơn nhiều so với bạn nghĩ.


Anti-pattern: Không Dùng Structured Logging

Ghi log dạng plain text thay vì JSON structured là anti-pattern phổ biến nhất với hệ quả nhiều mặt:

Tại sao nó sai về mặt cơ chế: Cloud Logging index và query dựa trên fields. Khi log là unstructured text, Logs Explorer phải dùng textPayload =~ "ERROR" (regex match) thay vì jsonPayload.level = "ERROR" (exact match). Regex match chậm hơn nhiều, tốn compute hơn, và không thể tạo log-based metric từ specific fields.

Hệ quả ở scale: Một query tìm lỗi trên 30 ngày logs unstructured của 100 services mất nhiều phút và tốn tiền (Log Analytics SQL query được tính phí theo volume scanned). Cùng query trên structured logs chạy trong vài giây với filter hiệu quả.


References