Skip to content

Improve Gemini Logging#188

Merged
sfreeman422 merged 2 commits intomasterfrom
feature/improve-gemini-logging
Mar 22, 2026
Merged

Improve Gemini Logging#188
sfreeman422 merged 2 commits intomasterfrom
feature/improve-gemini-logging

Conversation

@sfreeman422
Copy link
Collaborator

  • Improved gemini error logging
  • Changed .debug to .info

Copilot AI review requested due to automatic review settings March 22, 2026 15:21
@sfreeman422 sfreeman422 merged commit 91a1ee2 into master Mar 22, 2026
2 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to improve observability around Gemini image-generation responses in AIService, primarily by adding response-shape logging and guarding against missing/empty candidates/parts.

Changes:

  • Add Gemini response structure logging and explicit checks for missing candidates / parts before parsing image bytes.
  • Type Gemini parts iteration using Part from @google/genai.
  • Update AIService logger mock in tests to include debug.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
packages/backend/src/ai/ai.service.ts Adds Gemini response structure logging and defensive checks when extracting image data from Gemini responses.
packages/backend/src/ai/ai.service.spec.ts Extends the logger mock shape to include a debug method.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

firstCandidateKeys: response.candidates?.[0] ? Object.keys(response.candidates[0]) : null,
contentKeys: response.candidates?.[0]?.content ? Object.keys(response.candidates[0].content) : null,
partsLength: response.candidates?.[0]?.content?.parts?.length,
fullResponse: JSON.stringify(response, null, 2),
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging the full Gemini response at info level (including JSON.stringify(response)) will likely include the base64 image payload in inlineData.data. This can leak sensitive content into logs and can generate extremely large log lines. Prefer removing fullResponse, or redacting/truncating binary fields and logging only at debug level (or only when an error/unexpected structure occurs).

Suggested change
fullResponse: JSON.stringify(response, null, 2),

Copilot uses AI. Check for mistakes.
if (part.inlineData?.data) {
imageBytes = Buffer.concat([imageBytes, Buffer.from(part.inlineData.data, 'base64')]);
} else {
this.aiServiceLogger.info('Part does not have inlineData.data:', Object.keys(part));
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These info logs fire on every non-inline part encountered, which can become noisy in production and make it harder to spot real issues. Consider downgrading to debug and/or logging only once with a summary of part types when the response is unexpected.

Suggested change
this.aiServiceLogger.info('Part does not have inlineData.data:', Object.keys(part));
this.aiServiceLogger.debug('Part does not have inlineData.data:', Object.keys(part));

Copilot uses AI. Check for mistakes.
Comment on lines +241 to +245
this.aiServiceLogger.info('Gemini generateImage response structure:', {
hasCandidates: !!response.candidates,
candidatesLength: response.candidates?.length,
firstCandidateKeys: response.candidates?.[0] ? Object.keys(response.candidates[0]) : null,
contentKeys: response.candidates?.[0]?.content ? Object.keys(response.candidates[0].content) : null,
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Gemini generateImage response structure" message is logged at info for every image generation, which is likely to be high-volume and may bloat logs. Consider using debug, sampling, or logging this structure only when candidates/parts are missing (i.e., on the warning/error paths).

Copilot uses AI. Check for mistakes.
if (part.inlineData?.data) {
imageBytes = Buffer.concat([imageBytes, Buffer.from(part.inlineData.data, 'base64')]);
} else {
this.aiServiceLogger.info('GenerateImage part does not have inlineData.data:', Object.keys(part));
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This per-part info log in generateImage can be emitted many times and will add noise at scale. Consider moving it to debug and/or including more actionable context (e.g., part type) while avoiding high-cardinality logs.

Suggested change
this.aiServiceLogger.info('GenerateImage part does not have inlineData.data:', Object.keys(part));
this.aiServiceLogger.debug('GenerateImage part does not have inlineData.data:', Object.keys(part));

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants