Cloud Logging from Cloud Shell: write a log entry, then find it again with a filter
Every Google Cloud project already has a logbook. Learn where entries go, write a few of your own, search them by severity and JSON field, then delete the practice log so nothing is left behind.
Cloud Logging, in plain words
Cloud Logging is the place where Google Cloud keeps the running diary of your project: messages your apps print, requests that hit a load balancer, and audit records of who changed what. It is on by default, so a brand-new project already collects entries. Each log entry has a timestamp, a severity (from DEBUG up to EMERGENCY), the resource it came from, and a payload that is either plain text (textPayload) or structured JSON (jsonPayload).
Entries do not just land in one pile. A Log Router in every project passes them through sinks. The _Required sink sends key audit logs, such as Admin Activity, to the _Required bucket, which keeps them for 400 days and cannot be changed or deleted. The _Default sink sends almost everything else to the _Default bucket, kept for 30 days by default. You can edit the _Default sink, add exclusion filters to drop noisy entries, or add your own sinks that copy logs to BigQuery, Cloud Storage or Pub/Sub.
To read logs you use the Logs Explorer in the console or gcloud logging read in a terminal. Both speak the same Logging query language: severity>=WARNING, jsonPayload.user="ana", or log_id("my-app"). Writing logs into storage costs $0.50 per GiB after the first 50 GiB per project each month, which includes 30 days of storage, and querying is free, so a small lab like this one costs nothing. Recent news: the September 28, 2026 release notes say the legacy Logging agent has reached end of support (the Ops Agent replaces it) and that only platform services can now write entries to billing accounts.
Reach for it when
- An app on Cloud Run, GKE or Compute Engine misbehaves and you need to see what it printed in the minutes before the error, filtered to
severity>=ERROR. - You need to answer who deleted a VM or changed an IAM policy last week, which the Admin Activity audit logs in the
_Requiredbucket already record. - You want to send a copy of certain logs to BigQuery for long-term analysis or to Pub/Sub so another system can react to them, using a Log Router sink.
Skip it when
- You need numbers over time, such as request latency or CPU use, with charts and alerts; that is Cloud Monitoring's job (a log-based metric can bridge the two, but it is billed as a Monitoring custom metric).
- You want to follow one request as it hops across many services; Cloud Trace shows that path far better than reading log lines side by side.
- You plan to dump very chatty debug output from busy services forever; past the free 50 GiB per month every GiB is billed, so add exclusion filters or log less first.
The AI angle
Logs and AI meet in two ways. In the Logs Explorer you can select an entry and click Investigate log to have Gemini Cloud Assist summarize it in plain words; it sees only that entry's text, needs Cloud Assist set up first, and Google warns the summary can be wrong, so check it. Going the other way, AI workloads such as Gemini Enterprise Agent Platform (formerly Vertex AI) endpoints and agents write their own logs here, and writing your app's prompts, model IDs and latencies as jsonPayload fields makes them easy to filter and to route into BigQuery for evaluation.
Hands-on lab: Write, search and delete your own practice log
Write text and JSON log entries with different severities from Cloud Shell, find them with three kinds of filter, look at them in the Logs Explorer, then delete the practice log.
Before you start
- A sandbox Google Cloud project you own (shown here as YOUR_PROJECT_ID) with billing linked.
- Cloud Shell, or any terminal with the gcloud CLI signed in as a user who can write, read and delete logs (the Logs Writer, Logs Viewer and Logging Admin roles; a project Owner has all three).
- Optional: Gemini Cloud Assist set up for your account if you want to try the Investigate log button.
Point gcloud at your sandbox project
Open Cloud Shell, set the project and pick a name for the practice log. The Cloud Logging API is normally on already; enabling it again does no harm.
gcloud config set project YOUR_PROJECT_ID export LOG_ID="sandbox-lab-log" gcloud services enable logging.googleapis.comWrite three entries
Write one plain text entry, one warning and one structured JSON entry. With no extra flags,
gcloud logging writeuses theglobalresource type and severityDEFAULT;--payload-type=jsonstores the message asjsonPayloadso each key becomes a searchable field.gcloud logging write "$LOG_ID" "Hello from the sandbox lab" gcloud logging write "$LOG_ID" "Disk is almost full" --severity=WARNING gcloud logging write "$LOG_ID" '{"user": "ana", "action": "checkout", "ms": 840}' --payload-type=json --severity=ERRORRead the log back
log_id()takes the plain log name, so you do not have to URL-encode anything. Newest entries come first by default, and--freshnesslimits the search to the last hour. If nothing shows, wait a few seconds and run it again.gcloud logging read "log_id(\"$LOG_ID\")" --freshness=1h --limit=10 \ --format="table(timestamp, severity, textPayload, jsonPayload.user)"Filter by severity and by a JSON field
The first query keeps only entries at WARNING or worse, so the hello message disappears. The second reaches inside the JSON payload. Field names inside
jsonPayloadare case-sensitive;ANDmust be upper case.gcloud logging read "log_id(\"$LOG_ID\") AND severity>=WARNING" --freshness=1h \ --format="table(timestamp, severity)" gcloud logging read "log_id(\"$LOG_ID\") AND jsonPayload.user=\"ana\"" --freshness=1h \ --format=jsonSee the same entries in the Logs Explorer
In the console, open Logging > Logs Explorer, paste
log_id("sandbox-lab-log")into the query box and run it. Expand the ERROR entry to see itsjsonPayloadfields. If Gemini Cloud Assist is set up, click Investigate log to get a plain-language summary, and treat it as a hint, not a fact. Also rungcloud logging logs listto see your log next to the ones Google Cloud wrote for you.gcloud logging logs list --limit=20
Check that it worked
The first read shows three entries; the severity filter shows two (WARNING and ERROR); the JSON filter returns one entry whose jsonPayload has user "ana", action "checkout" and ms 840.
Clean up
The lab created only log entries in your practice log. Delete them (this removes every entry in that one log from the _Default bucket and asks for confirmation unless you pass --quiet), then confirm the log is gone. Do not delete any other log. Leave the Cloud Logging API enabled: Google Cloud itself writes logs through it. If you made a project just for this lab, you can delete the whole project instead.
gcloud logging logs delete "$LOG_ID" --quiet
# Confirm: no line should mention sandbox-lab-log, and the read should return nothing
gcloud logging logs list | grep "$LOG_ID" || echo "Practice log is gone"
gcloud logging read "log_id(\"$LOG_ID\")" --freshness=1h --limit=1
unset LOG_IDGotchas
gcloud logging logs deleteclears the log only in the_Defaultbucket and needs the Logging Admin role. It does not touch copies a sink already sent to BigQuery or Cloud Storage, or Error Reporting samples.- When you filter on
logNameyou must URL-encode slashes in the log ID (%2F);log_id("...")takes the plain name and avoids the problem. gcloud logging readonly looks back one day by default (--freshness=1d) and has no default limit, so add--limitand a time window before querying a busy project.- Exclusion filters stop entries from being stored and billed, but the entries still count against the
entries.writeAPI quota because exclusion happens after Logging receives them. - The
_Defaultbucket keeps entries for 30 days. Raising retention costs $0.01 per GiB per month for anything kept beyond 30 days; the_Requiredbucket's 400 days are free and cannot be changed.