Skip to content

[LFXV2-1043] Add comprehensive debug logging to ITX proxy client#113

Open
andrest50 wants to merge 3 commits intomainfrom
andrest50/proxy-debug-logging
Open

[LFXV2-1043] Add comprehensive debug logging to ITX proxy client#113
andrest50 wants to merge 3 commits intomainfrom
andrest50/proxy-debug-logging

Conversation

@andrest50
Copy link
Contributor

@andrest50 andrest50 commented Feb 19, 2026

Summary

This PR adds comprehensive debug logging to the ITX proxy client to enable troubleshooting of 404 errors and other API issues. All 28 ITX proxy client methods now have complete request/response logging with appropriate log levels.

Ticket

LFXV2-1043

Changes

Debug Logging Implementation

  • Added logRequest() helper: Logs outgoing HTTP requests at DEBUG level

    • Captures method, URL, and request body
    • Called before every HTTP request execution
  • Added logResponse() helper: Logs incoming HTTP responses with intelligent log levels

    • Uses DEBUG level for successful responses (2xx status codes)
    • Uses ERROR level for failed responses (non-2xx status codes)
    • Captures status code and response body for all responses
  • Applied logging to all 28 client methods:

    • Meeting operations (4 methods)
    • Registrant operations (6 methods)
    • Past meeting operations (5 methods)
    • Past meeting summary operations (2 methods)
    • Past meeting invitee operations (3 methods)
    • Past meeting attendee operations (3 methods)
    • Occurrence operations (2 methods)
    • Utility operations (3 methods)

Bug Fixes

  • Fixed CreateInvitee: Changed HTTP method from PUT to POST (create operations use POST)
  • Fixed UpdateInvitee: Changed HTTP method from DELETE to PUT (update operations use PUT)
  • Strip trailing slash from base URL: Prevents double slashes in URL construction (e.g., //v2/zoom/meetings)

Testing

Manual Verification

  • Ran comprehensive Python verification script to validate all 28 methods
  • Confirmed all methods have both logRequest and logResponse calls
  • Verified correct HTTP methods for each operation type

Linting

  • Passed make lint with 0 issues

Example Log Output

With LOG_LEVEL=debug, ITX proxy requests will now produce logs like:

Successful Request:

[DEBUG] ITX API Request method=GET url=https://api.itx.linuxfoundation.org/v2/zoom/meetings/12345 body=
[DEBUG] ITX API Response status_code=200 body={"id":"12345","title":"Team Meeting",...}

Failed Request:

[DEBUG] ITX API Request method=GET url=https://api.itx.linuxfoundation.org/v2/zoom/meetings/99999 body=
[ERROR] ITX API Response Error status_code=404 body={"code":3001,"message":"Meeting 99999 is not found or has expired."}

How to Enable Debug Logging

Local Development

# Option 1: Environment variable
export LOG_LEVEL=debug
make run

# Option 2: Use debug make target
make debug

Kubernetes Deployment

env:
  - name: LOG_LEVEL
    value: "debug"

Impact

  • Zero breaking changes: All changes are additive logging calls
  • Performance: Minimal overhead from logging (string operations only occur when debug is enabled)
  • Debugging: Full visibility into ITX API communication for troubleshooting 404s and other errors

🤖 Generated with Claude Code

- Add logRequest() helper to log outgoing HTTP requests at DEBUG level
- Add logResponse() helper to log responses at DEBUG/ERROR level based on status code
- Add logging to all 28 ITX proxy client methods for request/response visibility
- Fix HTTP method in CreateInvitee from PUT to POST
- Fix HTTP method in UpdateInvitee from DELETE to PUT
- Capture method, URL, request body, status code, and response body in logs
- Enable troubleshooting of 404 errors and other API issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Signed-off-by: Andres Tobon <andrest2455@gmail.com>
- Add strings.TrimRight() in NewClient to strip trailing slash from config.BaseURL
- Prevents double slash issues like "https://api.example.com//v2/zoom/meetings"
- All URL constructions use fmt.Sprintf with hardcoded "/" prefix in paths
- Ensures consistent URL parsing regardless of base URL configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Signed-off-by: Andres Tobon <andrest2455@gmail.com>
…g-service into andrest50/proxy-debug-logging
@andrest50 andrest50 requested a review from a team as a code owner February 19, 2026 01:44
Copilot AI review requested due to automatic review settings February 19, 2026 01:44
@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

Chart version incremented from 0.6.3 to 0.6.4 in Helm chart configuration. Logging infrastructure added to ITX proxy client with request/response debug helpers using slog, applied across Zoom meeting, registrant, attendee, and invite operations. Minor URL normalization implemented via trailing slash trimming.

Changes

Cohort / File(s) Summary
Helm Chart Version
charts/lfx-v2-meeting-service/Chart.yaml
Version bump from 0.6.3 to 0.6.4; appVersion remains "latest".
ITX Proxy Client Logging
internal/infrastructure/proxy/client.go
Added logRequest and logResponse debug logging helpers using slog; applied logging around all ITX proxy operations (Create/Get/Delete/Update for Zoom meetings, registrants, attendees, invites, past meetings, summaries, occurrences). Includes conditional error logging for non-2xx responses. Trailing slash trimmed from base URL to prevent double slashes. Added log/slog and strings imports.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~20 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch andrest50/proxy-debug-logging

Comment @coderabbitai help to get the list of available commands and usage tips.

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 adds request/response debug logging throughout the ITX proxy client to improve troubleshooting of ITX API failures (notably 404s), while also correcting a couple of invitee HTTP methods and hardening base URL construction.

Changes:

  • Added logRequest() / logResponse() helpers and applied them across ITX proxy client methods for consistent request/response logging.
  • Fixed HTTP verbs for invitee operations (Create -> POST, Update -> PUT).
  • Normalized BaseURL by stripping trailing slashes to avoid // in constructed URLs.

Reviewed changes

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

File Description
internal/infrastructure/proxy/client.go Adds request/response logging helpers, applies logging to ITX client methods, fixes invitee HTTP methods, trims trailing slash from base URL.
charts/lfx-v2-meeting-service/Chart.yaml Bumps chart version to reflect the change set.

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

Comment on lines +138 to +141
slog.ErrorContext(ctx, "ITX API Response Error",
"status_code", statusCode,
"body", string(body),
)
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

logResponse logs the entire response body at ERROR level for any non-2xx response. This can leak sensitive data into high-severity logs and can also create very noisy ERROR logs for expected 4xx responses. Consider logging only status code + a bounded/redacted excerpt (or parsed message field), and/or using WARN for 4xx while reserving ERROR for 5xx/transport failures.

Suggested change
slog.ErrorContext(ctx, "ITX API Response Error",
"status_code", statusCode,
"body", string(body),
)
// For non-2xx responses, avoid logging the full body to reduce the risk of
// leaking sensitive data. Log only a bounded excerpt and adjust log level
// so that 4xx client errors are WARN while 5xx/server errors remain ERROR.
const maxLogBodyLen = 512
logBody := string(body)
if len(logBody) > maxLogBodyLen {
logBody = logBody[:maxLogBodyLen]
}
if statusCode >= 400 && statusCode < 500 {
slog.WarnContext(ctx, "ITX API Response Client Error",
"status_code", statusCode,
"body_excerpt", logBody,
)
} else {
slog.ErrorContext(ctx, "ITX API Response Error",
"status_code", statusCode,
"body_excerpt", logBody,
)
}

Copilot uses AI. Check for mistakes.
Comment on lines +427 to +428
// Log request
c.logRequest(ctx, http.MethodGet, queryURL, nil)
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

This request log includes queryURL which can contain PII in query parameters (e.g., email, name, user_id). Consider logging only the path (or a sanitized URL with sensitive query params removed/hashed) to avoid leaking personal data when debug logging is enabled.

Suggested change
// Log request
c.logRequest(ctx, http.MethodGet, queryURL, nil)
// Log request (sanitize URL to avoid logging query parameters that may contain PII)
if parsedURL, err := url.Parse(queryURL); err == nil {
parsedURL.RawQuery = ""
c.logRequest(ctx, http.MethodGet, parsedURL.String(), nil)
} else {
// Fallback: log original URL if parsing fails to avoid changing behavior in edge cases
c.logRequest(ctx, http.MethodGet, queryURL, nil)
}

Copilot uses AI. Check for mistakes.
Comment on lines +685 to +686
// Log response
c.logResponse(ctx, resp.StatusCode, respBody)
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

GetRegistrantICS returns the response body as binary/ICS content, but logResponse will log the entire body. This can be large and may contain personal details, and dumping it to logs can bloat log volume and break log ingestion. Consider skipping body logging for this endpoint (or logging only content length / a small capped prefix).

Suggested change
// Log response
c.logResponse(ctx, resp.StatusCode, respBody)
// Log response metadata only to avoid logging potentially large or sensitive ICS content
slog.Info("GetRegistrantICS response", "status", resp.StatusCode, "content_length", len(respBody))

Copilot uses AI. Check for mistakes.
Comment on lines +126 to +145
// logRequest logs the outgoing HTTP request for debugging
func (c *Client) logRequest(ctx context.Context, method, url string, body []byte) {
slog.DebugContext(ctx, "ITX API Request",
"method", method,
"url", url,
"body", string(body),
)
}

// logResponse logs the incoming HTTP response for debugging
func (c *Client) logResponse(ctx context.Context, statusCode int, body []byte) {
if statusCode < 200 || statusCode >= 300 {
slog.ErrorContext(ctx, "ITX API Response Error",
"status_code", statusCode,
"body", string(body),
)
} else {
slog.DebugContext(ctx, "ITX API Response",
"status_code", statusCode,
"body", string(body),
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

logRequest logs the full request body by converting []byte to string. These requests can contain PII (e.g., names/emails) and this also allocates even when DEBUG logging is disabled (args are evaluated before slog.DebugContext checks the level). Consider gating with slog.Default().Enabled(ctx, slog.LevelDebug) and logging a redacted/truncated body (or just size/hash) to avoid leaking sensitive data and unnecessary allocations.

Suggested change
// logRequest logs the outgoing HTTP request for debugging
func (c *Client) logRequest(ctx context.Context, method, url string, body []byte) {
slog.DebugContext(ctx, "ITX API Request",
"method", method,
"url", url,
"body", string(body),
)
}
// logResponse logs the incoming HTTP response for debugging
func (c *Client) logResponse(ctx context.Context, statusCode int, body []byte) {
if statusCode < 200 || statusCode >= 300 {
slog.ErrorContext(ctx, "ITX API Response Error",
"status_code", statusCode,
"body", string(body),
)
} else {
slog.DebugContext(ctx, "ITX API Response",
"status_code", statusCode,
"body", string(body),
const maxLogBodyLen = 1024
// truncateBodyForLog returns a string representation of the body truncated to a safe length for logging.
func truncateBodyForLog(body []byte) string {
if len(body) == 0 {
return ""
}
if len(body) <= maxLogBodyLen {
return string(body)
}
return string(body[:maxLogBodyLen]) + "...(truncated)"
}
// logRequest logs the outgoing HTTP request for debugging
func (c *Client) logRequest(ctx context.Context, method, url string, body []byte) {
logger := slog.Default()
if !logger.Enabled(ctx, slog.LevelDebug) {
return
}
logger.DebugContext(ctx, "ITX API Request",
"method", method,
"url", url,
"body", truncateBodyForLog(body),
)
}
// logResponse logs the incoming HTTP response for debugging
func (c *Client) logResponse(ctx context.Context, statusCode int, body []byte) {
truncatedBody := truncateBodyForLog(body)
if statusCode < 200 || statusCode >= 300 {
slog.ErrorContext(ctx, "ITX API Response Error",
"status_code", statusCode,
"body", truncatedBody,
)
} else {
slog.DebugContext(ctx, "ITX API Response",
"status_code", statusCode,
"body", truncatedBody,

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