google / google/clasp

logs: graceful watch exit and Cloud Logging API quota compliance

Open
#1,170 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
5.8k
Forks
510
Avg merge
5h 27m
Merged PRs (30d)
1

Description

## Expected Behavior

- `clasp logs --watch` (`tail-logs`) exits gracefully on `SIGINT`/`SIGTERM` by clearing active timers and resolving the polling promise.
- Transient API fetch errors during log polling are caught and logged to stderr without uncaught promise rejections crashing the process.
- Cloud Logging requests attribute quota to the configured GCP project via `x-goog-user-project: ` rather than the global shared OAuth client (`1072944905499`).
- Log polling rate and pagination in `Logs.getLogEntries` stay within Google Cloud Logging API quota (60 read requests/minute).

## Actual Behavior

- `clasp logs --watch` does not clean up polling interval timers on termination signals, preventing clean process exit.
- Unhandled API errors during async log polling can bypass standard error logging or break execution.
- Requests without `x-goog-user-project` attribute quota to the global shared OAuth client project (`1072944905499`), causing global quota collision.
- Default pagination in `fetchWithPages` combined with polling interval causes requests to exceed Google Cloud Logging API read quota limit (60 req/min), triggering `429 RESOURCE_EXHAUSTED: Quota exceeded for quota metric Read requests`.

The following is a snippet of the console output on exit.
```
$ clasp logs --watch
...
Error: Quota exceeded for quota metric 'Read requests' and limit 'Read requests per minute' of service 'logging.googleapis.com' for consumer 'project_number:1072944905499'.
at Gaxios._request (/home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/node_modules/gaxios/build/cjs/src/gaxios.js:155:23)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async UserRefreshClient.requestAsync (/home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/node_modules/google-auth-library/build/src/auth/oauth2client.js:463:20)
at async createAPIRequestAsync (/home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/node_modules/googleapis-common/build/src/apirequest.js:308:25)
at async file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/core/logs.js:51:29
at async fetchWithPages (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/core/utils.js:90:22)
at async file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/tail-logs.js:32:67
at async withSpinner (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/utils.js:93:16)
at async fetchAndPrintLogs (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/tail-logs.js:32:25)
at async Timeout._onTimeout (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/tail-logs.js:63:13)
Error: Quota exceeded for quota metric 'Read requests' and limit 'Read requests per minute' of service 'logging.googleapis.com' for consumer 'project_number:1072944905499'.
at Gaxios._request (/home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/node_modules/gaxios/build/cjs/src/gaxios.js:155:23)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async UserRefreshClient.requestAsync (/home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/node_modules/google-auth-library/build/src/auth/oauth2client.js:463:20)
at async createAPIRequestAsync (/home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/node_modules/googleapis-common/build/src/apirequest.js:308:25)
at async file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/core/logs.js:51:29
at async fetchWithPages (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/core/utils.js:90:22)
at async file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/tail-logs.js:32:67
at async withSpinner (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/utils.js:93:16)
at async fetchAndPrintLogs (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/tail-logs.js:32:25)
at async Timeout._onTimeout (file:///home/lucasrangit/.nvm/versions/node/v24.14.0/lib/node_modules/@google/clasp/build/src/commands/tail-logs.js:63:13)
```

The following is an example of the quota exceeded console message that shows that quota from the shared GCP project https://console.cloud.google.com/home/dashboard?project=1072944905499 is being used not the configured `.clasp.json` project ID:

```
Quota exceeded for quota metric 'Read requests' and limit 'Read requests per minute' of service 'logging.googleapis.com' for consumer 'project_number:1072944905499'.
Quota exceeded for quota metric 'Read requests' and limit 'Read requests per minute' of service 'logging.googleapis.com' for consumer 'project_number:1072944905499'.
```

## Steps to Reproduce the Problem

1. Run `clasp logs --watch` on a project linked to Google Cloud Platform.
1. Send `SIGINT` (`Ctrl+C`) -> process does not clean up active polling timer before exit.
1. Run `clasp logs --watch` continuously on an active project -> Cloud Logging API throws 429 quota exhaustion.

## Specifications

- Node version (`node -v`): v20.x / v22.x
- Version (`clasp -v`): 3.4.1
- OS (Mac/Linux/Windows): Linux / macOS / Windows

## Proposed Fixes

1. https://github.com/lucasrangit/clasp/pull/1
1. https://github.com/lucasrangit/clasp/pull/2

Contributor guide

Open the contributing guide

Research direction

Start with the polling entry points shown in commands/tail-logs.js, core/logs.js, and core/utils.js, tracing timer cleanup, error handling, pagination, and request headers. Run clasp logs --watch and reproduce SIGINT plus the 429 response; done means graceful termination, logged transient errors, project-attributed requests, and polling within the documented quota.

Written by the indexing model from the issue text.

Assessment

Tech stack
google-cloud, typescript
Domain
api, cli, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.