Skip to content

[log] Add debug logging to GraphQL owner/repo and search query extraction#3308

Merged
lpcox merged 2 commits intomainfrom
log/proxy-graphql-debug-logging-77a3505da40cdd08
Apr 7, 2026
Merged

[log] Add debug logging to GraphQL owner/repo and search query extraction#3308
lpcox merged 2 commits intomainfrom
log/proxy-graphql-debug-logging-77a3505da40cdd08

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Apr 7, 2026

Adds 5 targeted logGraphQL debug log calls to the helper functions in internal/proxy/graphql.go that extract owner, repo, and search query values from GraphQL requests.

Changes

File: internal/proxy/graphql.go (1 file, 5 insertions)

extractOwnerRepo

This function tries three extraction strategies in order: request variables → query regex → raw JSON in query text. The new log calls make each step observable:

  • Log values found in the request variables map (e.g. owner=%q repo=%q)
  • Log values extracted via the queryRepoPattern regex fallback

extractSearchQuery

  • Log the search query string when found in request variables
  • Log the search query string when found inline in the query text (truncated to 80 chars)
  • Log when no search query is found at all (useful for debugging why guard scope determination fails)

Why this helps

When debugging why a GraphQL request ends up with incorrect or missing owner/repo labels (e.g. the guard applies the wrong policy), operators can enable DEBUG=proxy:graphql to see exactly which code path populated each field. Without these logs, the extraction is a black box.

Checklist

  • Exactly 1 file modified
  • No test files modified
  • Reuses existing logGraphQL logger (no new declaration needed)
  • Logger naming follows pkg:filename convention (proxy:graphql)
  • Log arguments are plain already-computed values — no side effects
  • Messages are meaningful and aid debugging
  • No duplication with existing logs (existing logs cover MatchGraphQL entry/exit; new logs cover internal extraction steps)
  • Import statements unchanged (logger already imported)

Generated by Go Logger Enhancement · ● 12.3M ·

Add logGraphQL calls to the extractOwnerRepo and extractSearchQuery
helper functions in internal/proxy/graphql.go to make the multi-step
extraction process observable during debugging.

- extractOwnerRepo: log values found in request variables
- extractOwnerRepo: log values extracted via query regex fallback
- extractSearchQuery: log search query found in variables
- extractSearchQuery: log search query found inline in the query text
- extractSearchQuery: log when no search query is found

These logs activate only when DEBUG=proxy:graphql (or DEBUG=*) is set,
adding zero overhead in production while enabling precise tracing of why
a particular GraphQL request ends up with a specific owner/repo/query label.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions bot added automation enhancement New feature or request labels Apr 7, 2026
@lpcox lpcox marked this pull request as ready for review April 7, 2026 18:45
Copilot AI review requested due to automatic review settings April 7, 2026 18:45
Copy link
Copy Markdown
Contributor

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

Adds additional debug-level observability to GraphQL parsing in the proxy layer so operators can see how owner/repo and search query scope are derived when DEBUG=proxy:graphql is enabled.

Changes:

  • Add debug logs in extractOwnerRepo when values are sourced from request variables and from the query regex fallback.
  • Add debug logs in extractSearchQuery when the search query is found (variables or inline) and when no query is found.
Show a summary per file
File Description
internal/proxy/graphql.go Adds targeted logGraphQL debug statements for owner/repo and search query extraction paths.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (1)

internal/proxy/graphql.go:205

  • Same concern for the inline match: logging the raw captured string without quoting can allow newlines/control characters to spill into logs. Prefer logging an escaped/quoted, truncated representation for safer/cleaner debug output.
	if m := searchQueryArgPattern.FindStringSubmatch(query); m != nil {
		logGraphQL.Printf("extractSearchQuery: found inline: %.80s", m[1])
		return m[1]
  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment on lines 197 to 199
if v, ok := variables["query"].(string); ok && v != "" {
logGraphQL.Printf("extractSearchQuery: found in variables: %.80s", v)
return v
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

The search query value is user-controlled and may contain newlines/control characters; logging it with %s can create multi-line or hard-to-parse debug output. Consider quoting/escaping the truncated value (e.g., using a quoted format verb) to keep logs single-line and unambiguous.

This issue also appears on line 203 of the same file.

See below for a potential fix:

func truncateForLog(s string, maxRunes int) string {
	if maxRunes <= 0 {
		return ""
	}
	r := []rune(s)
	if len(r) <= maxRunes {
		return s
	}
	return string(r[:maxRunes])
}

// extractSearchQuery returns the search query argument from a GraphQL search
// query. It checks variables ($query) first, then inline query text.
func extractSearchQuery(query string, variables map[string]interface{}) string {
	// Check variables for $query
	if variables != nil {
		if v, ok := variables["query"].(string); ok && v != "" {
			logGraphQL.Printf("extractSearchQuery: found in variables: %q", truncateForLog(v, 80))
			return v
		}
	}
	// Parse inline: search(query:"repo:owner/name is:issue", ...)
	if m := searchQueryArgPattern.FindStringSubmatch(query); m != nil {
		logGraphQL.Printf("extractSearchQuery: found inline: %q", truncateForLog(m[1], 80))

Copilot uses AI. Check for mistakes.
@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented Apr 7, 2026

@copilot apply changes based on the comments in this thread

@github github deleted a comment from rdevps Apr 7, 2026
…lled search query values

Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/985634c1-dde7-42d6-b1bb-258bd55d1f76

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 7, 2026

@copilot apply changes based on the comments in this thread

Done in 108772e. Added a truncateForLog(s string, maxRunes int) string helper and switched both extractSearchQuery log calls from %.80s to %q with truncateForLog(v, 80) / truncateForLog(m[1], 80). This ensures any newlines or control characters in user-controlled search query values are escaped, keeping debug output single-line and unambiguous.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build2538321610/b514/launcher.test /tmp/go-build2538321610/b514/launcher.test -test.testlogfile=/tmp/go-build2538321610/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build2538321610/b508/_pkg_.a .cfg 4624775/b286/ x_amd64/vet . --gdwarf2 (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build2538321610/b496/config.test /tmp/go-build2538321610/b496/config.test -test.testlogfile=/tmp/go-build2538321610/b496/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build2538321610/b394/vet.cfg hema-go@v0.4.2/jgo1.25.8 hema-go@v0.4.2/j-c=4 x_amd64/vet --gdwarf-5 nal/encoding/tag-atomic -o x_amd64/vet --de�� g_.a --debug-prefix-m-ifaceassert x_amd64/vet -I /opt/hostedtoolc-atomic -I x_amd64/vet (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build2538321610/b514/launcher.test /tmp/go-build2538321610/b514/launcher.test -test.testlogfile=/tmp/go-build2538321610/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build2538321610/b508/_pkg_.a .cfg 4624775/b286/ x_amd64/vet . --gdwarf2 (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build2538321610/b514/launcher.test /tmp/go-build2538321610/b514/launcher.test -test.testlogfile=/tmp/go-build2538321610/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build2538321610/b508/_pkg_.a .cfg 4624775/b286/ x_amd64/vet . --gdwarf2 (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build2538321610/b523/mcp.test /tmp/go-build2538321610/b523/mcp.test -test.testlogfile=/tmp/go-build2538321610/b523/testlog.txt -test.paniconexit0 -test.timeout=10m0s .cfg�� om/modelcontextprotocol/go-sdk@v1.4.1/jsonrpc/jsonrpc.go -I x_amd64/vet --gdwarf-5 b/gh-aw-mcpg/int/usr/bin/runc -o x_amd64/vet .cfg�� 4624775/b465/_pkg_.a /tmp/go-build2604624775/b286/ x_amd64/vet . /cobra --64 x_amd64/vet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from lpcox April 7, 2026 18:53
Copilot finished work on behalf of lpcox April 7, 2026 18:53
@lpcox lpcox merged commit 6d11c31 into main Apr 7, 2026
6 checks passed
@lpcox lpcox deleted the log/proxy-graphql-debug-logging-77a3505da40cdd08 branch April 7, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants