Technical Articles
Set Up Remote Debugging to Diagnose CAP Applications (Node.js Stack) at Runtime on SAP BTP, Cloud Foundry Environment
Introduction
In this blog post, you learn how to set up remote debugging for a deployed CAP application instance running on SAP BTP, Cloud Foundry environment.
As a developer, this is one of the go methods when your application is misbehaving, and you can’t troubleshoot just by analyzing the logs or/and you can’t reproduce runtime errors on your development environment (local machine).
With remote debugging, you can use your local development environment to inspect and interact with the application to diagnose problems efficiently.
Disclaimer: It isn’t advisable to enable remote debugging for an application running on production.
The major topics that are covered include:
- Authenticate to Cloud Foundry with the CLI
- Connect to a Cloud Foundry application instance using the Secure Shell protocol (SSH)
- Enable the Node.js inspector for remote debugging on a running application instance
- Enable port forwarding to Cloud Foundry
- Attach a Node.js debugger to a process running on a Cloud Foundry application instance
Step 1: Install and Verify the Cloud Foundry Command Line Interface (CLI) Installation
To install the Cloud Foundry CLI, follow the official guide.
To verify the installation, open a new command prompt session and run:
╰─$ cf -v
If your installation was successful, the Cloud Foundry CLI version is displayed to standard output.
cf version 7.2.0+be4a5ce2b.2020-12-10
Step 2: Log In to the Cloud Foundry Instance with the CLI and SAP Single Sign-On
To log in to the Cloud Foundry, the cf login
command is used.
cf login [-a API_URL] [-o ORG] [-s SPACE] [--sso]
Where:
API-URL
is your API endpoint (for example, https://api.cf.eu20.hana.ondemand.com).ORG
is the org name where your application is deployed. Orgs map to business units have quota plans and unique roles.SPACE
is the space in the organization where your application is deployed. Spaces map to teams or products, hold applications and have unique roles.--sso
Prompt for a one-time passcode to log in. SAP Single Sign-On is the safest and most recommended way to log in.
SAP BTP Cockpit Overview
Sample usage of the cf login
command:
╰─$ cf login -a https://api.cf.eu20.hana.ondemand.com -o myorg -s myspace --sso
API endpoint: https://api.cf.eu20.hana.ondemand.com
Temporary Authentication Code ( Get one at https://login.cf.eu20.hana.ondemand.com/passcode ):
After running cf login
with the --sso
option, the Cloud Foundry CLI prompts for a one-time passcode to log in. Open a browser window, go to the URL https://login.cf.eu20.hana.ondemand.com/passcode , authenticate →
SAP BTP SAP Single Sign-On
SAP BTP Temporary Authentication Code
, copy the one-time passcode, go back to the console and paste it into the prompt. Once authenticated, details of the targeted org and space are provided.
Temporary Authentication Code ( Get one at https://login.cf.eu20.hana.ondemand.com/passcode ):
Authenticating...
OK
Targeted org myorg.
Targeted space myspace.
API endpoint: https://api.cf.eu20.hana.ondemand.com
API version: 3.99.0
user: myemail@sap.com
org: myorg
space: myspace
Note that Cloud Foundry uses a role-based access control system to grant permissions to members, so make sure you’ve got the appropriate role permissions assigned. For example, by being an org auditor.
Step 3: Connect to a Cloud Foundry Application Instance Using SSH
Cloud Foundry allows you to SSH to application instances unless an org/space manager has prohibited this access. For more detailed information, you can refer to Enable and Disable SSH Access.
The cf ssh-enabled
command checks whether an application is accessible via SSH:
╰─$ cf ssh-enabled myapp
ssh support is enabled for app 'myapp'.
If the app isn’t accessible via SSH, it can be enabled with the command cf enable-ssh
.
╰─$ cf enable-ssh myapp
Enabling ssh support for app myapp as youremail@sap.com...
...
OK
You must restart your app after enabling SSH access. To restart your app, run the following command:
╰─$ cf restart myapp
Note that if a space manager disabled the access at the space level, all the applications that are part of this space would inherit the access level, and you as a developer won’t be able to SSH to an individual application even if you enabled SSH access at the application level.
If SSH access is allowed at the deployment, space, and application level, you can run the cf ssh myapp
command to start an interactive SSH session with the VM hosting the application.
╰─$ cf ssh myapp
vcap@afa9bea3-b619-6476-5e97-1328:~$
Step 4: Enable the Node.js Inspector for Remote Debugging on a Running Application Instance
To enable debug mode for a running Node.js process, you need to know its unique process ID (PID). On Linux and Unix-like environments, the ps
command gives you the information required.
vcap@afa9bea3-b619-6476-5e97-1328:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
vcap 151 0.0 0.1 687580 118376 ? Sl May28 0:05 node /home/vcap/deps/0/bin/npx cds run
...
Once the PID of the Node.js process running the application is known, you can use the kill
command to send a debugging signal to it. The Node.js runtime activates the inspector protocol when it receives a usr1
signal. The inspector protocol is more or less a debugging protocol that allows tools to instrument, inspect, debug, and profile.
vcap@afa9bea3-b619-6476-5e97-1328:~$ kill -usr1 151
SAP BTP Cockpit Application Logs
Step 5: Enable Port Forwarding to Cloud Foundry
With port forwarding or port mapping, you can redirect TCP requests from your development machine to an application instance running on a VM.
In Cloud Foundry, port forwarding works by creating a listening TCP port on your local machine that maps to a TCP port on the VM via a secure SSH channel.
When using the cf ssh
command,
the
-L
flag enables local port forwarding, binding an output port on your machine to an input port on the application VM. Pass in a local port and your application VM port and port number, all colon-delimited. You can prepend your local network interface or use the defaultlocalhost
.
$ cf ssh MY-APP -L [LOCAL-NETWORK-INTERFACE:]LOCAL-PORT:REMOTE-HOST-NAME:REMOTE-HOST-PORT
Port forwarding sample usage:
cf ssh -N -L 9229:127.0.0.1:9229 myapp
This starts an SSH tunnel session where a connection to port 9229
on your development environment is forwarded to myapp
instance on port 9229
.
You can now attach a debugger such as Visual Studio Code or Chrome DevTools to localhost:9229
. With this setup, you should be able to debug your application instance running on SAP BTP, Cloud Foundry environment, as if the Node.js application was running locally.
Step 6: Attach a Node.js Debugger to a Process Running on a Cloud Foundry Application Instance
Node.js debuggers typically support attaching to an already running program in debug mode. In VS Code and Chrome DevTools, there’s a built-in “Attach to Node Process” debugging model.
Attach VS Code Debugger
Add the following debug configuration to your launch.json
file.
{
"name": "Attach to a Cloud Foundry Instance on Port 9229",
"port": 9229,
"request": "attach",
"type": "node",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/home/vcap/app"
}
For example:
VS Code Debug Configuration
For detailed information on how to add a new debug configuration, refer to Add a new configuration.
Then on the sidebar, click on Run and Debug.
Then click on Start Debugging.
Open the Debug Console.
VS Code Debugger Console, Loaded Scripts …
At this point, if you followed the previous steps, you should be able to interact with the REPL, source code, and set breakpoints.
Attach Chrome DevTools
Chrome Browser Window
After navigating to the URL, you’ll see the following page:
Chrome Browser Window (Inspect Devices)
Under the Devices, click the Open dedicated DevTools for Node link, and a new window pops up for debugging a node session:
Chrome DevTools Node.js Debugger
Chrome Debugger Console Panel
At this point, if you followed the previous steps, we’re now able to debug, interact with the REPL, source code, and set breakpoints.
Chrome Debugger Sources Panel
Conclusions
Following the steps outlined in this blog post, you can set up remote debugging for CAP Applications (Node.js Stack) at runtime on SAP BTP and Cloud Foundry Environment. This will allow you to diagnose in real time and troubleshoot any issues that may arise in your applications. This approach will help you quickly identify the source of the problem and help you resolve it. Remote debugging provides a way to pinpoint the issue’s exact location and can help developers effectively fix it.
CLOUD FOUNDRY, the CLOUD FOUNDRY logo, and other CLOUD FOUNDRY marks used in this block post are trademarks of the CloudFoundry.org Foundation in the United States and other countries.
Hey Arley Triana Morin,
Thanks a lot for sharing, this is borderline magic!
It even works with Neovim (using nvim-dap), so no more console.log on remote systems for me.
Best regards,
David
I miss the days of the good old /H 🙁
Hi Arley Triana Morin, thanks for sharing this! When I try to ssh to my app I get the following error message: "Error opening SSH connection: You are not authorized to perform the requested action." Any ideas? I logged in with the --sso option, have the Space Manager (and Space Developer) roles assigned, verified SSH is enabled in the space, and enabled it for the app, so I'm at a loss. Thanks for any help!
Hi Jason,
You are welcome. Have you tried to restart the app?
> Note that if a space manager disabled the access at the space level, all the applications that are part of this space would inherit the access level, and you as a developer won’t be able to SSH to an individual application even if you enabled SSH access at the application level.
Kind regards,
Arley
Restarting the app worked! Thank you so much for the suggestion!
Hi Arley,
Nicely done! One point: the specification
"${workspacefolder}"
for the localRoot didn't work for me (macOS Monterey). I had to capitalize the F, so my complete entry in the launch.json looks like{
"name": "Attach to a Cloud Foundry Instance on Port 9229",
"port": 9229,
"request": "attach",
"type": "node",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/home/vcap/app"
}
Hi James,
I double-checked on that, and indeed, the variable substitution is as follows:
${workspaceFolder} - the path of the folder opened in VS Code
https://code.visualstudio.com/docs/editor/variables-reference
I corrected it.
Thanks for pointing this out.
Hi Arley,
Thanks a lot for sharing! This is a great article! I entered the URL "localhost:9229" in chrome, but get the error "WebSockets request was expected", do you know how to resolve this issue? Thanks.
As described in the blog post please try the URL chrome://inspect
Hi Gregor,
Thanks for the response. I'm using VSCODE. It worked, thanks.
Arley Triana Morin, thanks for sharing the detailed manual.
I am stuck at the «Step 3: Connect to a Cloud Foundry Application Instance Using SSH»:
where myapp is a name of the wanted app, I got from cf html5-info, but I get:
How can I debug a server-side of the app from SAP BAS, running on SAP BTP?
Please avoid cross-posting and check the answer that I've given at Debugging server-side running on SAP BTP using SAP BAS
Arley Triana Morin, a question regarding the step «Step 4: Enable the Node.js Inspector for Remote Debugging on a Running Application Instance», I execute
ps aux
and get a list of running processes:but I don't see my app there, although the app is available via URL, e.g.:
So, for which PID I have to execute
kill -usr1 XXX
?Looks like you are connected to the approuter and not to your backend.
Gregor Wolf, I've followed the step #3 of this manual, I've got the name of the app via "cf apps" (it was the only option), then enabled the SSH via "cf enable-ssh %myapp%" and restarted my app with "cf restart %myapp%".
So, the question how can I get connected to my app and not to the approuter?
In start of the NPM-script inside of package.json, I run "node ./app.js", which creates an instance of approuter, configures the routing and starts the approuter. Should I revise the logic?
Thanks.
Hi Arley Triana Morin Nice blog. Really looking for it for long time. few questions below.
Thanks,
Dhiraj M
Thanks Arley Triana Morin for response. However I have observed that although we have an active breakpoint but debugger is only stopping for first 1-2 times. Many times although i am running the process but debugger doesn't get executed.
Is there any specific we have to do as I have observed this multiple times that after first 1-2 instances, control doesn't stop even breakpoint is in place and then again you have to kill session and follow the whole process again.
Dear Arley Triana Morin, Thanks for the blog, I've followed the same and have couple of questions
1. After Step 4: Enable the Node.js Inspector for Remote Debugging on a Running Application Instance, There I couldn't find exact
node /home/vcap/deps/0/bin/npx cds run
ratherAlthough I continue by killing PID 187, then followed port forwarding
PFB attached Log
2. After successful Port forwarding, I cant find the source code and process.env.ADDR =undefined
launch.json :
Terminal :
Same in case of Chrome Devtools, The Remote Target was Blank and can't interact with the REPL.
Can you pls here, Is that something wrong I did?
.
Thanks,
Pravin
The same question has already been answered:
https://answers.sap.com/questions/13768892/set-up-remote-debugging-to-diagnose-cap-applicatio.html?childToView=13780965
Hi Arley,
do you know if there is a similar way how to do remote debugging of CAP applications on Kubernetes?
Thanks,
Christopher
Yes, it is possible in a similar way to do remote debugging of CAP Applications (Node.js Stack) at Runtime on Kubernetes.
One liner, once ssh is enabled on the application, this needs to be repeated after each start/restart(/crash):