Gemini CLI
Send Google Gemini CLI telemetry — traces, metrics, and logs — to Last9 via OpenTelemetry.
Gemini CLI is Google’s open-source AI coding agent for the terminal. It emits structured OpenTelemetry data for every session: user prompts, tool calls, model API requests, agent runs, file operations, and token usage. Routing this to Last9 lets you measure adoption, model latency, cost, and tool reliability — within your existing observability stack.
Gemini CLI exports all three OpenTelemetry signal types:
- Traces — spans for tool dispatch, API requests, agent runs (enable with
GEMINI_TELEMETRY_TRACES_ENABLED=true) - Metrics — counters and histograms across session, tool, API, token, file, agent, and process domains
- Logs — structured events for prompts, API requests/responses, slash commands, file operations
What gets exported
Metrics
| Metric | Type | Description |
|---|---|---|
gemini_cli.session.count | counter | Sessions started |
gemini_cli.tool.call.count | counter | Tool invocations |
gemini_cli.tool.call.latency | histogram | Tool latency (ms) |
gemini_cli.api.request.count | counter | Model API calls |
gemini_cli.api.request.latency | histogram | Model API latency (ms) |
gemini_cli.token.usage | counter | Tokens used (in/out/cached) |
gemini_cli.file.operation.count | counter | File ops (read/write/edit) |
gemini_cli.lines.changed | counter | Lines added/removed |
gemini_cli.agent.run.count | counter | Sub-agent invocations |
gemini_cli.agent.duration | histogram | Sub-agent duration |
gemini_cli.startup.duration | histogram | CLI startup time |
gemini_cli.memory.usage | gauge | Process memory |
gemini_cli.cpu.usage | gauge | Process CPU |
gen_ai.client.token.usage | counter | GenAI semconv |
gen_ai.client.operation.duration | histogram | GenAI semconv |
Log events
gemini_cli.config, gemini_cli.user_prompt, gemini_cli.tool_call, gemini_cli.api_request, gemini_cli.api_response, gemini_cli.api_error, gemini_cli.slash_command, gemini_cli.chat_compression, gemini_cli.conversation_finished, gemini_cli.agent.start, gemini_cli.agent.finish, gemini_cli.model_routing, gemini_cli.file_operation, gen_ai.client.inference.operation.details
Spans
llm_call (with gen_ai.request.model, gen_ai.operation.name, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, gen_ai.conversation.id)
Prerequisites
- Last9 account — Sign up at app.last9.io
- Gemini CLI installed —
npm install -g @google/gemini-cli - OTLP credentials — Get your endpoint and auth header from Integrations → OpenTelemetry
Setup
Gemini CLI uses GEMINI_TELEMETRY_* env vars for the endpoint configuration, but the underlying OpenTelemetry JS SDK reads standard OTEL_EXPORTER_OTLP_HEADERS for authentication headers — so direct export to Last9 works.
-
Get your Last9 OTLP credentials
Navigate to Integrations → OpenTelemetry. Copy:
- OTLP Endpoint (e.g.,
https://otlp.last9.ioorhttps://otlp-aps1.last9.io:443) - Authorization header value (e.g.,
Basic <base64-token>)
- OTLP Endpoint (e.g.,
-
Add environment variables to your shell profile
Add the following to
~/.zshrc,~/.bashrc, or equivalent:# Gemini CLI telemetry switchesexport GEMINI_TELEMETRY_ENABLED=trueexport GEMINI_TELEMETRY_TARGET=localexport GEMINI_TELEMETRY_OTLP_ENDPOINT="https://<your-last9-otlp-endpoint>"export GEMINI_TELEMETRY_OTLP_PROTOCOL=httpexport GEMINI_TELEMETRY_TRACES_ENABLED=true# Standard OTel env — picked up by the SDK for auth headersexport OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic <your-last9-auth-token>" -
Reload your shell
source ~/.zshrc -
Run Gemini CLI
gemini -p "explain this repo" -
Verify data is arriving
- Traces — open Traces in Last9, filter by
service.name = gemini-cli. Spanllm_callshould appear. - Metrics — open Metrics, search for
gemini_cli_session_count_total,gemini_cli_api_request_count_total, orgemini_cli_token_usage_total - Logs — open Logs, filter by
service.name = gemini-cli. Look forgemini_cli.user_prompt,gemini_cli.api_request.
- Traces — open Traces in Last9, filter by
Configuration reference
Gemini CLI-specific env vars
| Variable | Default | Description |
|---|---|---|
GEMINI_TELEMETRY_ENABLED | false | Master toggle |
GEMINI_TELEMETRY_TARGET | local | local (OTLP) or gcp (Google Cloud) |
GEMINI_TELEMETRY_OTLP_ENDPOINT | http://localhost:4317 | OTLP endpoint (base URL — /v1/traces etc. appended) |
GEMINI_TELEMETRY_OTLP_PROTOCOL | grpc | grpc or http |
GEMINI_TELEMETRY_TRACES_ENABLED | false | Opt-in span export |
GEMINI_TELEMETRY_LOG_PROMPTS | true | Include prompt text in logs |
Standard OTel env vars (used for auth headers)
| Variable | Purpose |
|---|---|
OTEL_EXPORTER_OTLP_HEADERS | key=value comma-separated auth headers. Use Authorization=Basic <token> |
OTEL_EXPORTER_OTLP_TRACES_HEADERS | Traces-only override |
OTEL_EXPORTER_OTLP_METRICS_HEADERS | Metrics-only override |
OTEL_EXPORTER_OTLP_LOGS_HEADERS | Logs-only override |
Configure via ~/.gemini/settings.json instead of env if you prefer:
{ "telemetry": { "enabled": true, "target": "local", "otlpEndpoint": "https://<your-last9-otlp-endpoint>", "otlpProtocol": "http", "traces": true, "logPrompts": true }}Environment variables still need to provide OTEL_EXPORTER_OTLP_HEADERS for auth — the Gemini CLI settings file doesn’t have an OTLP headers field.
Local Collector (optional)
If you want batching, retries, fan-out to multiple backends, or to inject auth headers without modifying user shells, run a local OTel Collector:
docker run -d \ --name gemini-cli-otel-collector \ -e LAST9_OTLP_ENDPOINT="https://<your-last9-otlp-endpoint>" \ -e LAST9_OTLP_AUTH="Basic <your-last9-auth-token>" \ -p 4317:4317 -p 4318:4318 \ -v "$(pwd)/otel-collector-config.yaml:/etc/otel/config.yaml:ro" \ otel/opentelemetry-collector-contrib:0.144.0 \ --config=/etc/otel/config.yamlThen point Gemini CLI at the collector:
export GEMINI_TELEMETRY_OTLP_ENDPOINT=http://localhost:4317export GEMINI_TELEMETRY_OTLP_PROTOCOL=grpcunset OTEL_EXPORTER_OTLP_HEADERS # collector handles authSee the reference example for a complete collector config.
Troubleshooting
- No data in Last9 — confirm
echo $GEMINI_TELEMETRY_ENABLEDreturnstruein the shell that rangemini. Restart shell after editing~/.zshrc. - Authentication errors — verify
OTEL_EXPORTER_OTLP_HEADERSisAuthorization=Basic <token>(note the=, not HTTP colon syntax). - Traces missing — set
GEMINI_TELEMETRY_TRACES_ENABLED=true. Span export is opt-in. - Metric names — Gemini CLI metrics use dots in source (
gemini_cli.session.count) but appear in Last9 with underscores (gemini_cli_session_count_total).
Please get in touch with us on Discord or Email if you have any questions.