Debug a Python app by using Cloud Debugger
This quickstart shows you how to use Cloud Debugger to debug the state of a simple Python app running on App Engine. This quickstart shows you how to accomplish the following:
- Inspect local variables and the call stack
- Generate logging statements
- Set snapshot conditions and use expressions
Before you begin
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Cloud project. Learn how to check if billing is enabled on a project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Cloud project. Learn how to check if billing is enabled on a project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
- Make sure that the following software is installed on your local system:
Deploy sample app to App Engine
Start by deploying a Python 3.7 app to App Engine.
Clone the app to your local computer:
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
Navigate to the directory that contains the app:
cd python-docs-samples/appengine/standard_python3/cloud_debugger
Deploy the app to App Engine by issuing the following command:
gcloud app deploy
When prompted, select the region where you want your App Engine app located.
View the app by issuing the following command:
gcloud app browse
If a browser window does not automatically open displaying the app, click the URL that appears in the terminal.
The app contains a prompt to enter a string with the field already prepopulated.
Click Submit.
You see two results after clicking submit. One is labeled Program Output and
shows the output from the Reverse
method in the source code. The other is
labeled Correct Output and is the output from Python's reverse list functionality.
The Program Output and the Correct Output should be identical. However, there's a problem with the source code. Use Debugger to diagnose the issue.
View deployed source code
After you have deployed your app, you can view the deployed source code on the Google Cloud console Debug page.
Navigate to the Debug page in the Google Cloud console:
Make sure you have the correct project selected:
Confirm Debugger has access to the deployed files by verifying that Deployed files is selected and the app's files are present:
Make sure the correct version of your app is selected:
App Engine maintains all the deployed versions of an app. When using Debugger, verify that you have the correct version of the app selected.
After selecting the
main.py
file, you see the following block of code:try: import googleclouddebugger googleclouddebugger.enable() except ImportError: pass import logging logging.basicConfig(level=logging.INFO)
This section imports and enables the Debugger agent using a try and except block :
try: import googleclouddebugger googleclouddebugger.enable() except ImportError: pass
This section configures logging:import logging logging.basicConfig(level=logging.INFO)
You are now ready to take debug snapshots and inject debug logpoints to diagnose the problem in the source code.
Take a debug snapshot
A debug snapshot captures the local variables and call stack that are in scope at a line location.
To take a debug snapshot, click the line number that contains the
tmp
variable. A blue arrow appears indicating that a snapshot is set, and the results panel displays "Waiting for snapshot to hit."To trigger your snapshot, refresh the page.
The Variables pane shows the values of the variables. See that the
chars
array was correctly populated on the first pass through the loop. The problem is not present here because the snapshot was taken the first time the breakpoint was hit.The Call Stack pane shows the results of the call stack. You can click on the functions in the Call Stack pane to see the local variables and parameters at that point in the code. When you click on
ReverseString
, you see that the input was correct.
Since taking a snapshot and inspecting the variables and call stack didn't reveal the problem, use logpoints to track down the problem.
Inject a debug logpoint
A debug logpoint enables you to inject logging into your running app without restarting it.
To insert a logpoint, select the Logpoint tab.
Click the line number that contains the
tmp
variable. An inline text box appears. Populate the fields as follows and click Add:if (True) logpoint("About to swap two characters. Chars is currently {chars}")
A logpoint has the following structure:
if(condition)logpoint(string)
. To create a logpoint, you supply two parts:A condition, which must written in the in syntax of the source code.
A string, which can contain any number of expressions in curly braces written in the syntax of the source code.
To verify that the logpoint has been injected successfully, select the Logpoint History tab.
To trigger the logpoint, refresh the page.
To see the logs generated by the logpoint, select the Logs panel and click refresh refresh.
Diagnosing the issue
The logpoints indicate that the while
loop executes three times, but it only
needs to execute two times. Since the logpoint is set at the beginning of the
loop, it logged that it was about to swap characters on a string that was
already fully reversed.
To pinpoint the problem, use a debug snapshot with a condition.
Take a debug snapshot using a condition
The app uses the left
variable and right
variable to track when to stop
swapping values. When the left
variable is greater than the right
variable, the loop should terminate.
Snapshots can be set to trigger based on a condition in the source code. Since you know when the loop should terminate, use a snapshot with a condition to isolate the problem.
To determine why the loop executes too many times, set the snapshot to trigger on the following condition:
left > right
. Then click the camera icon camera_alt to prepare Debugger for the snapshot.Trigger the snapshot by refreshing the page. The Variables pane shows that the
left
variable is greater than theright
variable.Since the
left
variable is already greater than theright
variable at this point in the loop, it means that as the loop continues, it will swap the values one more time before it reaches line 50 and exits the loop.
Take a debug snapshot using an expression
Debugger also lets you retrieve programming-language expressions
when the snapshot is triggered. For example, you can retrieve the values in
the chars
array with expressions like chars[1]
and chars[2]
.
To get the value of an expression when a snapshot is triggered, write the expression in the Expression field. You can enter multiple expressions.
After the snapshot triggers, the expression values appear above the Variables pane.
Fixing the issue
Snapshots and logpoints help diagnose the problem in the app. In this example,
the while
loop executes too many times because the statement that stops the
loop, if left >= right: break
is reached too late to stop the last iteration.
To fix the problem, move if left >= right: break
from line 50 to line 47.
Clean up
To avoid incurring charges to your Google Cloud account for the resources used on this page, follow these steps.
Navigate to the Projects page of the Google Cloud console.
Click Delete delete next to your project.
Type your project name to confirm the shutdown.
What's next
Read our resources about DevOps and explore our research program.