Cloud Logging

Why This Topic Matters

Data engineering incidents usually begin as events, not as averages. A Cloud Run task exits with code 1, a scheduler trigger never reaches the worker, a Pub/Sub consumer starts retrying, or a VM login policy fails. Metrics tell you that a system moved out of range. Logs tell you which actor, method, resource, and payload caused the movement. In Google Cloud, Cloud Logging is also the security evidence layer because Cloud Audit Logs capture control-plane and, when enabled, data-plane access.

The archived project state already shows why this matters. The project had system buckets, system sinks, system views, a default log scope, active audit logs, and no user-defined log-based metrics or analytics links. That is a realistic production baseline: enough telemetry to investigate platform events, but not yet enough derived metrics or retention architecture to support long-horizon analytics on its own.

Conceptual Model

Cloud Logging separates ingest, storage, access, and export. That separation is the reason you can keep the same incoming log flow while changing retention, access boundaries, or downstream destinations.


flowchart LR
    A["GCP services and apps<br>Cloud Run, GCE, IAM, Pub/Sub, BigQuery"] --> B["Log Router"]
    B --> C["_Required bucket<br>400 days<br>locked"]
    B --> D["_Default bucket<br>30 days<br>configurable"]
    D --> E["_Default view<br>excludes Data Access"]
    D --> F["_AllLogs view<br>full bucket read"]
    B --> G["User-defined sinks<br>BigQuery, GCS, Pub/Sub"]
    B --> H["Log-based metrics"]
    H --> I["Cloud Monitoring charts and alerts"]
    D --> J["Linked dataset / Log Analytics"]

Cloud Logging | archived project summary

The archived demo project used only the default storage and routing objects. There were no user-created sinks, no linked datasets, and no user-defined log-based metrics in the captured estate.

ObjectArchived state in removed projectOperational meaning
_Default bucketglobal, retentionDays: 30, ACTIVEMain non-required storage bucket
_Required bucketglobal, retentionDays: 400, locked: true, ACTIVEAudit and required system logging bucket
_Default sinkRoutes non-required logs to _DefaultBaseline project routing
_Required sinkRoutes required audit/system logs to _RequiredBaseline compliance/security routing
_Default viewExcludes cloudaudit.googleapis.com/data_accessReader-friendly default view, not full bucket access
_AllLogs viewNo filterFull bucket read lens
_Default log scopeprojects/bq-wh-nb onlyNo cross-project aggregation yet
Linked datasets on _Default[]Log Analytics not configured on this bucket
User-defined log-based metrics[]No log-to-metric bridge objects yet

Important conceptual note not safely executed here

The archived project did not contain user-defined buckets, exclusions, sinks, log-based metrics, analytics links, or custom views. Creating them would have mutated the live production-style environment and could have affected retention, cost, access, or downstream delivery. This note therefore distinguishes between:

  • historically captured inspection workflows for the objects that existed
  • production guidance for objects that were important to explain but not safe to create here

PowerShell / Linux

This section uses gcloud because the command syntax is the same on Windows PowerShell and Linux shells for the workflows shown here.

PowerShell / Linux | gcloud logging | inspect buckets, views, sinks, and scopes

Use these commands before you change retention, IAM, routing, or analytics posture. They show the storage objects that already exist, the filters that govern default read access, and whether the project has any extra routing or analytics surface beyond the Google-managed defaults.

Inspect the _Default bucket

Before changing retention or explaining why logs disappear after a fixed number of days. It is typically triggered by the reader needs to know where ordinary application and platform logs are stored. Run in a shell with project-level Logging read access. Read-only. Confirm the bucket name, location, lifecycle state, and retention policy for the main project bucket.

FieldTypeMeaning
namestringFully qualified bucket resource name
descriptionstringHuman-friendly purpose of the bucket
lifecycleStateenumCurrent bucket state such as ACTIVE
retentionDaysintegerNumber of days Cloud Logging retains entries in the bucket

Describe the project’s default log bucket and its retention policy.

gcloud logging buckets describe _Default --location=global --format=json
{
  "description": "Default bucket",
  "lifecycleState": "ACTIVE",
  "name": "projects/bq-wh-nb/locations/global/buckets/_Default",
  "retentionDays": 30
}

This confirms the expected default retention posture: ordinary logs stay in _Default for 30 days unless you change the bucket retention or route matching logs elsewhere. The bucket lives in the global location, which matters for data residency and for any future linked dataset or cross-region query design.

Inspect the _Required bucket

Before discussing audit retention, security evidence, or immutable default routing. It is typically triggered by the reader needs to know where Google-required logs are stored and why that bucket behaves differently. Run in a shell with project-level Logging read access. Read-only. Verify the fixed audit bucket attributes that are not controlled like _Default.

FieldTypeMeaning
namestringFully qualified bucket resource name
descriptionstringBucket role in the project
lifecycleStateenumCurrent bucket state
lockedbooleanWhether retention configuration is locked against updates
retentionDaysintegerRequired retention period for stored entries

Describe the Google-managed required bucket that stores audit and other mandatory logs.

gcloud logging buckets describe _Required --location=global --format=json
{
  "description": "Audit bucket",
  "lifecycleState": "ACTIVE",
  "locked": true,
  "name": "projects/bq-wh-nb/locations/global/buckets/_Required",
  "retentionDays": 400
}

The locked: true field is the operational difference that matters most. _Required is not a general-purpose archive bucket. It is a Google-managed bucket for required audit/system logs, and the 400-day retention is fixed.

Inspect default routing

Before diagnosing missing logs, planning export paths, or teaching the difference between buckets and sinks. It is typically triggered by A reader sees logs in buckets and assumes that storage and routing are the same thing. Run in a shell with project-level Logging read access. Read-only. Show the actual router filters that split required versus non-required log traffic.

FieldTypeMeaning
namestringSink identifier
destinationstringBucket or external target receiving matching entries
filterstringLogging query filter used by the sink
resourceNamestringFull sink resource path

Describe the system sink that routes non-required traffic to _Default.

gcloud logging sinks describe _Default --format=json
{
  "destination": "logging.googleapis.com/projects/bq-wh-nb/locations/global/buckets/_Default",
  "filter": "NOT LOG_ID(\"cloudaudit.googleapis.com/activity\") AND NOT LOG_ID(\"externalaudit.googleapis.com/activity\") AND NOT LOG_ID(\"cloudaudit.googleapis.com/system_event\") AND NOT LOG_ID(\"externalaudit.googleapis.com/system_event\") AND NOT LOG_ID(\"cloudaudit.googleapis.com/access_transparency\") AND NOT LOG_ID(\"externalaudit.googleapis.com/access_transparency\")",
  "name": "_Default",
  "resourceName": "projects/bq-wh-nb/sinks/_Default"
}

Describe the system sink that routes required traffic to _Required.

gcloud logging sinks describe _Required --format=json
{
  "destination": "logging.googleapis.com/projects/bq-wh-nb/locations/global/buckets/_Required",
  "filter": "LOG_ID(\"cloudaudit.googleapis.com/activity\") OR LOG_ID(\"externalaudit.googleapis.com/activity\") OR LOG_ID(\"cloudaudit.googleapis.com/system_event\") OR LOG_ID(\"externalaudit.googleapis.com/system_event\") OR LOG_ID(\"cloudaudit.googleapis.com/access_transparency\") OR LOG_ID(\"externalaudit.googleapis.com/access_transparency\")",
  "name": "_Required",
  "resourceName": "projects/bq-wh-nb/sinks/_Required"
}

These two sink definitions are the cleanest live proof that the Log Router is policy-driven. They also explain why not every audit log appears in _Default. Routing happens before you query.

Before troubleshooting access gaps, explaining why one reader sees fewer logs than another, or evaluating whether Log Analytics is already enabled. It is typically triggered by A query result seems incomplete even though the bucket clearly stores the data. Run in a shell with project-level Logging read access. Read-only. Distinguish bucket contents from view filters, log scopes, and linked datasets.

FieldTypeMeaning
VIEW_IDstringView name inside the bucket
DESCRIPTIONstringPurpose of the view
FILTERstringLogging query that restricts visibility in the view
resourceNamesarrayResources aggregated by the log scope

List the default views on the _Default bucket.

gcloud logging views list --bucket=_Default --location=global --format="table(name,description,filter)"
VIEW_ID   DESCRIPTION                                 FILTER
_AllLogs  Access to all logs
_Default  Access to all logs except data access logs  NOT LOG_ID("cloudaudit.googleapis.com/data_access") AND NOT LOG_ID("externalaudit.googleapis.com/data_access")

Describe the automatically created project log scope.

gcloud logging scopes describe _Default --project=bq-wh-nb --format=json
{
  "name": "projects/bq-wh-nb/locations/global/logScopes/_Default",
  "resourceNames": [
    "projects/bq-wh-nb"
  ]
}

List linked datasets on _Default to see whether Log Analytics is already configured.

gcloud logging links list --bucket=_Default --location=global --format=json
[]

The _Default view result is the key access-control fact: a reader who only has access to that default view will not see Data Access audit logs. The scope output shows that this project is not aggregating logs from other projects or custom views. The empty links list shows that _Default was not linked to a BigQuery dataset for Log Analytics in the captured state.

Current product note: Observability Analytics

Current Cloud Logging documentation frames the bucket-side SQL upgrade path as Observability Analytics. When a bucket is upgraded, the analytics setting is irreversible, and analytics views become part of the SQL/query access layer on top of that upgraded bucket.

FlagSyntaxDescription
--location--location=globalSpecifies the bucket or scope location
--format--format=jsonChooses JSON or table output for inspection
--bucket--bucket=_DefaultIdentifies which bucket owns the view or link
--project--project=bq-wh-nbTargets a specific project when the default config is not sufficient

PowerShell / Linux | gcloud logging | read real log entries

Use gcloud logging read for incident triage, audit review, and payload inspection. The core skill is not memorizing one filter. It is knowing which LogEntry fields narrow the search fastest and which payload type you expect to find.

Read recent audit logs in table form

At the start of a security review or when you need a fast audit timeline. It is typically triggered by you know the event class is audit-related but not yet the exact method or resource. Run in a shell with roles/logging.viewer or roles/logging.privateLogViewer, depending on whether Data Access entries must be visible. Read-only. Surface the actor, service, method, and timestamp of recent audit events without reading full JSON first.

ColumnSource fieldMeaning
TIMESTAMPtimestampWhen the event occurred
LOG_NAMElogNameWhich audit stream contains the event
TYPEresource.typeMonitored resource classification
SEVERITYseverityLog importance value
SERVICE_NAMEprotoPayload.serviceNameGoogle API or service that emitted the audit log
METHOD_NAMEprotoPayload.methodNameAPI method or action that occurred
PRINCIPAL_EMAILprotoPayload.authenticationInfo.principalEmailIdentity that performed or requested the operation

Query the most recent audit events and render only the fields needed for a fast timeline.

gcloud logging read 'logName:"cloudaudit.googleapis.com"' --limit=5 --freshness=30d --format="table(timestamp,logName,resource.type,severity,protoPayload.serviceName,protoPayload.methodName,protoPayload.authenticationInfo.principalEmail)"
TIMESTAMP                       LOG_NAME                                                        TYPE              SEVERITY  SERVICE_NAME            METHOD_NAME                                                         PRINCIPAL_EMAIL
2026-04-13T13:42:32.855240774Z  projects/bq-wh-nb/logs/cloudaudit.googleapis.com%2Factivity     audited_resource  NOTICE    iam.googleapis.com      iam.serviceAccounts.actAs                                           alexper.recovery@gmail.com
2026-04-13T13:42:32.122132Z     projects/bq-wh-nb/logs/cloudaudit.googleapis.com%2Fdata_access  audited_resource  INFO      oslogin.googleapis.com  google.cloud.oslogin.dataplane.OsLoginDataPlaneService.CheckPolicy  alexper.recovery@gmail.com
2026-04-13T13:42:32.087148099Z  projects/bq-wh-nb/logs/cloudaudit.googleapis.com%2Factivity     audited_resource  NOTICE    iam.googleapis.com      iam.serviceAccounts.actAs                                           alexper.recovery@gmail.com
2026-04-13T13:42:32.082874Z     projects/bq-wh-nb/logs/cloudaudit.googleapis.com%2Fdata_access  audited_resource  INFO      oslogin.googleapis.com  google.cloud.oslogin.dataplane.OsLoginDataPlaneService.CheckPolicy  alexper.recovery@gmail.com
2026-04-13T13:42:32.008244Z     projects/bq-wh-nb/logs/cloudaudit.googleapis.com%2Fdata_access  audited_resource  INFO      oslogin.googleapis.com  google.cloud.oslogin.dataplane.OsLoginDataPlaneService.CheckPolicy  alexper.recovery@gmail.com

This output shows both control-plane and data-access activity in the same investigation window. iam.serviceAccounts.actAs explains control-plane impersonation checks, while the OS Login CheckPolicy method explains instance login authorization checks. Both events belong to audited_resource, which is why resource.type is less specific here than the service and method fields.

Inspect a full protoPayload audit entry

After the table view tells you which service and method matter. It is typically triggered by you need request or authorization detail, not only the high-level timeline. Same permissions as the previous command. Read-only. Read the nested AuditLog object stored in protoPayload.

FieldTypeMeaning
protoPayload.@typestringDeclares the protobuf-backed payload type
authenticationInfo.principalEmailstringCaller identity
authorizationInfoarrayPermissions evaluated during the operation
methodNamestringAPI method invoked
resourceNamestringFully qualified resource being acted on
serviceNamestringService that generated the audit record

Read one audit log entry as full JSON to inspect the protobuf payload directly.

gcloud logging read 'logName:"cloudaudit.googleapis.com"' --limit=1 --freshness=30d --format=json
[
  {
    "insertId": "1xdq4ulf2av22d",
    "logName": "projects/bq-wh-nb/logs/cloudaudit.googleapis.com%2Factivity",
    "protoPayload": {
      "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
      "authenticationInfo": {
        "principalEmail": "alexper.recovery@gmail.com"
      },
      "authorizationInfo": [
        {
          "granted": true,
          "permission": "iam.serviceAccounts.actAs",
          "permissionType": "ADMIN_WRITE",
          "resource": "projects/-/serviceAccounts/bq-wh-sa@bq-wh-nb.iam.gserviceaccount.com"
        }
      ],
      "methodName": "iam.serviceAccounts.actAs",
      "request": {
        "@type": "type.googleapis.com/CanActAsServiceAccountRequest",
        "name": "bq-wh-sa@bq-wh-nb.iam.gserviceaccount.com"
      },
      "resourceName": "projects/-/serviceAccounts/bq-wh-sa@bq-wh-nb.iam.gserviceaccount.com",
      "response": {
        "@type": "type.googleapis.com/CanActAsServiceAccountResponse",
        "success": true
      },
      "serviceName": "iam.googleapis.com"
    },
    "receiveTimestamp": "2026-04-13T13:42:02.180888995Z",
    "resource": {
      "labels": {
        "method": "iam.serviceAccounts.actAs",
        "project_id": "bq-wh-nb",
        "service": "iam.googleapis.com"
      },
      "type": "audited_resource"
    },
    "severity": "NOTICE",
    "timestamp": "2026-04-13T13:42:02.180888995Z"
  }
]

This entry is the concrete example of why audit logs use protoPayload. The event is more than a message string. It has a typed request, a typed response, and explicit authorization facts.

Read an archived textPayload entry

When you need to verify unstructured application or ad hoc shell logging. It is typically triggered by you know the log name and only need the message text and severity. Read-only. The log was intentionally written during this refactor for verification. Show what an unstructured custom log entry looks like in Cloud Logging.

ColumnSource fieldMeaning
TIMESTAMPtimestampWhen Logging accepted the entry
SEVERITYseveritySeverity chosen at write time
TYPEresource.typeResource type associated with the entry
TEXT_PAYLOADtextPayloadHuman-readable message body

Read the verification log entry that was written as plain text.

gcloud logging read 'logName="projects/bq-wh-nb/logs/codex-cloud-logging-text"' --limit=5 --freshness=1d --format="table(timestamp,severity,resource.type,textPayload)"
TIMESTAMP                       SEVERITY  TYPE    TEXT_PAYLOAD
2026-04-13T13:42:20.635565815Z  NOTICE    global  Codex verification text entry 2026-04-13T14:44:00Z

This is the simplest LogEntry payload shape. It is useful for quick operator messages, but not ideal when you later need to chart or alert on extracted fields.

Read an archived jsonPayload entry

When you need structured application telemetry. It is typically triggered by the investigation requires field-level filtering, grouping, or future metric extraction. Read-only. The log was intentionally written during this refactor for verification. Show a structured custom entry that can be filtered by JSON path.

ColumnSource fieldMeaning
TIMESTAMPtimestampWhen the entry was accepted
SEVERITYseverityChosen write severity
TYPEresource.typeResource type
WORKFLOWjsonPayload.workflowStructured event category
NOTEjsonPayload.noteSource note or producer identifier
PROJECTjsonPayload.projectProject echoed into the payload

Read the verification log entry that was written as JSON.

gcloud logging read 'logName="projects/bq-wh-nb/logs/codex-cloud-logging-json"' --limit=5 --freshness=1d --format="table(timestamp,severity,resource.type,jsonPayload.workflow,jsonPayload.note,jsonPayload.project)"
TIMESTAMP                       SEVERITY  TYPE    WORKFLOW        NOTE              PROJECT
2026-04-13T13:42:20.626347780Z  WARNING   global  vault-refactor  01-cloud-logging  bq-wh-nb

This is the payload style to prefer for pipelines and services. Each JSON key is queryable, so you can later build precise sinks, dashboards, or log-based metrics without parsing free text.

FlagSyntaxDescription
--limit--limit=5Caps the number of entries returned
--freshness--freshness=30dRestricts results to recent time only
--format--format="table(...)"Renders selected fields instead of full JSON
--order--order=ascChanges result ordering from default newest-first
--project--project=bq-wh-nbOverrides the target project if needed

PowerShell / Linux | gcloud logging | write verification entries

Use gcloud logging write when a shell script, break-glass runbook, or one-off operational check must emit an event directly into Logging without a client library.

Write a text log entry

During controlled verification of routing or to leave a shell-origin event marker. It is typically triggered by you need a human-readable log entry immediately from the CLI. State-changing. Writes one new log entry into the target project. Confirm that the project accepts direct CLI log writes and that the chosen log name becomes queryable.

ArgumentMeaning
codex-cloud-logging-textDestination log ID
message stringtextPayload value
--severity=NOTICESets the log severity

Write a plain-text verification event into a dedicated custom log.

gcloud logging write codex-cloud-logging-text "Codex verification text entry 2026-04-13T14:44:00Z" --severity=NOTICE
Created log entry.

The command output is intentionally minimal. Success means the event was accepted by the Logging API, not that a downstream sink or alert has already processed it.

Write a JSON log entry

When you need a structured event from a shell context. It is typically triggered by the downstream consumer needs stable keys instead of message parsing. State-changing. Writes one new JSON log entry into the target project. Demonstrate how gcloud logging write can produce jsonPayload.

ArgumentMeaning
codex-cloud-logging-jsonDestination log ID
JSON objectStructured payload stored in jsonPayload
--severity=WARNINGSets the log severity
--payload-type=jsonTells gcloud not to treat the payload as text

Write a structured verification event into a dedicated custom log.

gcloud logging write codex-cloud-logging-json '{"workflow":"vault-refactor","note":"01-cloud-logging","verifiedAt":"2026-04-13T14:44:00Z","project":"bq-wh-nb"}' --severity=WARNING --payload-type=json
Created log entry.

This is the safest CLI pattern when you know the event will later feed dashboards, metrics, or automated triage. Structured fields age better than free-form text.

FlagSyntaxDescription
--severity--severity=WARNINGSets the severity field on the written entry
--payload-type--payload-type=jsonChooses text versus JSON payload handling
--project--project=bq-wh-nbSends the write to a specific project

PowerShell / Linux | gcloud logging | live tailing in this SDK

Historically, many Cloud Logging guides present gcloud logging tail as a stable command. That is not true in this environment.

Verify the stable command surface

Before copying a tail command from older documentation into an operator runbook. It is typically triggered by A guide claims that gcloud logging tail is available on the stable surface. Read-only. This command intentionally checks CLI behavior. Confirm whether live tailing is a stable command in the installed Cloud SDK.

Ask the stable CLI to run tail and capture the current behavior.

gcloud logging tail 'logName="projects/bq-wh-nb/logs/codex-cloud-logging-tail-2"' --buffer-window=1s --format=json
ERROR: (gcloud.logging) Invalid choice: 'tail'.
This command is available in one or more alternate release tracks.  Try:
  gcloud alpha logging tail
  gcloud beta logging tail

This is a live correction to the older note. In this SDK build, stable gcloud logging supports read and write, but not stable tail.

Verify the alpha tail surface

When you need to confirm whether streaming exists at all in the installed SDK. It is typically triggered by the stable surface rejected tail. Read-only with respect to the tail command itself, but the session below was paired with a deliberate verification write. The streaming capture was attempted under non-interactive automation. Confirm that the alpha surface exists and starts a tail session, while documenting the automation limitation honestly.

Start the alpha tail command in the current environment.

gcloud alpha logging tail 'logName="projects/bq-wh-nb/logs/codex-cloud-logging-tail-5"' --buffer-window=1s --format='value(timestamp,severity,textPayload)'
C:\Users\aperi\AppData\Local\Google\Cloud SDK\google-cloud-sdk\lib\third_party\google\cloud\__init__.py:20: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  import pkg_resources
Initializing tail session.

The alpha command exists and starts a live session, but non-interactive capture in this environment did not flush streamed entries before forced termination. That is why this note uses read as the canonical reproducible workflow and treats alpha tail as a verified but automation-sensitive tool.

FlagSyntaxDescription
--buffer-window--buffer-window=1sBuffers entries briefly to improve ordering
--format--format=jsonControls how streamed entries render

PowerShell / Linux | gcloud logging | check the log-to-metric bridge

Log-based metrics are the narrow bridge between event streams and alertable numeric time series. They are useful when a recurring log pattern is too important to keep only in raw logs but does not already exist as a native metric.

Inspect the current log-based metric inventory

Before designing a new alert or dashboard from logs. It is typically triggered by you need to know whether the project already derives metrics from logs. Run in a shell with Logging read access. Read-only. Show whether user-defined log-based metrics already exist in the archived project.

FieldTypeMeaning
result arrayarrayAll user-defined and system-visible log metrics returned by the command
[]empty arrayNo user-defined log-based metrics exist in the project

List log-based metrics in the archived project.

gcloud logging metrics list --format=json
[]

The archived project had no user-defined log-based metrics. That means no existing log pattern had yet been promoted into a chartable or alertable Cloud Monitoring series.

Current product note: log-based metric behavior

Log-based metrics are still not retroactive. System-defined metrics are generated from logs that are stored in the bucket, while user-defined log-based metrics can count matching entries even when those entries are excluded from bucket storage. User-defined metrics can also be bucket-scoped, which matters when teams separate retention, access, and analytics by bucket.

Do not create log-based metrics by reflex

A log-based metric is operational state, not a saved search. Every additional metric adds cardinality, alert design pressure, and potential cost.

Create a log-based metric only when the event pattern is recurrent

Good candidates are repeated pipeline failure signatures, dead-letter counts, retry storms, or bounded error families that need dashboards or alerts. Ad hoc forensics should stay in raw logs.

Warnings And Anti-Patterns

These are the failure modes that most often turn a working logging setup into an expensive, misleading, or incomplete one.

Do not treat _Default as an audit archive

_Default in this project retains logs for 30 days. That is enough for operational triage, not for long-horizon compliance or forensics.

Use retention and routing intentionally

If you need longer retention, change _Default deliberately or route selected logs to a custom bucket, a linked analytics dataset, or a dedicated archive destination.

Do not assume roles/logging.viewer exposes Data Access audit logs

The _Default view excludes Data Access audit logs, and Data Access visibility often requires roles/logging.privateLogViewer.

Validate the read boundary before declaring logs "missing"

First verify the bucket, then the view filter, then the IAM role, and only then the service configuration.

Do not create high-cardinality log-based metric labels

Labels extracted from values like full timestamps, UUIDs, or insertId can explode time-series count and cost.

Extract only the dimensions you will actually aggregate by

Safe examples are environment, pipeline name, result class, resource zone, or a bounded error code family.

Recommendations And Production Rules

These rules convert the live findings above into repeatable production behavior.

Use structured application logs whenever you control the emitter. jsonPayload gives you safer filtering, cleaner exports, and a better path to derived metrics than textPayload.

Keep security and analytics concerns separate. _Required is for required logs, _Default is for operational retention, custom buckets are for deliberate retention boundaries, and sinks are for exporting to systems with different performance or compliance needs.

Export design should match the question you are trying to answer:

  • Use BigQuery or Log Analytics when the problem is set-based analysis over long time windows.
  • Use GCS when the requirement is cheap archival of raw log objects.
  • Use Pub/Sub when the requirement is near-real-time downstream reaction.

Prefer log-based metrics only when the event matters repeatedly enough to deserve charting or alerting. A one-off investigation belongs in raw logs. A recurrent failure signature belongs in a metric.

Data-Engineering Scenarios

These scenarios show how to apply Cloud Logging during common platform and pipeline investigations.

Pipeline failed and I need the root cause fast

Start with a narrow read query, not with an all-logs scan. Filter on resource.type, severity, and the relevant log or audit stream first. If the failure involves identity, configuration drift, or access denial, inspect audit logs immediately because protoPayload.methodName, resourceName, and principalEmail usually shorten the investigation faster than application logs alone.

Need long-term retention and SQL analysis

If the main question is trend analysis, cost attribution, or large-window correlation across many services, raw log browsing becomes the wrong tool. In that case:

  1. Retain the operational subset in _Default.
  2. Route the analytic subset to a custom bucket or external destination.
  3. Use a linked dataset or BigQuery sink for SQL access.

In the archived project, gcloud logging links list --bucket=_Default --location=global --format=json returned [], so that analytics path was not configured in the captured state.

Need compliance or audit evidence

Use audit log filters, not general free-text searches. The live audit output in this project already shows IAM impersonation and OS Login policy checks. For evidence collection, preserve the exact logName, methodName, resourceName, principalEmail, and timestamps.

Troubleshooting And Runbooks

These runbooks focus on the most common reasons a Logging workflow appears broken even when the platform is behaving as designed.

Logs are missing

Check these layers in order:

  1. Confirm the service is writing logs at all.
  2. Confirm the log lands in the expected bucket.
  3. Confirm the view you are querying does not exclude that log class.
  4. Confirm your IAM role exposes the needed bucket or Data Access logs.
  5. Confirm no sink or exclusion pattern intentionally removed the event from local storage.

The most common false positive in this project would be querying through the _Default view and expecting to see Data Access audit logs that the view intentionally hides.

Sink exists but destination is empty

Verify the sink filter first, then the sink destination, then the destination IAM binding for the Logging service account. A created sink with no destination permissions is structurally valid but operationally ineffective.

Too many logs or noisy logs

Reduce noise at the source first. If a service emits repetitive INFO or DEBUG logs that nobody reads, tune the service logging policy before you add bucket-level exclusions. Exclusions are useful, but they permanently change what is stored.

Audit logs are inaccessible

Determine whether the gap is configuration or permissions:

  1. If Admin Activity is missing, suspect query scope or IAM first, because those logs are always written.
  2. If Data Access is missing, verify whether the service writes Data Access logs by default and whether your role includes roles/logging.privateLogViewer.
  3. If the event should be in _Default, verify whether you are reading the bucket or only the _Default view.

Quick Reference

Use this table when you already know the question and only need the fastest verified command path.

NeedFastest live workflow
Check ordinary retentiongcloud logging buckets describe _Default --location=global --format=json
Check audit retentiongcloud logging buckets describe _Required --location=global --format=json
See default routinggcloud logging sinks describe _Default --format=json and _Required
Verify view boundariesgcloud logging views list --bucket=_Default --location=global --format="table(name,description,filter)"
Read audit timelinegcloud logging read 'logName:"cloudaudit.googleapis.com"' --limit=5 --freshness=30d --format="table(...)"
Verify custom log writegcloud logging write ... followed by gcloud logging read 'logName="projects/bq-wh-nb/logs/..."'
Check log-based metrics inventorygcloud logging metrics list --format=json
Check analytics linksgcloud logging links list --bucket=_Default --location=global --format=json

These notes extend the same observability workflow into metrics, service-specific debugging, and downstream analytics.

Cloud Logging References

These official references were used to verify retention behavior, audit log structure, metrics bridging, and cost guidance.