Debugging gogcli API Requests with the Verbose Flag: A Complete Guide
Enable verbose logging in gogcli by passing the -v flag to set the internal logger to debug level, which exposes detailed API request metadata, retry attempts, and authentication flow information to stderr.
The steipete/gogcli tool provides a streamlined interface for interacting with Google APIs from the command line. When troubleshooting failed requests, rate limiting, or authentication issues, understanding how to leverage the verbose logging system is essential for diagnosing the root cause quickly.
How the Verbose Flag Configures gogcli Logging
The application uses Go's standard library log/slog package for structured diagnostics. The global logger initialization happens in internal/cmd/root.go during the command execution lifecycle.
Flag Declaration and Level Assignment
The RootFlags struct defines the verbose option using struct tags for the Kong CLI parser:
type RootFlags struct {
Verbose bool `help:"Enable verbose logging" short:"v"`
}
During the Execute function in internal/cmd/root.go, the code evaluates this flag to determine the appropriate log level:
logLevel := slog.LevelWarn // default
if cli.Verbose { // –v supplied
logLevel = slog.LevelDebug
}
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: logLevel,
})))
This configuration ensures that when you pass -v, the logger captures Debug level messages while writing all output to stderr, keeping stdout clean for command results.
What Debug Output Reveals About API Requests
With debug logging enabled, gogcli exposes internal state from the internal/googleapi package, which handles all Google HTTP interactions. The most valuable diagnostic information appears in the transport layer and authentication modules.
Transport Layer Debugging in transport.go
The internal/googleapi/transport.go file implements retry logic with exponential backoff. When the verbose flag is active, you will see detailed retry metadata:
rate limited, retrying: Displays the calculated delay duration, current attempt number, and maximum retry limitserver error, retrying: Shows the HTTP status code (e.g., 502, 503) and retry timing
Example debug output:
2026-02-16T10:23:12Z DEBUG rate limited, retrying delay=1.2s attempt=1 max_retries=5
2026-02-16T10:23:13Z DEBUG server error, retrying status=502 attempt=1
Authentication Flow in client.go
The internal/googleapi/client.go file logs credential creation and scope configuration. Debug messages reveal:
- Which service account file is being loaded
- Which OAuth scopes are being requested for the API client
This is critical when troubleshooting "permission denied" errors or scope-related failures.
Circuit Breaker State Changes
In internal/googleapi/circuitbreaker.go, the verbose flag exposes:
- When the circuit breaker opens or closes
- Success/failure counts triggering state transitions
- Reset attempts after failure bursts
This helps diagnose intermittent 5xx errors that trigger the circuit breaker to open, temporarily halting requests.
Practical Examples for Debugging gogcli API Requests
Basic Verbose Usage
Run any command with the -v flag to enable debug output:
# List Google Drive files with debugging enabled
gogcli -v drive ls
Troubleshooting Rate Limits
When sending emails through Gmail, watch for 429 responses and retry behavior:
gogcli -v gmail send \
--to [email protected] \
--subject "Test Message" \
--body "Debugging API requests"
Expected debug output during rate limiting:
2026-02-16T12:05:04Z DEBUG rate limited, retrying delay=2s attempt=1 max_retries=5
2026-02-16T12:05:06Z DEBUG rate limited, retrying delay=4s attempt=2 max_retries=5
Separating Debug Logs from Command Output
Since debug messages write to stderr and command results write to stdout, you can pipe clean JSON while preserving diagnostics:
gogcli -v --json gmail list 2>debug.log | jq '.messages[] | .id'
This captures verbose API debugging information in debug.log while jq processes only the JSON message IDs from stdout.
Summary
- Verbose logging in gogcli is controlled by the
-vflag, which switches the internalsloglogger fromLevelWarntoLevelDebugininternal/cmd/root.go. - Debug output appears on stderr, keeping stdout clean for command results and enabling log separation via shell redirection.
- Transport layer messages in
internal/googleapi/transport.goreveal retry attempts, rate-limit delays, and HTTP error codes. - Authentication debugging in
internal/googleapi/client.goexposes credential files and OAuth scopes being used. - Circuit breaker state changes are visible in
internal/googleapi/circuitbreaker.go, helping diagnose intermittent service failures.
Frequently Asked Questions
How do I enable verbose logging in gogcli?
Pass the -v or --verbose flag immediately after the gogcli command and before subcommands. For example: gogcli -v drive ls. This flag is defined in the RootFlags struct within internal/cmd/root.go and configures the global slog logger to output debug-level messages to stderr.
What information does the verbose flag reveal about API requests?
When enabled, the verbose flag exposes detailed metadata from the internal/googleapi package, including HTTP retry attempts with calculated backoff delays, rate-limit responses showing Retry-After headers, server error codes (502, 503), credential file paths, requested OAuth scopes, and circuit breaker state transitions between open and closed states.
Why do debug messages appear on stderr instead of stdout?
The logger initialization in internal/cmd/root.go explicitly configures slog.NewTextHandler to write to os.Stderr. This design separates diagnostic information from command output, allowing you to pipe clean data (JSON or text) from stdout while still capturing debug logs via stderr redirection to a file or separate stream.
Can I use the verbose flag with JSON output mode?
Yes, the verbose flag functions independently of output formatting. When using gogcli -v --json <command>, debug logs write to stderr in text format while the command results print to stdout as JSON. This combination is useful for debugging API parsing issues while maintaining machine-readable output for downstream processing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →