2025-06-13 20:28:18 -07:00
#!/usr/bin/env node
/ * *
* @ license
* Copyright 2025 Google LLC
* SPDX - License - Identifier : Apache - 2.0
* /
2025-08-25 22:11:27 +02:00
import path from 'node:path' ;
import fs from 'node:fs' ;
import { spawn , execSync } from 'node:child_process' ;
2025-06-13 20:28:18 -07:00
import {
OTEL _DIR ,
BIN _DIR ,
fileExists ,
waitForPort ,
ensureBinary ,
manageTelemetrySettings ,
registerCleanup ,
} from './telemetry_utils.js' ;
const OTEL _CONFIG _FILE = path . join ( OTEL _DIR , 'collector-gcp.yaml' ) ;
const OTEL _LOG _FILE = path . join ( OTEL _DIR , 'collector-gcp.log' ) ;
const getOtelConfigContent = ( projectId ) => `
receivers :
otlp :
protocols :
grpc :
endpoint : "localhost:4317"
processors :
batch :
timeout : 1 s
exporters :
googlecloud :
project : "${projectId}"
metric :
prefix : "custom.googleapis.com/gemini_cli"
log :
default _log _name : "gemini_cli"
debug :
verbosity : detailed
service :
telemetry :
logs :
level : "debug"
metrics :
level : "none"
pipelines :
traces :
receivers : [ otlp ]
processors : [ batch ]
exporters : [ googlecloud ]
metrics :
receivers : [ otlp ]
processors : [ batch ]
exporters : [ googlecloud , debug ]
logs :
receivers : [ otlp ]
processors : [ batch ]
exporters : [ googlecloud , debug ]
` ;
async function main ( ) {
console . log ( '✨ Starting Local Telemetry Exporter for Google Cloud ✨' ) ;
let collectorProcess ;
let collectorLogFd ;
const originalSandboxSetting = manageTelemetrySettings (
true ,
'http://localhost:4317' ,
Add telemetry command and refactor telemetry settings (#1060)
#750
### Telemetry Settings
Refactors telemetry configuration to use a nested `telemetry` object in `settings.json`, for example:
```json
{
"telemetry": {
"enabled": true,
"target": "gcp"
"log-prompts": "true"
},
"sandbox": false
}
```
The above includes
- Centralized telemetry settings under a `telemetry` object in `settings.json`.
- CLI flags for the `gemini` command to override all telemetry sub-settings:
- `--telemetry` / `--no-telemetry`
- `--telemetry-target <local|gcp>`
- `--telemetry-otlp-endpoint <URL>`
- `--telemetry-log-prompts` / `--no-telemetry-log-prompts`
- Updates `packages/cli/src/config/config.ts` and `packages/core/src/config/config.ts` to read from the new settings structure and respect the new CLI flags.
- Modifies `scripts/handle-telemetry.js`, `scripts/local_telemetry.js`, and `scripts/telemetry_utils.js` to align with the new settings structure.
- Updates `docs/core/telemetry.md` to reflect the new settings structure, CLI flags, and order of precedence.
- Renames `logUserPromptsEnabled` to `logPrompts` for brevity.
### `npm run telemetry`
Add a new `npm run telemetry` command that uses `scripts/telemetry.js`, automates the entire process of setting up a local and GCP telemetry pipelines, including configuring the necessary settings in the `.gemini/settings.json` workspace file and installing required binaries (e.g. `otelcol-contrib`).
---
```shell
$ npm run telemetry -- --target=gcp
> gemini-cli@0.1.0 telemetry
> node scripts/telemetry.js --target=gcp
⚙️ Using command-line target: gcp
🚀 Running telemetry script for target: gcp.
✨ Starting Local Telemetry Exporter for Google Cloud ✨
⚙️ Enabled telemetry in workspace settings.
🔧 Set telemetry OTLP endpoint to http://localhost:4317.
🎯 Set telemetry target to gcp.
✅ Workspace settings updated.
✅ Using Google Cloud Project ID: foo-bar
🔑 Please ensure you are authenticated with Google Cloud:
- Run `gcloud auth application-default login` OR ensure `GOOGLE_APPLICATION_CREDENTIALS` environment variable points to a valid service account key.
- The account needs "Cloud Trace Agent", "Monitoring Metric Writer", and "Logs Writer" roles.
✅ otelcol-contrib already exists at /Users/jerop/github/gemini-cli/.gemini/otel/bin/otelcol-contrib
🧹 Cleaning up old processes and logs...
✅ Deleted old GCP collector log.
📄 Wrote OTEL collector config to /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.yaml
🚀 Starting OTEL collector for GCP... Logs: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
⏳ Waiting for OTEL collector to start (PID: 17013)...
✅ OTEL collector started successfully on port 4317.
✨ Local OTEL collector for GCP is running.
🚀 To send telemetry, run the Gemini CLI in a separate terminal window.
📄 Collector logs are being written to: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
📊 View your telemetry data in Google Cloud Console:
- Logs: https://console.cloud.google.com/logs/query;query=logName%3D%22projects%2Ffoo-bar%2Flogs%2Fgemini_cli%22?project=foo-bar
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer?project=foo-bar
- Traces: https://console.cloud.google.com/traces/list?project=foo-bar
Press Ctrl+C to exit.
^C
👋 Shutting down...
⚙️ Disabled telemetry in workspace settings.
🔧 Cleared telemetry OTLP endpoint.
🎯 Cleared telemetry target.
✅ Workspace settings updated.
🛑 Stopping otelcol-contrib (PID: 17013)...
✅ otelcol-contrib stopped.
```
2025-06-15 00:47:32 -04:00
'gcp' ,
2025-06-13 20:28:18 -07:00
) ;
registerCleanup (
( ) => [ collectorProcess ] . filter ( ( p ) => p ) , // Function to get processes
( ) => [ collectorLogFd ] . filter ( ( fd ) => fd ) , // Function to get FDs
originalSandboxSetting ,
) ;
2025-06-15 21:12:57 -04:00
const projectId = process . env . OTLP _GOOGLE _CLOUD _PROJECT ;
2025-06-13 20:28:18 -07:00
if ( ! projectId ) {
console . error (
2025-06-15 21:12:57 -04:00
'🛑 Error: OTLP_GOOGLE_CLOUD_PROJECT environment variable is not exported.' ,
2025-06-13 20:28:18 -07:00
) ;
Add telemetry command and refactor telemetry settings (#1060)
#750
### Telemetry Settings
Refactors telemetry configuration to use a nested `telemetry` object in `settings.json`, for example:
```json
{
"telemetry": {
"enabled": true,
"target": "gcp"
"log-prompts": "true"
},
"sandbox": false
}
```
The above includes
- Centralized telemetry settings under a `telemetry` object in `settings.json`.
- CLI flags for the `gemini` command to override all telemetry sub-settings:
- `--telemetry` / `--no-telemetry`
- `--telemetry-target <local|gcp>`
- `--telemetry-otlp-endpoint <URL>`
- `--telemetry-log-prompts` / `--no-telemetry-log-prompts`
- Updates `packages/cli/src/config/config.ts` and `packages/core/src/config/config.ts` to read from the new settings structure and respect the new CLI flags.
- Modifies `scripts/handle-telemetry.js`, `scripts/local_telemetry.js`, and `scripts/telemetry_utils.js` to align with the new settings structure.
- Updates `docs/core/telemetry.md` to reflect the new settings structure, CLI flags, and order of precedence.
- Renames `logUserPromptsEnabled` to `logPrompts` for brevity.
### `npm run telemetry`
Add a new `npm run telemetry` command that uses `scripts/telemetry.js`, automates the entire process of setting up a local and GCP telemetry pipelines, including configuring the necessary settings in the `.gemini/settings.json` workspace file and installing required binaries (e.g. `otelcol-contrib`).
---
```shell
$ npm run telemetry -- --target=gcp
> gemini-cli@0.1.0 telemetry
> node scripts/telemetry.js --target=gcp
⚙️ Using command-line target: gcp
🚀 Running telemetry script for target: gcp.
✨ Starting Local Telemetry Exporter for Google Cloud ✨
⚙️ Enabled telemetry in workspace settings.
🔧 Set telemetry OTLP endpoint to http://localhost:4317.
🎯 Set telemetry target to gcp.
✅ Workspace settings updated.
✅ Using Google Cloud Project ID: foo-bar
🔑 Please ensure you are authenticated with Google Cloud:
- Run `gcloud auth application-default login` OR ensure `GOOGLE_APPLICATION_CREDENTIALS` environment variable points to a valid service account key.
- The account needs "Cloud Trace Agent", "Monitoring Metric Writer", and "Logs Writer" roles.
✅ otelcol-contrib already exists at /Users/jerop/github/gemini-cli/.gemini/otel/bin/otelcol-contrib
🧹 Cleaning up old processes and logs...
✅ Deleted old GCP collector log.
📄 Wrote OTEL collector config to /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.yaml
🚀 Starting OTEL collector for GCP... Logs: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
⏳ Waiting for OTEL collector to start (PID: 17013)...
✅ OTEL collector started successfully on port 4317.
✨ Local OTEL collector for GCP is running.
🚀 To send telemetry, run the Gemini CLI in a separate terminal window.
📄 Collector logs are being written to: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
📊 View your telemetry data in Google Cloud Console:
- Logs: https://console.cloud.google.com/logs/query;query=logName%3D%22projects%2Ffoo-bar%2Flogs%2Fgemini_cli%22?project=foo-bar
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer?project=foo-bar
- Traces: https://console.cloud.google.com/traces/list?project=foo-bar
Press Ctrl+C to exit.
^C
👋 Shutting down...
⚙️ Disabled telemetry in workspace settings.
🔧 Cleared telemetry OTLP endpoint.
🎯 Cleared telemetry target.
✅ Workspace settings updated.
🛑 Stopping otelcol-contrib (PID: 17013)...
✅ otelcol-contrib stopped.
```
2025-06-15 00:47:32 -04:00
console . log (
' Please set it to your Google Cloud Project ID and try again.' ,
) ;
2025-06-15 21:12:57 -04:00
console . log ( ' `export OTLP_GOOGLE_CLOUD_PROJECT=your-project-id`' ) ;
2025-06-13 20:28:18 -07:00
process . exit ( 1 ) ;
}
2025-06-15 21:12:57 -04:00
console . log ( ` ✅ Using OTLP Google Cloud Project ID: ${ projectId } ` ) ;
2025-06-13 20:28:18 -07:00
console . log ( '\n🔑 Please ensure you are authenticated with Google Cloud:' ) ;
console . log (
' - Run `gcloud auth application-default login` OR ensure `GOOGLE_APPLICATION_CREDENTIALS` environment variable points to a valid service account key.' ,
) ;
console . log (
' - The account needs "Cloud Trace Agent", "Monitoring Metric Writer", and "Logs Writer" roles.' ,
) ;
if ( ! fileExists ( BIN _DIR ) ) fs . mkdirSync ( BIN _DIR , { recursive : true } ) ;
const otelcolPath = await ensureBinary (
'otelcol-contrib' ,
'open-telemetry/opentelemetry-collector-releases' ,
( version , platform , arch , ext ) =>
` otelcol-contrib_ ${ version } _ ${ platform } _ ${ arch } . ${ ext } ` ,
'otelcol-contrib' ,
false , // isJaeger = false
) . catch ( ( e ) => {
console . error ( ` 🛑 Error getting otelcol-contrib: ${ e . message } ` ) ;
return null ;
} ) ;
if ( ! otelcolPath ) process . exit ( 1 ) ;
console . log ( '🧹 Cleaning up old processes and logs...' ) ;
try {
execSync ( 'pkill -f "otelcol-contrib"' ) ;
console . log ( '✅ Stopped existing otelcol-contrib process.' ) ;
} catch ( _e ) {
/* no-op */
}
try {
fs . unlinkSync ( OTEL _LOG _FILE ) ;
console . log ( '✅ Deleted old GCP collector log.' ) ;
} catch ( e ) {
if ( e . code !== 'ENOENT' ) console . error ( e ) ;
}
if ( ! fileExists ( OTEL _DIR ) ) fs . mkdirSync ( OTEL _DIR , { recursive : true } ) ;
fs . writeFileSync ( OTEL _CONFIG _FILE , getOtelConfigContent ( projectId ) ) ;
console . log ( ` 📄 Wrote OTEL collector config to ${ OTEL _CONFIG _FILE } ` ) ;
console . log ( ` 🚀 Starting OTEL collector for GCP... Logs: ${ OTEL _LOG _FILE } ` ) ;
collectorLogFd = fs . openSync ( OTEL _LOG _FILE , 'a' ) ;
collectorProcess = spawn ( otelcolPath , [ '--config' , OTEL _CONFIG _FILE ] , {
stdio : [ 'ignore' , collectorLogFd , collectorLogFd ] ,
env : { ... process . env } ,
} ) ;
console . log (
` ⏳ Waiting for OTEL collector to start (PID: ${ collectorProcess . pid } )... ` ,
) ;
try {
await waitForPort ( 4317 ) ;
console . log ( ` ✅ OTEL collector started successfully on port 4317. ` ) ;
} catch ( err ) {
console . error ( ` 🛑 Error: OTEL collector failed to start on port 4317. ` ) ;
console . error ( err . message ) ;
if ( collectorProcess && collectorProcess . pid ) {
process . kill ( collectorProcess . pid , 'SIGKILL' ) ;
}
if ( fileExists ( OTEL _LOG _FILE ) ) {
console . error ( '📄 OTEL Collector Log Output:' ) ;
console . error ( fs . readFileSync ( OTEL _LOG _FILE , 'utf-8' ) ) ;
}
process . exit ( 1 ) ;
}
collectorProcess . on ( 'error' , ( err ) => {
console . error ( ` ${ collectorProcess . spawnargs [ 0 ] } process error: ` , err ) ;
process . exit ( 1 ) ;
} ) ;
console . log ( ` \n ✨ Local OTEL collector for GCP is running. ` ) ;
2025-06-14 07:49:21 -07:00
console . log (
'\n🚀 To send telemetry, run the Gemini CLI in a separate terminal window.' ,
) ;
2025-06-13 20:28:18 -07:00
console . log ( ` \n 📄 Collector logs are being written to: ${ OTEL _LOG _FILE } ` ) ;
2025-06-23 01:10:26 -04:00
console . log (
` 📄 Tail collector logs in another terminal: tail -f ${ OTEL _LOG _FILE } ` ,
) ;
2025-06-13 20:28:18 -07:00
console . log ( ` \n 📊 View your telemetry data in Google Cloud Console: ` ) ;
console . log (
Add telemetry command and refactor telemetry settings (#1060)
#750
### Telemetry Settings
Refactors telemetry configuration to use a nested `telemetry` object in `settings.json`, for example:
```json
{
"telemetry": {
"enabled": true,
"target": "gcp"
"log-prompts": "true"
},
"sandbox": false
}
```
The above includes
- Centralized telemetry settings under a `telemetry` object in `settings.json`.
- CLI flags for the `gemini` command to override all telemetry sub-settings:
- `--telemetry` / `--no-telemetry`
- `--telemetry-target <local|gcp>`
- `--telemetry-otlp-endpoint <URL>`
- `--telemetry-log-prompts` / `--no-telemetry-log-prompts`
- Updates `packages/cli/src/config/config.ts` and `packages/core/src/config/config.ts` to read from the new settings structure and respect the new CLI flags.
- Modifies `scripts/handle-telemetry.js`, `scripts/local_telemetry.js`, and `scripts/telemetry_utils.js` to align with the new settings structure.
- Updates `docs/core/telemetry.md` to reflect the new settings structure, CLI flags, and order of precedence.
- Renames `logUserPromptsEnabled` to `logPrompts` for brevity.
### `npm run telemetry`
Add a new `npm run telemetry` command that uses `scripts/telemetry.js`, automates the entire process of setting up a local and GCP telemetry pipelines, including configuring the necessary settings in the `.gemini/settings.json` workspace file and installing required binaries (e.g. `otelcol-contrib`).
---
```shell
$ npm run telemetry -- --target=gcp
> gemini-cli@0.1.0 telemetry
> node scripts/telemetry.js --target=gcp
⚙️ Using command-line target: gcp
🚀 Running telemetry script for target: gcp.
✨ Starting Local Telemetry Exporter for Google Cloud ✨
⚙️ Enabled telemetry in workspace settings.
🔧 Set telemetry OTLP endpoint to http://localhost:4317.
🎯 Set telemetry target to gcp.
✅ Workspace settings updated.
✅ Using Google Cloud Project ID: foo-bar
🔑 Please ensure you are authenticated with Google Cloud:
- Run `gcloud auth application-default login` OR ensure `GOOGLE_APPLICATION_CREDENTIALS` environment variable points to a valid service account key.
- The account needs "Cloud Trace Agent", "Monitoring Metric Writer", and "Logs Writer" roles.
✅ otelcol-contrib already exists at /Users/jerop/github/gemini-cli/.gemini/otel/bin/otelcol-contrib
🧹 Cleaning up old processes and logs...
✅ Deleted old GCP collector log.
📄 Wrote OTEL collector config to /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.yaml
🚀 Starting OTEL collector for GCP... Logs: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
⏳ Waiting for OTEL collector to start (PID: 17013)...
✅ OTEL collector started successfully on port 4317.
✨ Local OTEL collector for GCP is running.
🚀 To send telemetry, run the Gemini CLI in a separate terminal window.
📄 Collector logs are being written to: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
📊 View your telemetry data in Google Cloud Console:
- Logs: https://console.cloud.google.com/logs/query;query=logName%3D%22projects%2Ffoo-bar%2Flogs%2Fgemini_cli%22?project=foo-bar
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer?project=foo-bar
- Traces: https://console.cloud.google.com/traces/list?project=foo-bar
Press Ctrl+C to exit.
^C
👋 Shutting down...
⚙️ Disabled telemetry in workspace settings.
🔧 Cleared telemetry OTLP endpoint.
🎯 Cleared telemetry target.
✅ Workspace settings updated.
🛑 Stopping otelcol-contrib (PID: 17013)...
✅ otelcol-contrib stopped.
```
2025-06-15 00:47:32 -04:00
` - Logs: https://console.cloud.google.com/logs/query;query=logName%3D%22projects%2F ${ projectId } %2Flogs%2Fgemini_cli%22?project= ${ projectId } ` ,
2025-06-13 20:28:18 -07:00
) ;
console . log (
` - Metrics: https://console.cloud.google.com/monitoring/metrics-explorer?project= ${ projectId } ` ,
) ;
console . log (
Add telemetry command and refactor telemetry settings (#1060)
#750
### Telemetry Settings
Refactors telemetry configuration to use a nested `telemetry` object in `settings.json`, for example:
```json
{
"telemetry": {
"enabled": true,
"target": "gcp"
"log-prompts": "true"
},
"sandbox": false
}
```
The above includes
- Centralized telemetry settings under a `telemetry` object in `settings.json`.
- CLI flags for the `gemini` command to override all telemetry sub-settings:
- `--telemetry` / `--no-telemetry`
- `--telemetry-target <local|gcp>`
- `--telemetry-otlp-endpoint <URL>`
- `--telemetry-log-prompts` / `--no-telemetry-log-prompts`
- Updates `packages/cli/src/config/config.ts` and `packages/core/src/config/config.ts` to read from the new settings structure and respect the new CLI flags.
- Modifies `scripts/handle-telemetry.js`, `scripts/local_telemetry.js`, and `scripts/telemetry_utils.js` to align with the new settings structure.
- Updates `docs/core/telemetry.md` to reflect the new settings structure, CLI flags, and order of precedence.
- Renames `logUserPromptsEnabled` to `logPrompts` for brevity.
### `npm run telemetry`
Add a new `npm run telemetry` command that uses `scripts/telemetry.js`, automates the entire process of setting up a local and GCP telemetry pipelines, including configuring the necessary settings in the `.gemini/settings.json` workspace file and installing required binaries (e.g. `otelcol-contrib`).
---
```shell
$ npm run telemetry -- --target=gcp
> gemini-cli@0.1.0 telemetry
> node scripts/telemetry.js --target=gcp
⚙️ Using command-line target: gcp
🚀 Running telemetry script for target: gcp.
✨ Starting Local Telemetry Exporter for Google Cloud ✨
⚙️ Enabled telemetry in workspace settings.
🔧 Set telemetry OTLP endpoint to http://localhost:4317.
🎯 Set telemetry target to gcp.
✅ Workspace settings updated.
✅ Using Google Cloud Project ID: foo-bar
🔑 Please ensure you are authenticated with Google Cloud:
- Run `gcloud auth application-default login` OR ensure `GOOGLE_APPLICATION_CREDENTIALS` environment variable points to a valid service account key.
- The account needs "Cloud Trace Agent", "Monitoring Metric Writer", and "Logs Writer" roles.
✅ otelcol-contrib already exists at /Users/jerop/github/gemini-cli/.gemini/otel/bin/otelcol-contrib
🧹 Cleaning up old processes and logs...
✅ Deleted old GCP collector log.
📄 Wrote OTEL collector config to /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.yaml
🚀 Starting OTEL collector for GCP... Logs: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
⏳ Waiting for OTEL collector to start (PID: 17013)...
✅ OTEL collector started successfully on port 4317.
✨ Local OTEL collector for GCP is running.
🚀 To send telemetry, run the Gemini CLI in a separate terminal window.
📄 Collector logs are being written to: /Users/jerop/github/gemini-cli/.gemini/otel/collector-gcp.log
📊 View your telemetry data in Google Cloud Console:
- Logs: https://console.cloud.google.com/logs/query;query=logName%3D%22projects%2Ffoo-bar%2Flogs%2Fgemini_cli%22?project=foo-bar
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer?project=foo-bar
- Traces: https://console.cloud.google.com/traces/list?project=foo-bar
Press Ctrl+C to exit.
^C
👋 Shutting down...
⚙️ Disabled telemetry in workspace settings.
🔧 Cleared telemetry OTLP endpoint.
🎯 Cleared telemetry target.
✅ Workspace settings updated.
🛑 Stopping otelcol-contrib (PID: 17013)...
✅ otelcol-contrib stopped.
```
2025-06-15 00:47:32 -04:00
` - Traces: https://console.cloud.google.com/traces/list?project= ${ projectId } ` ,
2025-06-13 20:28:18 -07:00
) ;
console . log ( ` \n Press Ctrl+C to exit. ` ) ;
}
main ( ) ;