Google Cloud
Connect a Google Cloud organization, folder or project by running one script in Cloud Shell. Maple receives Cloud Logging entries through Pub/Sub and reads Cloud Monitoring metrics every 5 minutes.
The Google Cloud integration connects an organization, a folder or a single project to Maple. You choose what each connection collects:
| What to collect | Collects |
|---|---|
| Log forwarding | A Log Router sink sends Cloud Logging entries through Pub/Sub to Maple. They appear in Logs under the service that wrote them. |
| Metrics and resources | Maple reads Cloud Monitoring metrics for Cloud Run, Cloud Functions, GKE, Compute Engine, Cloud SQL, Pub/Sub and HTTP(S) load balancers every 5 minutes, and lists the resources behind them every hour. The metrics are named gcp.* and work in dashboards and alert rules. |
There is no OAuth step and no service account key. You run a generated gcloud script in Cloud Shell, and Maple gets no write access to Google Cloud.
If your workloads also send telemetry over OpenTelemetry, read Google Cloud with OpenTelemetry: it covers which telemetry to send over OpenTelemetry and which to collect here, and why GKE container logs are left out by default.
Prerequisites
- You are an admin of the Maple organization.
- You can sign in to Cloud Shell with the roles for what you connect:
| You connect | Roles you need |
|---|---|
| A project | Owner on the project. |
| A folder | Owner on the host project. On the folder: Logs Configuration Writer for the log sink, and Folder IAM Admin for the read-only roles. |
| An organization | Owner on the host project. On the organization: Logs Configuration Writer for the log sink, and Organization Administrator for the read-only roles. |
If you can’t get Owner, see Roles for running the script.
The host project holds Maple’s Pub/Sub topic, subscription and read-only service account. A project is its own host project. For a folder or organization, name a shared operations project inside it that won’t be deleted. Google bills the Pub/Sub and Cloud Monitoring usage to the host project.
Metrics and resources needs billing enabled on the host project: Cloud Monitoring only answers for projects that have a billing account. The script checks this before it changes anything.
Find your IDs
| ID | Where to find it |
|---|---|
| Project ID | The console’s project picker lists it next to each project name, or run gcloud projects list. It is not the project name or number. |
| Organization ID | IAM & Admin → Manage resources in the console, or run gcloud organizations list. Digits only. |
| Folder ID | The same console page, or run gcloud resource-manager folders list --organization=ORGANIZATION_ID with your organization’s ID in place of ORGANIZATION_ID. Digits only. |
Connect
- Open Integrations → Google Cloud in Maple and click Connect Google Cloud. When the page already has a connection, click Add connection above the list. The dialog Connect Google Cloud opens on its first stage, Connect.
- Under What to connect, choose Organization, Folder or Project and enter its ID. An organization or folder covers every project in it, including new ones.
- For an organization or folder, enter the Host project ID.
- Under Collect, leave Log forwarding and Metrics and resources ticked, or untick one. To change which logs are forwarded, choose a log filter under Log filter.
- Click Create and continue. Maple creates the connection and the dialog moves to its second stage, Apply in Google Cloud. Nothing changes in Google Cloud until you run the script.
- In step 1, click Open Cloud Shell and sign in with the roles above. Click Authorize if Cloud Shell asks.
- In step 2, click Copy script, paste it into Cloud Shell and press Enter. The script takes about a minute. Read the script shows it in the dialog.
- Return to Maple. Step 3, Maple is waiting for the run, updates on its own. Within a minute of the script ending, usually in seconds, the dialog shows Google Cloud matches this configuration. Click Done.
If you close the dialog before the script has run, the connection’s row shows Setup pending. Click Finish setup to open the dialog at the script. After five minutes without a report from the script, step 3 reads Maple has no confirmation yet and lists what to check.
A first run for a project prints:
Maple setup for project acme-prod
Log forwarding on
Metrics and resources on
Checking access
✓ Signed in as jane@acme.com
✓ Project acme-prod found (Acme Production)
✓ Billing is enabled
✓ jane@acme.com has the permissions this script needs
✓ Log filter accepted
Log forwarding
✓ APIs enabled (Pub/Sub, Cloud Logging, Cloud Resource Manager)
✓ Topic created
✓ Push subscription created
✓ Log sink created
✓ Sink allowed to write to the project
✓ Sink allowed to publish to the topic
✓ Check message sent to Maple through the topic
Metrics and resources
✓ APIs enabled (Cloud Monitoring, Cloud Asset, IAM, IAM Credentials, Cloud Resource Manager)
✓ Read-only service account created
✓ Read-only roles granted (Monitoring Viewer, Cloud Asset Viewer, Service Usage Consumer)
✓ Maple allowed to read as that account
✓ Maple notified
Done. Google Cloud is set up for Maple.
Maple confirms it within a minute: https://app.maple.dev/integrations?integration=gcp
Logs: a new sink can take about 10 minutes to start forwarding. What is logged before
it does is not forwarded later.
Metrics: the first read lands within about 10 minutes.
If a step fails, the script stops and prints what to do. Fix it and paste the script again: it continues where it stopped. Running the script again is safe, and its last line says what the run did:
| The script ends with | The run |
|---|---|
| “Done. Google Cloud is set up for Maple.” | Created the log sink or the read-only service account. |
| “Done. Everything is in place.” | Created and removed nothing. It makes every grant again, so it also restores one that was removed. |
| “Done. The log sink has the filter of this script. Everything else is in place.” | Replaced the sink’s filter and created nothing. |
| “Done. Google Cloud matches your Maple switches.” | Removed what Log forwarding or Metrics and resources, now off, had set up. |
After Maple confirms the run, Log forwarding and Metrics and resources each wait for their first data:
| What to collect | First data |
|---|---|
| Log forwarding | A new sink can take about 10 minutes to start forwarding. Entries logged before that are not forwarded. |
| Metrics and resources | The first read lands within about 10 minutes. Maple reads every 5 minutes, about 5 minutes behind, so that each minute is complete. |
The script contains a secret that lets anyone send logs to your Maple organization. Don’t share it or commit it, and run it in Cloud Shell: there neither the paste nor the secret ends up in shell history. The pasted text keeps itself out of the history files of bash 5 and zsh, but it still shows in your terminal’s scrollback.
The push endpoint with the secret is also visible in the subscription’s configuration and in the host project’s Admin Activity audit log, to anyone who can read those. If it leaks, disconnect and connect again: the new connection gets a new secret.
The first two lines and the last two lines of the pasted text run the script in a bash process of its own, so a failed step can’t close your Cloud Shell session.
A project, folder or organization can be connected once per Maple organization. A project that sits inside a connected organization or folder is collected twice if you also connect it on its own.
Change what a connection collects
- On the connection’s row, click Configure. The dialog opens on its first stage, Configure.
- Under Collect, tick or untick Log forwarding or Metrics and resources. The line beside a changed checkbox says what saving it does.
- Click Save and continue. For a change that takes effect in Maple at once, Maple asks first, in a dialog titled for example “Turn log forwarding off for Project acme-prod?”. The dialog says what happens In Maple and what goes on In Google Cloud. Click Turn off and continue, or Turn on when you turn something back on that still exists in Google Cloud. Then the button of the first stage reads Save, and there is nothing to run.
- The dialog moves to Apply in Google Cloud. Its recap says what is saved and what this run does. Copy the script and run it in Cloud Shell again.
- When the run reports, the dialog shows Google Cloud matches this configuration. Click Done.
A change takes effect in Maple and in Google Cloud at different times:
| Change in Configure | In Maple | In Google Cloud |
|---|---|---|
| Log forwarding off | Maple stops storing the connection’s logs within about a minute of saving. | Google Cloud keeps publishing logs to Pub/Sub, billed by Google, until the script has removed the log sink. |
| Metrics and resources off | Maple stops reading from the next 5-minute read. | The read-only service account and its roles stay until the script has removed them. |
| Log forwarding or Metrics and resources on | Starts once the script has run. | The script creates the log sink, or the read-only service account. |
| Back on while Google Cloud still has the log sink or the service account | At once: Maple stores the logs again as soon as you save, and reads metrics again from the next 5-minute read. | Nothing changes. |
Until the script has run, the connection’s row shows Changes not applied in Google Cloud and says what goes on until then, for example “Google Cloud keeps forwarding logs, billed by Google, until the script has removed the log sink.” Click Apply changes to open the dialog at the script.
A run that removes the log sink takes one to two minutes: after it deletes the sink it waits a minute for Google to stop routing to the topic, so your project logs no sink error.
When nothing is changed, the button in the first stage reads Continue to the script. The setup script exists only in the second stage of this dialog, so this is how you get it again, for example to change the log filter or to repair something. Back returns to the first stage.
A connection collects at least one of the two: the last one that is on can’t be unticked. To stop collecting, disconnect.
Log filter
Log filter decides which filter the script writes onto the sink. It is in the first stage of Connect Google Cloud and of Configure, below Collect, while Log forwarding is ticked.
Platform, request and audit logs are always forwarded. Application output, what the code of a runtime writes to stdout and stderr, is not: send it with your OpenTelemetry setup, where each line links to its trace.
For workloads that can’t send logs over OpenTelemetry, click Can’t forward via OpenTelemetry and tick the runtimes whose application output to forward. None is ticked until you do. Use OpenTelemetry instead closes the ticks and forwards none again.
| Runtime | Covers |
|---|---|
| Cloud Run | Services, jobs, worker pools and 2nd gen functions. |
| Cloud Functions | 1st gen functions. |
| App Engine | Standard and flexible. |
| GKE containers | Every container of a cluster. |
Don’t tick a runtime whose workloads already send their logs to Maple over OpenTelemetry. Otherwise each line is stored twice: see Application output. Maple does not check which workloads do.
On a connection that already has a sink, the choice starts on Keep current filter: the script leaves the sink’s filter as it is. Maple can’t see that filter, so Current filter in Log Router opens it in the console. To change it, click Configure, choose Replace filter, set the runtimes, click Continue to the script and run the script again.
For any other filter, paste the script into an editor first, edit LOG_FILTER near its top and set LOG_FILTER_MODE to set. The filter uses the Logging query language. The script checks the filter with Google before it creates anything. Later runs with Keep current filter leave your filter in place, while Replace filter replaces it.
Verify
Once a connection has delivered data, Integrations → Google Cloud opens with a row of numbers, summed over every connection:
| Number | Counts |
|---|---|
| Log entries · 24h | Entries forwarded in the last 24 hours, with a bar per hour. |
| Errors · 24h | The entries among them of severity error and above. |
| Workloads · 24h | Workloads that reported metrics in the last 24 hours. |
| Resources | Resources in the inventory, and the projects they are in. |
The row follows what has delivered. While only Log forwarding delivers, it shows Log entries, Errors and Warnings. While only Metrics and resources delivers, it shows Workloads, Resources and Projects. A number Maple cannot count yet shows a dash. Below the numbers, Workloads lists what reported metrics in the last 24 hours, the worst first, each a link to its page under Infrastructure → Google Cloud. Beside it, Resources counts the inventory by type.
Under Connections, each connection is a row, the worst state first, with a status for Logs and one for Metrics. A hint, a warning or a failure shows in a band under the row. The page updates on its own.
| Logs | Meaning |
|---|---|
| Not set up | The setup script has not set log forwarding up yet. Run it. |
| Setup running | A run reported on metrics and resources in the last two minutes and has not reported on log forwarding yet. |
| Waiting for the first entry | The script ran and no entry has arrived. After 20 minutes the band reads No log entry in 20 minutes with a gcloud logging write command that writes a test entry. |
| Receiving | Entries arrive. The row shows when the last one did. |
| Nothing in 24 hours | Nothing passed the filter for a day. Not an error. |
| Rejected | Maple refused the last push. The band says why and what to do. |
| Off | Turned off in Configure. While Google Cloud still has the log sink, the band Changes not applied in Google Cloud says so. |
| Metrics | Meaning |
|---|---|
| Not set up | The setup script has not granted Maple read access yet. Run it. |
| Setup running | A run reported on log forwarding in the last two minutes and has not reported on metrics and resources yet. |
| Waiting for the first read | The script ran and the first read has not landed. After 15 minutes the band says that no metrics have arrived yet. |
| Receiving | Reads succeed. The row shows when the last one landed. The label reads Receiving, resource list incomplete when Maple could not list every resource. |
| Incomplete | The last read is under 10 minutes old, but some metric queries failed or were cut short. The band says which. |
| Stalled | No read for 30 minutes and no error. Maple retries every 5 minutes. |
| Can’t be read | Reads fail, and none has succeeded in the last 10 minutes. The band says why and what to do. |
| Off | Turned off in Configure. While the read-only service account still exists, the band Changes not applied in Google Cloud says so. |
The page header and the Integrations list show the connection’s worst status: Needs attention, Setup pending, Changes pending, Waiting for data or Healthy.
A connection that needs the setup script shows a band with one button. The button opens Configure at its second stage, Apply in Google Cloud.
| Band | Button | Shown when |
|---|---|---|
| Setup pending | Finish setup | The script of a new connection has not reported, or its last run stopped part of the way. |
| Changes not applied in Google Cloud | Apply changes | The saved configuration and what the script last reported differ. The band says what goes on until the script has run. |
| A failure’s own message | Run the script again | The text of the failure asks for another run of the setup script. |
Members who are not admins of the Maple organization see the statuses and the numbers, without Configure, the ⋮ menu or the band’s button. The band asks them to have an admin run the setup script, and a line under the list says “Only Maple organization admins can add, configure or disconnect connections.”
Then check the data:
- Open Logs and look for a service named after one of your Cloud Run services, functions or instances.
- In the metrics explorer, search for the prefix
gcp. - Under Dashboards → Browse templates, select Google Cloud and click Create dashboard. It has one tab per service. Use the Project, Region and Workload filters in the toolbar to narrow every chart. To open it on one project, first fill in Project ID under Parameters, below the preview.
- Open Infrastructure → Google Cloud for a table of your workloads per service.
Permissions
The script enables these APIs in the host project:
pubsub.googleapis.comandlogging.googleapis.com, for log forwarding: carrying the log entries and routing them through the sink.monitoring.googleapis.com,cloudasset.googleapis.com,iam.googleapis.comandiamcredentials.googleapis.com, for metrics and resources: reading metrics, listing resources, creating the read-only service account and minting its short-lived tokens. No key is ever created.cloudresourcemanager.googleapis.com, for both: granting the roles below.
For log forwarding it creates a Pub/Sub topic and push subscription in the host project and a log sink on the project, folder or organization. For metrics and resources it creates a read-only service account in the host project. Each is named maple- followed by 24 hexadecimal characters unique to the connection.
It grants these roles:
- Pub/Sub Publisher (
roles/pubsub.publisher) to the sink’s Google-managed writer identity, on Maple’s topic: publishing log entries to the topic. - Logs Writer (
roles/logging.logWriter) to the same writer identity, on the host project: Google requires it on the project that holds a sink’s destination. - Monitoring Viewer (
roles/monitoring.viewer) to the read-only service account, on the project, folder or organization: reading metrics (monitoring.timeSeries.list). - Cloud Asset Viewer (
roles/cloudasset.viewer) to the read-only service account, on the project, folder or organization: listing resources (cloudasset.assets.searchAllResources). The role can also read resource metadata and IAM policies. - Service Usage Consumer (
roles/serviceusage.serviceUsageConsumer) to the read-only service account, on the host project: calling both read APIs through the host project. - Service Account Token Creator (
roles/iam.serviceAccountTokenCreator) to Maple’s service account, on the read-only service account: minting short-lived tokens for that one account.
roles/monitoring.viewer and roles/cloudasset.viewer are the narrowest predefined roles for these calls, and both are read-only. On a folder or organization, every project under it inherits them.
Roles for running the script
Owner on the host project is the simplest. Without it, these predefined roles together cover what the script does:
| On | Role | For |
|---|---|---|
| The host project | Service Usage Admin (roles/serviceusage.serviceUsageAdmin) | Switching on the APIs above. |
| The host project | Project IAM Admin (roles/resourcemanager.projectIamAdmin) | The role grants on the host project. |
| The host project | Pub/Sub Admin (roles/pubsub.admin) | Log forwarding: the topic and the subscription. |
| The host project | Service Account Admin (roles/iam.serviceAccountAdmin) | Metrics and resources: the read-only service account. |
| The project, folder or organization | Logs Configuration Writer (roles/logging.configWriter) | Log forwarding: the sink. |
| The project, folder or organization | Project IAM Admin (roles/resourcemanager.projectIamAdmin), Folder IAM Admin (roles/resourcemanager.folderIamAdmin) or Organization Administrator (roles/resourcemanager.organizationAdmin) | Metrics and resources: the read-only roles. |
Before it changes anything, the script asks Google which permissions the signed-in account holds and stops with the missing ones.
Collected data
Logs
Maple receives every entry the sink’s filter lets through. The default filter excludes:
| Excluded | Reason |
|---|---|
| Data Access audit logs | They record every API read. |
| Load balancer health checks | Probes hit each backend every few seconds. |
| Kubernetes lease renewals | A GKE cluster renews its leader-election leases all day: hundreds of audit entries a minute for an idle node. |
| VM serial console output | A VM writes thousands of lines of raw terminal output at boot. |
| Application output of unticked runtimes | By default every runtime: workloads send their logs over OpenTelemetry, so each line would be stored twice. See Application output. |
The filter, one clause per line in the same order:
NOT log_id("cloudaudit.googleapis.com/data_access")
AND NOT httpRequest.userAgent:"GoogleHC"
AND NOT protoPayload.methodName="io.k8s.coordination.v1.leases.update"
AND NOT logName:"serialconsole.googleapis.com"
AND NOT (log_id("run.googleapis.com/stdout") OR log_id("run.googleapis.com/stderr"))
AND NOT log_id("cloudfunctions.googleapis.com/cloud-functions")
AND NOT (resource.type="gae_app" AND (log_id("stdout") OR log_id("stderr")))
AND NOT resource.type="k8s_container"
The last four clauses are the application output of each runtime: ticking one under Log filter removes its clause.
The script reports to Maple through a log named maple-setup. Maple reads that entry as the report and does not store it, so don’t write your own logs under that name.
Each entry gets its service.name from the resource that wrote it, so workload logs join the traced service of the same name:
| Resource | service.name |
|---|---|
| Cloud Run service | The service name. |
| Cloud Run job | The job name. |
| Cloud Function | The function name. |
| GKE container | The container name. |
| Compute Engine instance | The instance name, or gcp/gce_instance when the entry has none. |
| App Engine | The module ID. |
| Everything else | gcp/<resource type>, for example gcp/cloudsql_database. |
Every entry also carries cloud.provider (gcp), gcp.resource.type and the resource’s labels as gcp.resource.labels.*, plus cloud.account.id (the project ID) and cloud.region when the resource has them. GKE container entries add k8s.cluster.name, k8s.namespace.name, k8s.pod.name and k8s.container.name. Cloud Run service entries add faas.name, faas.version (the revision) and faas.instance, Cloud Run job entries gcp.cloud_run.job.execution and gcp.cloud_run.job.task_index, and Compute Engine entries host.id, host.name and gcp.gce.instance.name.
The log body is textPayload, or the message or msg field of jsonPayload, or the whole jsonPayload as JSON when it has neither. The other jsonPayload fields become log attributes. Audit logs use the method name as the body, and request logs the method, URL and status. An entry’s trace and spanId become the log’s trace and span IDs.
Entry fields that have an OpenTelemetry semantic convention take its name and type:
| Cloud Logging field | Attribute |
|---|---|
httpRequest | http.request.method, url.full, http.response.status_code, http.request.size, http.response.size, user_agent.original, client.address, server.address, http.request.header.referer |
sourceLocation | code.file.path, code.line.number, code.function.name |
insertId | log.record.uid |
Audit authenticationInfo.principalEmail, status.code | user.email, rpc.response.status_code (the code name, for example PERMISSION_DENIED) |
Other fields keep their Cloud Logging names under gcp.: gcp.log_name, gcp.labels.*, gcp.http_request.* (for example latency), gcp.source_location.* and gcp.audit.*.
| Cloud Logging severity | Maple severity |
|---|---|
DEBUG | DEBUG |
INFO, NOTICE | INFO |
WARNING | WARN |
ERROR | ERROR |
CRITICAL, ALERT, EMERGENCY | FATAL |
DEFAULT | Not set |
Metrics
Maple stores these Cloud Monitoring metrics at one-minute resolution, under the gcp. namespace and named the way OpenTelemetry semantic conventions name metrics. Two Cloud Monitoring types that measure the same thing share a name: the byte and operation counters are split by a direction attribute, shown in brackets, and Cloud SQL reports connections from whichever of the two types its engine has.
| Service | Metric | Cloud Monitoring type | Kind | Unit |
|---|---|---|---|---|
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.requests | run.googleapis.com/request_count | Counter | {request} |
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.request.duration | run.googleapis.com/request_latencies | Distribution | s |
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.container.instance.count | run.googleapis.com/container/instance_count | Gauge | {instance} |
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.container.cpu.utilization | run.googleapis.com/container/cpu/utilizations | Distribution | 1 |
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.container.memory.utilization | run.googleapis.com/container/memory/utilizations | Distribution | 1 |
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.container.request.max_concurrency | run.googleapis.com/container/max_request_concurrencies | Distribution | {request} |
| Cloud Run, Cloud Functions (2nd gen) | gcp.cloud_run.container.billable_time | run.googleapis.com/container/billable_instance_time | Counter | s |
| Cloud Functions (1st gen) | gcp.cloud_functions.executions | cloudfunctions.googleapis.com/function/execution_count | Counter | {execution} |
| Cloud Functions (1st gen) | gcp.cloud_functions.execution.duration | cloudfunctions.googleapis.com/function/execution_times | Distribution | s |
| Cloud Functions (1st gen) | gcp.cloud_functions.instance.count | cloudfunctions.googleapis.com/function/instance_count | Gauge | {instance} |
| Cloud Functions (1st gen) | gcp.cloud_functions.memory.usage | cloudfunctions.googleapis.com/function/user_memory_bytes | Distribution | By |
| Cloud Functions (1st gen) | gcp.cloud_functions.network.io (transmit) | cloudfunctions.googleapis.com/function/network_egress | Counter | By |
| GKE containers | gcp.gke.container.cpu.time | kubernetes.io/container/cpu/core_usage_time | Counter | s |
| GKE containers | gcp.gke.container.cpu.limit.utilization | kubernetes.io/container/cpu/limit_utilization | Gauge | 1 |
| GKE containers | gcp.gke.container.memory.usage | kubernetes.io/container/memory/used_bytes | Gauge | By |
| GKE containers | gcp.gke.container.memory.limit.utilization | kubernetes.io/container/memory/limit_utilization | Gauge | 1 |
| GKE containers | gcp.gke.container.restarts | kubernetes.io/container/restart_count | Counter | {restart} |
| GKE nodes | gcp.gke.node.cpu.allocatable.utilization | kubernetes.io/node/cpu/allocatable_utilization | Gauge | 1 |
| GKE nodes | gcp.gke.node.memory.allocatable.utilization | kubernetes.io/node/memory/allocatable_utilization | Gauge | 1 |
| Compute Engine | gcp.gce.cpu.utilization | compute.googleapis.com/instance/cpu/utilization | Gauge | 1 |
| Compute Engine | gcp.gce.memory.usage | compute.googleapis.com/instance/memory/balloon/ram_used (E2 machine types only) | Gauge | By |
| Compute Engine | gcp.gce.network.io (receive) | compute.googleapis.com/instance/network/received_bytes_count | Counter | By |
| Compute Engine | gcp.gce.network.io (transmit) | compute.googleapis.com/instance/network/sent_bytes_count | Counter | By |
| Compute Engine | gcp.gce.disk.io (read) | compute.googleapis.com/instance/disk/read_bytes_count | Counter | By |
| Compute Engine | gcp.gce.disk.io (write) | compute.googleapis.com/instance/disk/write_bytes_count | Counter | By |
| Cloud SQL | gcp.cloud_sql.cpu.utilization | cloudsql.googleapis.com/database/cpu/utilization | Gauge | 1 |
| Cloud SQL | gcp.cloud_sql.memory.utilization | cloudsql.googleapis.com/database/memory/utilization | Gauge | 1 |
| Cloud SQL | gcp.cloud_sql.disk.utilization | cloudsql.googleapis.com/database/disk/utilization | Gauge | 1 |
| Cloud SQL | gcp.cloud_sql.connection.count | cloudsql.googleapis.com/database/network/connections (MySQL, SQL Server) | Gauge | {connection} |
| Cloud SQL | gcp.cloud_sql.connection.count | cloudsql.googleapis.com/database/postgresql/num_backends (PostgreSQL) | Gauge | {connection} |
| Cloud SQL | gcp.cloud_sql.disk.operations (read) | cloudsql.googleapis.com/database/disk/read_ops_count | Counter | {operation} |
| Cloud SQL | gcp.cloud_sql.disk.operations (write) | cloudsql.googleapis.com/database/disk/write_ops_count | Counter | {operation} |
| Cloud SQL | gcp.cloud_sql.replication.lag | cloudsql.googleapis.com/database/replication/replica_lag | Gauge | s |
| Pub/Sub subscriptions | gcp.pubsub.subscription.undelivered_messages | pubsub.googleapis.com/subscription/num_undelivered_messages | Gauge | {message} |
| Pub/Sub subscriptions | gcp.pubsub.subscription.oldest_unacked_message.age | pubsub.googleapis.com/subscription/oldest_unacked_message_age | Gauge | s |
| Pub/Sub subscriptions | gcp.pubsub.subscription.sent_messages | pubsub.googleapis.com/subscription/sent_message_count | Counter | {message} |
| Pub/Sub subscriptions | gcp.pubsub.subscription.acked_messages | pubsub.googleapis.com/subscription/ack_message_count | Counter | {message} |
| Pub/Sub subscriptions | gcp.pubsub.subscription.push_requests | pubsub.googleapis.com/subscription/push_request_count | Counter | {request} |
| Pub/Sub subscriptions | gcp.pubsub.subscription.dead_lettered_messages | pubsub.googleapis.com/subscription/dead_letter_message_count | Counter | {message} |
| Pub/Sub topics | gcp.pubsub.topic.publish_requests | pubsub.googleapis.com/topic/send_request_count | Counter | {request} |
| Load balancers | gcp.load_balancing.requests | loadbalancing.googleapis.com/https/request_count | Counter | {request} |
| Load balancers | gcp.load_balancing.request.duration | loadbalancing.googleapis.com/https/total_latencies | Distribution | s |
| Load balancers | gcp.load_balancing.backend.request.duration | loadbalancing.googleapis.com/https/backend_latencies | Distribution | s |
| Load balancers | gcp.load_balancing.backend.requests | loadbalancing.googleapis.com/https/backend_request_count | Counter | {request} |
| Load balancers | gcp.load_balancing.network.io (receive) | loadbalancing.googleapis.com/https/request_bytes_count | Counter | By |
| Load balancers | gcp.load_balancing.network.io (transmit) | loadbalancing.googleapis.com/https/response_bytes_count | Counter | By |
Value conventions:
- Counters are delta sums per minute. Chart them with
sum, notrate. - Distributions are gauges with a
quantileattribute (0.5,0.95,0.99). - Utilization is a fraction from 0 to 1.
- Durations, such as latency, execution time, message age and replica lag, are in seconds.
Service names follow the same rule as logs: Cloud Run services, functions, GKE containers and Compute Engine instances use the workload name, and everything else is gcp/<resource type>. Narrow further by resource attribute:
| Service | Resource attributes |
|---|---|
| GKE containers | k8s.cluster.name, k8s.namespace.name, k8s.container.name |
| GKE nodes | k8s.cluster.name |
| Compute Engine | gcp.gce.instance.name, host.name, host.id |
| Cloud SQL | gcp.resource.labels.database_id |
| Pub/Sub | gcp.resource.labels.subscription_id, gcp.resource.labels.topic_id |
| Load balancers | gcp.resource.labels.url_map_name, gcp.resource.labels.backend_target_name |
Every series also carries cloud.account.id (the project ID) and, for resources with a location, cloud.region. Google aggregates away every other label, such as revision, pod, response code and device, before the data reaches Maple. These attributes are kept, Cloud Monitoring metric labels under gcp.metric.labels.:
| Attribute | On |
|---|---|
gcp.metric.labels.response_code_class | gcp.cloud_run.requests, gcp.load_balancing.requests, gcp.load_balancing.backend.requests |
gcp.metric.labels.state | gcp.cloud_run.container.instance.count, gcp.cloud_functions.instance.count |
gcp.metric.labels.status | gcp.cloud_functions.executions |
gcp.metric.labels.memory_type | The GKE memory metrics |
gcp.metric.labels.response_class | gcp.pubsub.subscription.push_requests, gcp.pubsub.topic.publish_requests |
network.io.direction | The network.io metrics: receive or transmit |
disk.io.direction | gcp.gce.disk.io, gcp.cloud_sql.disk.operations: read or write |
Resources
Every hour Maple lists these resources from Cloud Asset Inventory, with their project, location, state and labels: projects, Cloud Run services and jobs, Cloud Functions, GKE clusters, Compute Engine instances, Cloud SQL instances, Pub/Sub topics and subscriptions, and load balancer URL maps, backend services and forwarding rules.
Infrastructure → Google Cloud
Infrastructure → Google Cloud is in the sidebar and on the Infrastructure overview while a connection has Metrics and resources on.
The page opens with a band that counts the workloads of every service by health, then one tab per service that reported metrics in the selected time range, with one row per workload. The tab you are on stays when you change the range. Counts and byte totals cover the time range; everything else is the average over it.
| Band cell | Workloads it counts |
|---|---|
| Saturated | Using 90% or more of a CPU, memory or disk limit, on average over the time range |
| Elevated | Using 60% or more of one |
| Erroring | Failing 1% or more of at least 100 requests, executions or push deliveries in the range |
Click a cell to narrow every service tab to those workloads, and click it again to clear it. While a cell is active each tab shows how many of its workloads it holds.
| Tab | One row per | Columns |
|---|---|---|
| Cloud Run | Service, project and region | Requests, 5xx rate, latency p95 and p99, active instances, CPU p95, memory p95 |
| Cloud Functions | 1st gen function, project and region | Executions, error rate, duration p95 and p99, active instances, memory p95 |
| GKE | Container name, namespace and cluster | CPU cores, CPU of limit, memory, memory of limit, restarts |
| Compute Engine | Instance, project and zone | CPU, memory (E2 machine types only), network in and out, disk read and write |
| Cloud SQL | Instance, project and region | CPU, memory, disk, connections, replica lag |
| Pub/Sub | Subscription and project | Backlog, age of the oldest unacknowledged message, delivered, acknowledged, dead-lettered, push errors |
| Load Balancing | URL map, backend and project | Requests, 5xx rate, latency p95 and p99, backend latency p95, bytes sent |
| Resources | Resource from the inventory | Type, project, location, state and labels, with a filter by type and by project |
Search a tab by name, project or location, filter every service tab by project and region, and click a column to sort by it. The search, the filters and the band cell are part of the page’s address, so a link opens the same view. A dash means the workload did not report that metric. CPU below one core is written in millicores: 250m is a quarter of a core. Cloud Functions (2nd gen) run on Cloud Run and appear on the Cloud Run tab. Pub/Sub topic metrics are collected but have no tab: chart them in a dashboard.
Workload pages
Click a row to open that workload: its headline numbers, each marked as a total or an average over the time range, then its charts.
| Service | Charts |
|---|---|
| Cloud Run | Requests by response class, 5xx rate, request latency, active and idle instances, CPU and memory utilization, peak concurrent requests per instance, billable instances |
| Cloud Functions | Executions by status, error rate, execution time, active and idle instances, memory per execution, network egress |
| GKE | CPU cores, CPU of limit, memory, memory of limit and restarts of the container, then CPU and memory of allocatable for the nodes of its cluster |
| Compute Engine | CPU utilization, memory used (E2 machine types only), network received and sent, disk read and written |
| Cloud SQL | CPU, memory and disk utilization, connections, disk read and write operations, replica lag (read replicas only) |
| Pub/Sub | Backlog, age of the oldest unacknowledged message, delivered and acknowledged messages, dead-lettered messages, push requests by response and push error rate (push only) |
| Load Balancing | Requests by response class, 5xx rate, total latency, backend latency, backend requests by response class, request and response traffic |
Latency charts draw p50, p95 and p99, and so do Cloud Run’s CPU, memory and concurrency and a function’s memory; every other line is the average. Requests and executions by class, traffic, messages and disk operations are per second; restarts and dead-lettered messages are counts per point. A point covers at least 5 minutes, and more on a long range. While a workload reports nothing, as a Cloud Run service scaled to zero does, its counters read zero and its other lines have a gap. A share of a limit carries a line at 80%. Hovering one chart marks the same moment on the others.
From a workload’s page:
- Logs opens the workload’s logs. A Cloud SQL instance, a subscription and a URL map open the logs of their resource type, narrowed to the resource.
- Traces is there when a service of the same name sent traces in the time range.
- The icon beside a chart’s title opens its metric in the metrics explorer.
- When the workload is in the inventory, its state and labels show under its name, and Google Cloud opens its product’s list in the Google Cloud console, on the resource’s project. A GKE container gets the link to its cluster’s list, without state or labels. The match is by type, project, name and location: a workload Maple cannot match exactly shows neither.
Elsewhere in Maple
- The Infrastructure overview row counts the workloads, colors them by health and lists up to three that are saturated, elevated or erroring. Each opens the workload’s page. While every workload is healthy the row names the services that report.
- On the service map, the panel of a traced service shows the numbers of the Cloud Run service, function, GKE container or VM of the same name, with a link to its page.
- A row of the Resources tab that is one workload (a Cloud Run service, a 1st gen function, a VM, a Cloud SQL instance, a subscription) opens that workload’s page.
The Resources tab shows the first 500 resources that match its filters, and how many projects Maple found. It does not depend on the time range.
Until a connection’s setup script has run, the page reads Finish setting up Google Cloud. After the run it reads Collecting your first Google Cloud metrics until the first read lands, within about 10 minutes.
With Metrics and resources off on every connection, the page leaves the sidebar and the overview. Its address still opens it: for a time range with data it shows the service tabs with what Maple collected before, under the notice Google Cloud metrics are switched off, and otherwise it reads Turn on metrics for Google Cloud. The Resources tab is back once a connection collects again.
Google Cloud costs
Google bills Pub/Sub and Cloud Monitoring usage to your account, separately from your Maple plan.
Google bills Pub/Sub for the log entries that pass through the topic and the subscription. A narrower LOG_FILTER lowers it. See Pub/Sub pricing.
Google bills Cloud Monitoring API reads to the host project. Each connection runs 46 timeSeries.list queries every 5 minutes, and the cost grows with the number of time series in the project, folder or organization. See Google Cloud Observability pricing.
Cloud Asset Inventory searches are free of charge. See Cloud Asset Inventory pricing.
Limits
- Pub/Sub delivers one log entry per HTTP request, at least once. A redelivered entry is stored again. Its Cloud Logging
insertIdis in thelog.record.uidattribute. - The subscription keeps undelivered entries for one day. Entries Maple could not accept within that day are lost.
- Connecting an organization and a folder or project inside it collects that part twice. Each connection has its own sink and its own metric reads.
- Metrics arrive every 5 minutes, 5 minutes behind. The first read, and the first read after a pause, covers at most the last hour.
- One read takes up to 20,000 data points per metric, about 4,000 series, and up to 2 minutes in total. Past that, the connection says how many metric queries were cut short. For a folder or organization, connect its folders or projects separately to collect all of it.
- Maple reads up to 10 connections of one Maple organization every 5 minutes. With more, they take turns.
- The resource list holds up to 10,000 resources per connection.
- Load balancer metrics cover global external Application Load Balancers only.
Troubleshooting
To run the setup script again, click Configure on the connection’s row, then Continue to the script. When a failure asks for another run, its band has the button Run the script again.
In Cloud Shell
A step that fails stops the script. It prints what went wrong, Google’s answer, and a line that starts with What to do:. Nothing needs undoing: fix it and paste the script again. A connection’s ID can’t be changed, so a wrong ID is fixed by removing the connection in Maple and connecting the right ID. In the lines below, account stands for the account you are signed in as.
| The script prints | Cause and fix |
|---|---|
| “Can’t open project acme-prod as account.” | The ID is wrong, or the account has no access to the project. Check the ID with gcloud projects list. It is the project ID, not the name or number. If it is wrong, remove the connection and connect the right ID. |
| “account has none of the permissions this script needs on project acme-prod.” | Check the ID in Maple first. If it is wrong, remove the connection and connect the right ID. If it is right, the account has no rights there: ask for the roles under Prerequisites, or have an administrator run the script. |
| “account is missing permissions on project acme-prod:” and a list | The account lacks a role. The line names the permissions and the role to ask for. If the only one listed is the permission to enable services, an API the script needs is off: ask for Service Usage Admin on the host project, or have an administrator switch the named APIs on. Nothing was created yet. |
| “Project acme-prod has no billing account.” | Link a billing account to the host project, then paste the script again. |
| “gcloud version is too old for this script.” | Run the script in Cloud Shell, or update gcloud (gcloud components update, or the package manager that installed it). Versions before 470 can’t update a folder or organization sink. |
| “account can’t see folder 123456789012.” (or organization) | The ID is wrong, or the account has no rights there. Check it with gcloud resource-manager folders list --organization=ORGANIZATION_ID or gcloud organizations list. |
| “Couldn’t look for a resource: its API is off in project acme-prod.” | Cleanup only. The API was switched off after a setup run, so the resource may still be there. Switch the API on and paste the cleanup script again. |
| “Google does not accept the log filter.” | LOG_FILTER was edited into something Google can’t parse. Correct it near the top of the script and paste it again. Nothing was created yet. |
| “An organization policy (domain restricted sharing) blocks granting Maple’s service account” | See Domain restricted sharing. |
| “Google is still switching an API on, or the API is off.” | Wait a minute and paste the script again. |
| “Google has not published the new service account yet.” | Wait a minute and paste the script again. |
| “Couldn’t reach Maple to confirm.” | Cloud Shell could not reach Maple. Google Cloud is set up, and Maple shows Setup pending or Changes pending until a later run reaches it. Paste the script again. |
When you create a connection in Maple, “The Google Cloud project acme-prod is already connected.” means this Maple organization already has a connection for it. Click Configure on that connection instead.
Log forwarding
| The connection shows | Cause and fix |
|---|---|
| Setup pending after the script ran | The script stopped before it finished, or could not reach Maple. Read its last lines in Cloud Shell and paste it again. |
| Waiting for the first entry for more than 20 minutes | Either nothing was logged that passes the filter, or the sink can’t publish. Run the gcloud logging write command the band shows. If the entry does not arrive within a minute, open Configure and run the setup script again. |
| Rejected: “The Pub/Sub subscription wraps each entry in an envelope Maple can’t read.” | The subscription was changed to deliver wrapped messages. Run the setup script again: it resets the subscription. Entries sent meanwhile are lost. |
| Rejected: “Maple could not store an entry just now.” | Nothing to do. Pub/Sub retries the entry for up to a day, and the status returns to Receiving with the next accepted entry. |
| Rejected: “This Maple organization is over its plan limit, so Maple refuses new logs.” | Raise the plan limit under Settings → Billing. Pub/Sub retries refused entries for up to a day. |
| A workload’s logs appear twice | The sink forwards its application output and the workload also sends its logs over OpenTelemetry. In Configure, choose Replace filter, leave its runtime unticked under Log filter and run the script again. |
| A workload’s stdout and stderr are missing | Application output is not forwarded by default. Send it over OpenTelemetry, or tick its runtime under Log filter in Configure and run the script again. |
Metrics and resources
Can’t be read and Incomplete come with one of the messages below. The first means no read has succeeded in the last 10 minutes. The second means the last read is under 10 minutes old and something is missing. The messages about the resource list show under Receiving, resource list incomplete. Where a project’s message says “the project”, a folder’s or organization’s says “the host project”.
| The connection shows | Cause and fix |
|---|---|
| Stalled | No read for 30 minutes and no error. Maple retries on its own. If it stays for more than an hour, write to support. |
| “Maple can’t sign in as this connection’s read-only service account yet.” | Shown from 10 minutes after a setup run, on a connection Maple has never read. The account does not exist, or the grant to Maple is missing or blocked by an organization policy. Run the setup script again and read its last lines. See Domain restricted sharing. |
| “Maple can no longer sign in as this connection’s read-only service account.” | Maple has read this connection before. The account was deleted, or the grant to Maple was removed or is blocked by an organization policy. Run the setup script again: it restores both, or says what blocks it. |
| “The project acme-prod has no active billing account” | Link a billing account to the host project. The message carries the link. Maple retries every 5 minutes. |
| “The Cloud Monitoring API is switched off in the project acme-prod.” | Run the setup script again: it switches the API on. |
| “Google denied Maple’s read of project acme-prod: the read-only roles are missing.” | Run the setup script again: it grants them. A new grant can take a few minutes to work. |
| “Google rate-limited the Cloud Monitoring API for the project acme-prod.” | Maple keeps what it read and retries in 5 minutes. If it repeats, raise that API’s quota on the host project. |
| “3 of 46 metric queries failed, first …” | The rest were stored. The failed metrics miss those minutes, and Maple retries in 5 minutes. |
| “3 of 46 metric queries were not read in full” | The project, folder or organization holds more series than one read takes. Connect the folders or projects of a folder or organization as separate connections. For a single project, write to support. |
| “Reading the metrics took longer than two minutes.” | Maple reads the same minutes again, which can store part of them twice. If it repeats, connect the folders or projects of a folder or organization separately. For a single project, write to support. |
| “Metrics are paused: this Maple organization is over its plan limit.” | Raise the plan limit under Settings → Billing. Maple tries again in an hour. |
| “Maple could not store the metrics it read just now.” | Nothing to do. Maple reads the same minutes again. |
| “Google denied the resource listing for project acme-prod.” | Run the setup script again: it grants Cloud Asset Viewer. Metrics are unaffected. |
| “The project holds more than 10,000 resources, so the resource list is incomplete.” | Metrics are unaffected. For a full list, connect the folders or projects of a folder or organization separately. For a single project, write to support. |
| “The resource listing ran out of time and is incomplete.” | Nothing to do. Maple retries within the hour. |
A message that ends in parentheses, such as “(Cloud Monitoring returned 403, BILLING_DISABLED)”, quotes Google’s answer. Include it when you write to support.
On a self-hosted Maple, the Metrics and resources checkbox reads Not available on this Maple deployment until MAPLE_GCP_SERVICE_ACCOUNT_EMAIL names a Google service account the deployment owns. Reading metrics also needs MAPLE_GCP_SERVICE_ACCOUNT_KEY, that account’s key file, base64-encoded.
Domain restricted sharing
An organization policy can restrict which identities may hold IAM roles in your organization (constraints/iam.allowedPolicyMemberDomains, or a custom constraint on member domains). Maple’s service account lives outside your organization, so such a policy can reject a grant the script makes, most often the one that lets Maple read as your read-only service account. The script then stops with “An organization policy (domain restricted sharing) blocks granting Maple’s service account”.
Don’t turn the policy off or allow all principals for this. An Organization Policy Administrator can allow Maple’s one service account on the host project, and nothing else:
- Use the managed constraint Restrict allowed policy members in IAM allow policies (
iam.managed.allowedPolicyMembers). The olderiam.allowedPolicyMemberDomainscan’t make an exception for a single principal. - On the host project, set a policy for it whose allowed principals are your organization’s principal set plus Maple’s service account (
serviceAccount:followed by the address the script’s error names). Listing your organization keeps everyone in it allowed on the project. Google’s steps: Restrict identities with domain-restricted sharing. - Paste the setup script again. It continues where it stopped.
Google checks the policy when a grant is made, so leave the exception in place: a later re-run grants again.
Disconnect
- On Integrations → Google Cloud, open the ⋮ menu (More actions) on the connection’s row and choose Disconnect.
- Click Copy cleanup script and run it in Cloud Shell. It deletes the log sink, topic, subscription and read-only service account, and ends with “Done. Everything the setup script created is gone.”
- Wait for the check mark in the dialog, then click Disconnect. Maple stops reading the connection’s metrics, and stops accepting its logs within about a minute. Data already in Maple is kept.
The cleanup takes one to two minutes when the connection forwards logs: after it deletes the sink it waits a minute for Google to stop routing to the topic, so your project logs no sink error. Turning Log forwarding off in Configure and running the setup script takes as long, for the same reason.
Disconnect anyway disconnects without the cleanup. Google Cloud then keeps publishing logs to Pub/Sub, billed by Google, until the cleanup script runs. Maple keeps a panel with Copy cleanup script on the page until you click Dismiss and confirm.
The cleanup script leaves the APIs it switched on enabled, and the Logs Writer role of Google’s logging service account on the host project, which other sinks share.
For a connection whose setup script Maple never saw run, Disconnect asks once and has no cleanup step. Maple still offers the cleanup script afterwards, in case the setup script ran part of the way.
Next steps
- Google Cloud with OpenTelemetry: what to instrument on GKE, Cloud Run and Compute Engine.
- Logs: search Google Cloud logs next to your application logs.
- Dashboards: start from the Google Cloud template.
- Infrastructure → Google Cloud: scan every workload of a service in one table.
- Alert rules: alert on any
gcp.*metric. - API reference: manage connections with the
/v2/integrations/gcpendpoints.