Loading...
Loading...
Configure and troubleshoot Google Cloud cross-project centralized logging and read-time aggregation. Use when: - Setting up log routing from multiple projects/folders/organizations to a central log bucket. - Creating cross-project log sinks and configuring central log buckets. - Troubleshooting cross-project routing. Don't use for single-project basic configurations.
npx skill4agent add google/skills cloud-logging-cross-project-configurationgcloud[!IMPORTANT] Sandbox Network Limitation (CRITICAL for Agent Testing): During evaluation or in restricted sandboxed environments, network traffic to GCP APIs is blocked. Do NOT run network discovery commands to find resource names, project IDs, or organization IDs. Always use the exact project IDs or placeholders provided in the user prompt or instructions, for example,,{project_id},{source_project_id}. Assume these resources exist and proceed directly with configuration commands. Running these discovery commands will cause the execution to hang and timeout.{central_project_id}
gcloud logging readgcloud logging buckets listgcloud logging views creategcloud logging views updategcloud logging scopes creategcloud logging buckets creategcloud logging metrics creategcloud logging links creategcloud projects add-iam-policy-bindinggcloud logging buckets deletegcloud logging sinks update --add-exclusion| Criterion | Centralized Storage | Read-Time Aggregation |
|---|---|---|
| GCP Project Scale | Scales to thousands of | Best for < 375 projects. |
| : : projects. : : | ||
| Log Storage | Consolidated in a single | Resides in originating |
| : : log bucket. : resources. : | ||
| SQL Analytics | Easy; unified querying | Hard; requires querying |
| : : via Observability : multiple log buckets. : | ||
| : : Analytics. : : | ||
| Access Control | Scoped access via log | Requires IAM access to |
| : : views on the centralized : all views on resources : | ||
| : : log bucket. : that store log data. : | ||
| Configuration | Options vary based on | Will not interfere with |
| : Complexity : Project, Folder, : bucket-based log-based : | ||
| : : Organization structure. : metrics. : | ||
| Cost | Potential for duplicate | Cost-effective; no data |
| : : storage of log buckets : replication. : | ||
| : : if exclusions aren't : : | ||
| : : set. : : |
graph LR
subgraph "Source Project(s)"
Log[Resource Logs] --> Sink["Sink: route-to-central-project"]
end
subgraph "Central Project"
Sink --> Bucket["Bucket: central-logs-bucket (us-central1)"]
endgraph LR
subgraph "Source Project 1"
Log1[Resource Logs] --> Bucket1["Bucket: _Default"]
end
subgraph "Source Project 2"
Log2[Resource Logs] --> Bucket2["Bucket: _Default"]
end
subgraph "Scoping Project (No Log Storage)"
Scope["Log scope: central-query-scope"]
Scope -.-> View1["_AllLogs View on Bucket1"]
Scope -.-> View2["_AllLogs View on Bucket2"]
end[Tip] Use regional log buckets, for example, set the location to. Don't use theus-central1location. This approach ensures compatibility with Observability Analytics and SQL querying.global
gcloud logging buckets create {bucket_id} \
--project={central_project_id} \
--location={region} \
--retention-days={retention_days} \
--enable-analyticsgcloud logging sinks create {sink_name} \
logging.googleapis.com/projects/{central_project_id}/locations/{region}/buckets/{bucket_id} \
--project={central_project_id}--log-filtergcloud logging sinks create {sink_name} \
logging.googleapis.com/projects/{central_project_id} \
--organization={source_organization_id} \
--include-children \
--exclusion=filter='LOG_ID("cloudaudit.googleapis.com/activity")' \
--exclusion=filter='LOG_ID("externalaudit.googleapis.com/activity")' \
--exclusion=filter='LOG_ID("cloudaudit.googleapis.com/system_event")' \
--exclusion=filter='LOG_ID("externalaudit.googleapis.com/system_event")' \
--exclusion=filter='LOG_ID("cloudaudit.googleapis.com/access_transparency")' \
--exclusion=filter='LOG_ID("externalaudit.googleapis.com/access_transparency")'gcloud logging sinks create {sink_name} \
logging.googleapis.com/projects/{central_project_id} \
--project={source_project_id} \
--exclusion=filter='LOG_ID("cloudaudit.googleapis.com/activity")' \
--exclusion=filter='LOG_ID("externalaudit.googleapis.com/activity")' \
--exclusion=filter='LOG_ID("cloudaudit.googleapis.com/system_event")' \
--exclusion=filter='LOG_ID("externalaudit.googleapis.com/system_event")' \
--exclusion=filter='LOG_ID("cloudaudit.googleapis.com/access_transparency")' \
--exclusion=filter='LOG_ID("externalaudit.googleapis.com/access_transparency")'[!IMPORTANT] Security Action (Tier B): Granting IAM permissions changes access control policy and must be explicitly confirmed by the user before execution.
writerIdentityroles/logging.logWriter# Get the writer identity of the source sink
gcloud logging sinks describe {sink_name} \
--project={source_project_id} \
--format="value(writerIdentity)"{source_writer_identity}serviceAccount:...# Grant Logs Writer permissions on the central project
gcloud projects add-iam-policy-binding {central_project_id} \
--member={source_writer_identity} \
--role=roles/logging.logWriterwriterIdentityroles/logging.bucketWriter# Get the writer identity of the central sink
gcloud logging sinks describe {central_sink_name} \
--project={central_project_id} \
--format="value(writerIdentity)"{central_writer_identity}# Grant Bucket Writer permissions on the central project
gcloud projects add-iam-policy-binding {central_project_id} \
--member={central_writer_identity} \
--role=roles/logging.bucketWritergcloud logging views create {view_id} \
--bucket={bucket_id} \
--location={region} \
--project={central_project_id} \
--log-filter='LOG_ID("{log_id}")'gcloud logging views create {view_id} \
--bucket={bucket_id} \
--location={region} \
--project={central_project_id} \
--log-filter='project_id="{source_project_id}"'gcloud logging write {test_log_id} "Test log entry for verification" \
--severity=WARNING \
--project={source_project_id}--view_Default_AllLogsgcloud logging read 'logName:"projects/{source_project_id}/logs/{test_log_id}"' \
--bucket={bucket_id} \
--location={region} \
--view=_AllLogs \
--project={central_project_id}[!IMPORTANT] Gotcha: Log View filters can only contain specific restrictions. Refer to https://docs.cloud.google.com/logging/docs/logs-views.md.txt#view-filter
gcloud logging views create {view_id} \
--bucket={bucket_id} \
--location={region} \
--project={source_project_id} \
--log-filter='LOG_ID("{log_id}")'{bucket_id}_Default{region}global{view_id}app-logs-view--log-filtergcloud logging scopes create {log_scope_id} \
--project={scoping_project_id} \
--resource-names={resource_names}{log_scope_id}central-query-scope{resource_names}projects/source-project-1/locations/global/buckets/_Default/views/app-logs-view,projects/source-project-2/locations/global/buckets/_Default/views/app-logs-viewgcloud observability scopes update _Default \
--project={scoping_project_id} \
--location=global \
--log-scope=//logging.googleapis.com/projects/{scoping_project_id}/locations/global/logScopes/{log_scope_id}roles/logging.viewAccessorroles/logging.viewer[!IMPORTANT] Gotcha: Standard filter expressions likeorlogName:abccan fail to match in log sinks. Always uselogName="projects/{project_id}/logs/abc"for precise matching in log sink filters.LOG_ID("abc")
gcloud logging sinks describe {sink_name} \
--project={source_project_id} \
--format="value(writerIdentity)"[!IMPORTANT] Security Action (Tier B): Granting IAM permissions changes access control policy and must be explicitly confirmed by the user before execution.
roles/logging.bucketWritergcloud projects add-iam-policy-binding {central_project_id} \
--member={writer_identity} \
--role=roles/logging.bucketWriterroles/storage.objectCreatorroles/pubsub.publisherroles/bigquery.dataEditor