Full-Stack Debugging with Structured Logging
In this step, you’ll learn how to debug issues that only appear when multiple parts of your application work together. Unlike unit tests, which isolate functions and logic, full-stack bugs emerge from the interaction between the frontend (browser), backend (Next.js), and the database. To debug these effectively, you’ll need to combine logging with a unified orchestration workflow so that Copilot can see the entire system executing in one place.
This section teaches you how to leverage Copilot to insert targeted logs, run full browser-driven E2E tests, and trace data across environments to uncover the root cause.
- 1 Problem
- 2 What You Need to Know
- 3 ✏️ Hands-On Exploration
- 4 Next Steps
- 5 Sources
Problem
Your task is to work with GitHub Copilot to diagnose and fix a full-stack bug described in BUG_REPORT.md on the debug-2 branch. This bug only appears during a real browser-driven workflow, not in unit tests — meaning Copilot must observe both the server and the browser execution at the same time.
Debugging this kind of defect requires two key capabilities:
Logging: inserting detailed, well-structured logs across both the frontend and backend to trace what the system is actually doing.
Orchestration: running the dev server and Playwright E2E tests together in a way that Copilot can reliably monitor and react to output from both processes.
What You Need to Know
Why Full-Stack Bugs Require Richer Debugging
Unit tests validate isolated behaviors. But real-world bugs often emerge only when multiple systems interact:
the frontend sends data to the backend
the backend modifies database state
the frontend updates UI state based on responses
the browser reflects the final outcome
When something goes wrong in this chain, you may see no stack traces, no visible errors — just incorrect behavior.
That’s why deep logging and cross-environment observation are essential.
Full-stack debugging isn’t about catching exceptions; it’s about reconstructing the flow of truth across systems.
Logging as a Full-Stack Debugging Tool
Copilot is extremely effective at inserting “trace logs” across your code. For multi-environment debugging, good logs should:
print important variables (database payloads, request bodies, UI state snapshots)
appear at each step in the request/response lifecycle
clearly distinguish frontend vs backend output
optionally include custom stack traces for deep insight
Well-designed logs allow you and Copilot to:
see where the data flow deviates from expectations
track state changes across layers
detect timing issues and race conditions
understand what actually happened, not just what the code should have done
And because Copilot can insert, refine, and later remove logs in bulk, it becomes an efficient partner in exploratory debugging.
Orchestration with VS Code Tasks
How Copilot Orchestrates Multiple Processes
GitHub Copilot can manage complex development workflows by coordinating multiple processes at once — such as running a dev server and executing E2E tests together. With VS Code Tasks, Copilot gains a structured environment that allows it to:
spawn multiple terminals
run independent processes in parallel
monitor outputs from each terminal in real time
respond intelligently to events from different environments
sequence actions based on log activity (“once the server is ready, start the tests”)
This makes full-stack debugging far more powerful and predictable.
Why Tasks Enable Reliable Multi-Process Control
VS Code Tasks provide Copilot with a consistent, well-defined interface for running commands. You can configure tasks in the .vscode/tasks.json. It’s best to have Copilot help you write this file, as writing it from scratch can be tedious.
Each task has:
a label
a shell command
a dedicated terminal
optional background or watch modes
predictable lifecycles and statuses
Because tasks behave consistently, Copilot can confidently orchestrate them without guesswork.
For example, when you say:
“Run the dev server, and once it’s ready, run the E2Es.”
Copilot will:
launch the dev server task
watch its terminal until startup logs indicate readiness
start the E2E task in another terminal
read and correlate logs across both environments
make decisions or suggest fixes based on combined output
Example Prompt: Copilot writes a task for you
Generate a task in
.vscode/tasks.jsonthat runs the e2e tests. It should find and terminate any processes running on port 3000, start the dev server, then once it’s loaded run the tests.
What VS Code Manages for You
VS Code handles all the process plumbing so Copilot doesn’t have to:
Named terminals → predictable, stable output streams
Long-running task management → dev servers, watchers, background jobs
Task sequencing → run one after another or in parallel
Consistent output routing → Copilot always knows where logs will appear
Automatic cleanup → stopping tasks when debugging is complete
Together, these features give Copilot the ability to orchestrate full-stack workflows with clarity and control, enabling real-time understanding of how your system behaves across multiple layers.
How Logs Flow in a Multi-Task Environment
VS Code ensures that task output is:
grouped by task / terminal
consistently formatted
available for Copilot to read sequentially
Playwright can also be configured to forward browser console events to its terminal stream:
console.logconsole.errornetwork events
page crashes
test step tracing
When combined with the server logs, Copilot gets a complete picture:
[Server] API route hit with payload: { ... }
[Browser] Button clicked: "Submit"
[Browser] Form state: { ... }
[Server] Database update → success
[Browser] UI updated with new task
This gives the AI enough visibility to follow the chain of cause and effect across the entire stack.
Writing to Log Files (Optional)
In some debugging scenarios — especially for nondeterministic bugs — it’s useful to:
write logs to a file
ask Copilot to analyze the file after execution
This can supplement the real-time terminal view for deeper historical analysis.
The Full-Stack Debugging Prompt
This step uses a dedicated debugging prompt located in .github/prompts, which is also accessible directly from Copilot by typing /debug-with-logs in the agent chat window.
✏️ Hands-On Exploration
Rather than manually stepping through logging, orchestration, and debugging, you will use the provided prompt to guide Copilot through the entire workflow. Your role is to observe how Copilot reasons, what logs it adds, and how it identifies the root cause.
Checkout out the
bug-2branch in TaskFlowCommit or reset any changes made by Copilot;
Commit
git add . && git commit -m “changes“Reset
git reset --hard HEAD && git clean -fd
Check out the new branch
git switch bug-2
Explore the bug outlined in
BUG_REPORT.mdReplicate it in TaskFlow and make sure you understand what the problem is
Run the e2e tests normally
Start the dev server
npm run devIn another terminal, run the e2es
npm run test:e2eYou may need to re-install the playwright browsers
npx playwright install chromium
Look over the logging debug prompt
.github/prompts/debug-with-logs.prompt.mdRun the prompt
"/debug-with-logs"Observe the output and how Copilot goes about fixing the bugs
Pro Tip: Use a more advanced model to get better results
Verify the bug is fixed
Manually run the TaskFlow app and try to toggle a task.
Run the tests
npm run test:e2e:debugornpm run test:docker
Next Steps
You now know how to orchestrate multiple environments through a unified log stream and use Copilot to debug full-stack issues.
Continue to: https://wiki.at.bitovi.com/wiki/spaces/AIEnabledDevelopment/pages/1764917265
In the next section, you’ll go deeper by using a PostgreSQL MCP server to debug data issues directly from the database layer — enabling Copilot to query live data while solving bugs.