Skip to content

Commit 8a30099

Browse files
authored
Switch to local telemetry and upload manually to GCP (#361)
Resolves #360
1 parent a4d0af1 commit 8a30099

File tree

8 files changed

+137
-59
lines changed

8 files changed

+137
-59
lines changed

.github/workflows/gemini-invoke.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,16 @@ jobs:
6161
google_api_key: '${{ secrets.GOOGLE_API_KEY }}'
6262
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
6363
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
64+
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
6465
settings: |-
6566
{
6667
"model": {
6768
"maxSessionTurns": 25
6869
},
6970
"telemetry": {
70-
"enabled": ${{ vars.GOOGLE_CLOUD_PROJECT != '' }},
71-
"target": "gcp"
71+
"enabled": true,
72+
"target": "local",
73+
"outfile": ".gemini/telemetry.log"
7274
},
7375
"mcpServers": {
7476
"github": {

.github/workflows/gemini-issue-fixer.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ jobs:
6262
google_api_key: '${{ secrets.GOOGLE_API_KEY }}'
6363
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
6464
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
65+
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
6566
settings: |-
6667
{
6768
"debug": ${{ fromJSON(env.DEBUG || env.ACTIONS_STEP_DEBUG || false) }},
@@ -85,8 +86,9 @@ jobs:
8586
}
8687
},
8788
"telemetry": {
88-
"enabled": ${{ vars.GOOGLE_CLOUD_PROJECT != '' }},
89-
"target": "gcp"
89+
"enabled": true,
90+
"target": "local",
91+
"outfile": ".gemini/telemetry.log"
9092
}
9193
}
9294
prompt: '/gemini-issue-fixer'

.github/workflows/gemini-review.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,16 @@ jobs:
6363
google_api_key: '${{ secrets.GOOGLE_API_KEY }}'
6464
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
6565
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
66+
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
6667
settings: |-
6768
{
6869
"model": {
6970
"maxSessionTurns": 25
7071
},
7172
"telemetry": {
72-
"enabled": ${{ vars.GOOGLE_CLOUD_PROJECT != '' }},
73-
"target": "gcp"
73+
"enabled": true,
74+
"target": "local",
75+
"outfile": ".gemini/telemetry.log"
7476
},
7577
"mcpServers": {
7678
"github": {

.github/workflows/gemini-scheduled-triage.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,16 @@ jobs:
103103
google_api_key: '${{ secrets.GOOGLE_API_KEY }}'
104104
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
105105
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
106+
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
106107
settings: |-
107108
{
108109
"model": {
109110
"maxSessionTurns": 25
110111
},
111112
"telemetry": {
112-
"enabled": ${{ vars.GOOGLE_CLOUD_PROJECT != '' }},
113-
"target": "gcp"
113+
"enabled": true,
114+
"target": "local",
115+
"outfile": ".gemini/telemetry.log"
114116
},
115117
"tools": {
116118
"core": [

.github/workflows/gemini-triage.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,16 @@ jobs:
7373
google_api_key: '${{ secrets.GOOGLE_API_KEY }}'
7474
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
7575
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
76+
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
7677
settings: |-
7778
{
7879
"model": {
7980
"maxSessionTurns": 25
8081
},
8182
"telemetry": {
82-
"enabled": ${{ vars.GOOGLE_CLOUD_PROJECT != '' }},
83-
"target": "gcp"
83+
"enabled": true,
84+
"target": "local",
85+
"outfile": ".gemini/telemetry.log"
8486
},
8587
"tools": {
8688
"core": [

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ go to the [Gemini Assistant workflow documentation](./examples/workflows/gemini-
183183

184184
- <a name="__input_extensions"></a><a href="#user-content-__input_extensions"><code>extensions</code></a>: _(Optional)_ A list of Gemini CLI extensions to install.
185185

186+
- <a name="__input_upload_artifacts"></a><a href="#user-content-__input_upload_artifacts"><code>upload_artifacts</code></a>: _(Optional, default: `false`)_ Whether or not to upload artifacts to the github action.
187+
186188

187189
<!-- END_AUTOGEN_INPUTS -->
188190

action.yml

Lines changed: 93 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ inputs:
7171
extensions:
7272
description: 'A list of Gemini CLI extensions to install.'
7373
required: false
74+
upload_artifacts:
75+
description: 'Whether or not to upload artifacts to the github action.'
76+
required: false
77+
default: 'false'
7478

7579
outputs:
7680
summary:
@@ -183,26 +187,6 @@ runs:
183187
token_format: 'access_token'
184188
access_token_scopes: 'https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile'
185189

186-
- name: 'Run Telemetry Collector for Google Cloud'
187-
if: |-
188-
${{ inputs.gcp_workload_identity_provider != '' }}
189-
env:
190-
OTLP_GOOGLE_CLOUD_PROJECT: '${{ inputs.gcp_project_id }}'
191-
GITHUB_ACTION_PATH: '${{ github.action_path }}'
192-
shell: 'bash'
193-
run: |-
194-
set -euo pipefail
195-
mkdir -p .gemini/
196-
sed "s/OTLP_GOOGLE_CLOUD_PROJECT/${OTLP_GOOGLE_CLOUD_PROJECT}/g" "${GITHUB_ACTION_PATH}/scripts/collector-gcp.yaml.template" > ".gemini/collector-gcp.yaml"
197-
198-
chmod 444 "$GOOGLE_APPLICATION_CREDENTIALS"
199-
docker run -d --name gemini-telemetry-collector --network host \
200-
-v "${GITHUB_WORKSPACE}:/github/workspace" \
201-
-e "GOOGLE_APPLICATION_CREDENTIALS=${GOOGLE_APPLICATION_CREDENTIALS/$GITHUB_WORKSPACE//github/workspace}" \
202-
-w "/github/workspace" \
203-
otel/opentelemetry-collector-contrib:0.128.0 \
204-
--config /github/workspace/.gemini/collector-gcp.yaml
205-
206190
- name: 'Install Gemini CLI'
207191
id: 'install'
208192
env:
@@ -274,22 +258,29 @@ runs:
274258
fi
275259
fi
276260
277-
GEMINI_RESPONSE="$(cat "${TEMP_STDOUT}")"
261+
# Create the artifacts directory and copy full logs
262+
mkdir -p gemini-artifacts
263+
cp "${TEMP_STDOUT}" gemini-artifacts/stdout.log
264+
cp "${TEMP_STDERR}" gemini-artifacts/stderr.log
265+
if [[ -f .gemini/telemetry.log ]]; then
266+
cp .gemini/telemetry.log gemini-artifacts/telemetry.log
267+
else
268+
# Create an empty file so the artifact upload doesn't fail if telemetry is missing
269+
touch gemini-artifacts/telemetry.log
270+
fi
278271
279272
# Set the captured response as a step output, supporting multiline
280273
echo "gemini_response<<EOF" >> "${GITHUB_OUTPUT}"
281-
echo "${GEMINI_RESPONSE}" >> "${GITHUB_OUTPUT}"
274+
cat "${TEMP_STDOUT}" >> "${GITHUB_OUTPUT}"
282275
echo "EOF" >> "${GITHUB_OUTPUT}"
283276
284-
GEMINI_ERRORS="$(cat "${TEMP_STDERR}")"
285-
286277
# Set the captured errors as a step output, supporting multiline
287278
echo "gemini_errors<<EOF" >> "${GITHUB_OUTPUT}"
288-
echo "${GEMINI_ERRORS}" >> "${GITHUB_OUTPUT}"
279+
cat "${TEMP_STDERR}" >> "${GITHUB_OUTPUT}"
289280
echo "EOF" >> "${GITHUB_OUTPUT}"
290281
291282
if [[ "${FAILED}" = true ]]; then
292-
LAST_LINE="$(echo "${GEMINI_ERRORS}" | tail -n1)"
283+
LAST_LINE="$(tail -n1 "${TEMP_STDERR}")"
293284
echo "::error title=Gemini CLI execution failed::${LAST_LINE}"
294285
echo "See logs for more details"
295286
exit 1
@@ -307,6 +298,82 @@ runs:
307298
PROMPT: '${{ inputs.prompt }}'
308299
GEMINI_MODEL: '${{ inputs.gemini_model }}'
309300

301+
- name: 'Upload Gemini CLI outputs'
302+
if: |-
303+
${{ inputs.upload_artifacts }}
304+
uses: 'actions/upload-artifact@v4' # ratchet:exclude
305+
with:
306+
name: 'gemini-output'
307+
path: 'gemini-artifacts/'
308+
309+
- name: 'Upload Telemetry to Google Cloud'
310+
if: |-
311+
${{ inputs.gcp_workload_identity_provider != '' }}
312+
shell: 'bash'
313+
run: |-
314+
set -euo pipefail
315+
316+
# If the telemetry log doesn't exist or is empty, do nothing.
317+
if [[ ! -s ".gemini/telemetry.log" ]]; then
318+
echo "No telemetry log found, skipping upload."
319+
exit 0
320+
fi
321+
322+
# Generate the real config file from the template
323+
sed -e "s#OTLP_GOOGLE_CLOUD_PROJECT#${OTLP_GOOGLE_CLOUD_PROJECT}#g" \
324+
-e "s#GITHUB_REPOSITORY_PLACEHOLDER#${GITHUB_REPOSITORY}#g" \
325+
-e "s#GITHUB_RUN_ID_PLACEHOLDER#${GITHUB_RUN_ID}#g" \
326+
"${GITHUB_ACTION_PATH}/scripts/collector-gcp.yaml.template" > ".gemini/collector-gcp.yaml"
327+
328+
# Ensure credentials file has the right permissions
329+
chmod 444 "$GOOGLE_APPLICATION_CREDENTIALS"
330+
331+
# Run the collector in the background with a known name
332+
docker run --rm --name gemini-telemetry-collector --network host \
333+
-v "${GITHUB_WORKSPACE}:/github/workspace" \
334+
-e "GOOGLE_APPLICATION_CREDENTIALS=${GOOGLE_APPLICATION_CREDENTIALS/$GITHUB_WORKSPACE//github/workspace}" \
335+
-w "/github/workspace" \
336+
otel/opentelemetry-collector-contrib:0.108.0 \
337+
--config /github/workspace/.gemini/collector-gcp.yaml &
338+
339+
# Wait for the collector to start up
340+
echo "Waiting for collector to initialize..."
341+
sleep 10
342+
343+
# Monitor the queue until it's empty or we time out
344+
echo "Monitoring exporter queue..."
345+
ATTEMPTS=0
346+
MAX_ATTEMPTS=12 # 12 * 5s = 60s timeout
347+
while true; do
348+
# Use -f to fail silently if the server isn't ready yet
349+
# Filter out the prometheus help/type comments before grabbing the value
350+
QUEUE_SIZE=$(curl -sf http://localhost:8888/metrics | grep otelcol_exporter_queue_size | grep -v '^#' | awk '{print $2}' || echo "-1")
351+
352+
if [ "$QUEUE_SIZE" == "0" ]; then
353+
echo "Exporter queue is empty, all data processed."
354+
break
355+
fi
356+
357+
if [ "$ATTEMPTS" -ge "$MAX_ATTEMPTS" ]; then
358+
echo "::warning::Timed out waiting for exporter queue to empty. Proceeding with shutdown."
359+
break
360+
fi
361+
362+
echo "Queue size: $QUEUE_SIZE, waiting..."
363+
sleep 5
364+
ATTEMPTS=$((ATTEMPTS + 1))
365+
done
366+
367+
# Gracefully shut down the collector
368+
echo "Stopping collector..."
369+
docker stop gemini-telemetry-collector
370+
echo "Collector stopped."
371+
env:
372+
OTLP_GOOGLE_CLOUD_PROJECT: '${{ inputs.gcp_project_id }}'
373+
GITHUB_ACTION_PATH: '${{ github.action_path }}'
374+
GITHUB_REPOSITORY: '${{ github.repository }}'
375+
GITHUB_RUN_ID: '${{ github.run_id }}'
376+
310377
branding:
311378
icon: 'terminal'
312379
color: 'blue'
Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,33 @@
11
receivers:
2-
otlp:
3-
protocols:
4-
grpc:
5-
endpoint: 'localhost:4317'
2+
filelog:
3+
include: ['.gemini/telemetry.log']
4+
start_at: 'beginning'
5+
66
processors:
7+
resource:
8+
attributes:
9+
- key: 'github.repository'
10+
value: 'GITHUB_REPOSITORY_PLACEHOLDER'
11+
action: 'upsert'
12+
- key: 'github.run_id'
13+
value: 'GITHUB_RUN_ID_PLACEHOLDER'
14+
action: 'upsert'
715
batch:
8-
timeout: '1s'
16+
send_batch_size: 100
17+
timeout: '10s'
18+
919
exporters:
1020
googlecloud:
1121
project: 'OTLP_GOOGLE_CLOUD_PROJECT'
12-
metric:
13-
prefix: 'custom.googleapis.com/gemini_cli'
1422
log:
15-
default_log_name: 'gemini_cli'
23+
default_log_name: 'gemini-cli'
24+
1625
service:
17-
telemetry:
18-
logs:
19-
level: 'debug'
20-
metrics:
21-
level: 'none'
2226
pipelines:
23-
traces:
24-
receivers: ['otlp']
25-
processors: ['batch']
26-
exporters: ['googlecloud']
27-
metrics:
28-
receivers: ['otlp']
29-
processors: ['batch']
30-
exporters: ['googlecloud']
3127
logs:
32-
receivers: ['otlp']
33-
processors: ['batch']
28+
receivers: ['filelog']
29+
processors: ['batch', 'resource']
3430
exporters: ['googlecloud']
31+
telemetry:
32+
metrics:
33+
address: '0.0.0.0:8888'

0 commit comments

Comments
 (0)