Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Arley
Product and Topic Expert
Product and Topic Expert



 

Introduction


 

In this blog post, we will explore the process of setting up remote debugging for a deployed CAP (Cloud Application Programming) application instance running on the SAP BTP (Business Technology Platform) in a Cloud Foundry environment. Remote debugging is a valuable tool for developers when troubleshooting misbehaving applications, especially when analysis of logs or local testing fails to reproduce runtime errors.

By enabling remote debugging, developers can leverage their local development environment to inspect and interact with the application, allowing for efficient problem diagnosis.

Disclaimer: It isn't advisable to enable remote debugging for an application running on production.

The key topics covered in this article include:

  • Authenticating to Cloud Foundry with the Command Line Interface (CLI)

  • Connecting to a Cloud Foundry application instance using the Secure Shell (SSH) protocol

  • Enabling the Node.js inspector for remote debugging on a running application instance

  • Enabling port forwarding to Cloud Foundry

  • Attaching 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 begin, we need to install the Cloud Foundry CLI. Follow the official guide for installation instructions, which provides detailed steps tailored to your operating system.

Once the installation is complete, we can verify it by performing the following steps:

  • Open a new command prompt session or terminal.

  • Run the following command:


╰─$ cf -v

If the installation is successful, the Cloud Foundry CLI version will be displayed in the standard output. For example:

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 account, 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.


The org name, API endpoint, and space information can be found in the SAP BTP Cockpit under HomeRegionsGlobal AccountsSubaccounts.



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 😞

Upon executing the command with the --sso option, the Cloud Foundry CLI will display the API endpoint and prompt you for one-time passcode to log in.

  • Open a browser and navigate to the URL provided, such as https://login.cf.eu20.hana.ondemand.com/passcode

  • Authenticate yourself using SAP Single Sign-On.

    SAP BTP SAP Single Sign-On



    SAP BTP Temporary Authentication Code



  • Copy the one-time passcode generated.

  • Return to the console and paste the passcode into the prompt.

  • Once authenticated, the CLI will provide details about the targeted org and space.


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


 

In Cloud Foundry, you can SSH into application instances unless SSH access has been prohibited by an org/space manager. If you would like more detailed information, you can refer to the Enable and Disable SSH Access documentation.

To check if an application is accessible via SSH, you can use the following command:
╰─$ 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

Please note that if SSH access has been disabled at the space level by a space manager, all applications within that space will inherit the access level. In such cases, even if you, as a developer, enable SSH access at the application level, you cannot SSH into individual applications.

Assuming SSH access is allowed at the deployment, space, and application level, you can initiate an interactive SSH session with the VM hosting the application by running the following command:



╰─$ cf ssh myapp

Once connected, you will be in an interactive SSH session with the VM, indicated by the prompt:
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'll need to determine its unique process ID (PID). On Linux and Unix-like environments, you can use the ps command to obtain this information. Here's an example:
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


After sending this signal to the Node.js process, inspect the application logs. You should see that a debugger is now listening on ws://127.0.0.1:9229/48d7a94b-acb8-4d43-9932-95b781ee932d, this indicates that the Node.js process has switched to debug mode and is actively listening for debugging request on a WebSocket server located at host and port 127.0.0.1:9229.


SAP BTP Cockpit Application Logs


 

Step 5: Enable Port Forwarding to Cloud Foundry


 

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 default localhost

.

Enables local port forwarding


$ cf ssh MY-APP -L [LOCAL-NETWORK-INTERFACE:]LOCAL-PORT:REMOTE-HOST-NAME:REMOTE-HOST-PORT


Here's an example of enabling local port forwarding using the cf ssh command:

cf ssh -N -L 9229:127.0.0.1:9229 myapp


This command initiates an SSH tunnel session where a connection to port 9229 on your development environment is forwarded to the myapp instance on port 9229.



Now, you can attach a debugger such as Visual Studio Code, SAP Business Application Studio (BAS) or Chrome DevTools to localhost:9229. With this setup, you'll be able to debug your application instance running on SAP BTP, Cloud Foundry environment as if the Node.js application were running locally.



 

Step 6: Attach a Node.js Debugger to a Process Running on a Cloud Foundry Application Instance


 

Node.js debuggers support attaching to a running program in debug mode. In VS Code and Chrome DevTools, there's a built-in "Attach to Node Process" debugging model.

Here's how you can attach the debugger to a process running on a Cloud Foundry application instance:

 

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.

Launch VS Code and click on the Run and Debug button in the sidebar.


Click on Start Debugging to initiate the debugging session.



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, view loaded scripts, and set breakpoints.

 

Attach Chrome DevTools


 

Open the Chrome browser (or any Chromium-based browser) and enter chrome://inspect in the address bar. If you're using Microsoft Edge, it also supports the V8 JavaScript engine and can be used for debugging.



 


Chrome Browser Window


 

After navigating to the URL, you'll see the following page:


Chrome Browser Window (Inspect Devices)



On the Devices screen, click the Open dedicated DevTools for Node link. This will open a new window pops up for debugging a node session.


Chrome DevTools Node.js Debugger


 


Chrome Debugger Console Panel


If you followed the previous steps, we can now 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.
25 Comments
david_kunz2
Advisor
Advisor
Hey arley.trianamorin,

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
former_member752115
Discoverer
I miss the days of the good old /H    😞
jasonmuzzy
Active Participant
Hi arley.trianamorin, 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!
Arley
Product and Topic Expert
Product and Topic Expert

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

jasonmuzzy
Active Participant
Restarting the app worked!  Thank you so much for the suggestion!
coffeehacker
Employee
Employee
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"
}
Arley
Product and Topic Expert
Product and Topic Expert
0 Kudos

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.

leon_chen_sap
Explorer
0 Kudos
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.
gregorw
Active Contributor
As described in the blog post please try the URL chrome://inspect
leon_chen_sap
Explorer
0 Kudos
Hi Gregor,

Thanks for the response. I'm using VSCODE. It worked, thanks.
MikeB
Contributor
0 Kudos

arley.trianamorin, thanks for sharing the detailed manual.

I am stuck at the «Step 3: Connect to a Cloud Foundry Application Instance Using SSH»:

cf ssh-enabled myapp

where myapp is a name of the wanted app, I got from cf html5-info, but I get:

App 'myapp-html5-srv' not found.
FAILED.

How can I debug a server-side of the app from SAP BAS, running on SAP BTP?

gregorw
Active Contributor
Please avoid cross-posting and check the answer that I've given at Debugging server-side running on SAP BTP using SAP BAS
MikeB
Contributor
0 Kudos

arley.trianamorin, 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:

root           1  0.0  0.0   1044     4 ?        Ss   16:16   0:00 /tmp/garden-init
vcap 8 0.1 0.0 739588 46776 ? Ssl 16:16 0:00 npm
vcap 9 0.0 0.0 716040 10344 ? Rsl 16:16 0:00 /tmp/lifecycle/diego-sshd --allowedKeyExchanges= --address=0.0.0.0:2222 --allowUnauthenticatedClients=false --inh
root 75 0.0 0.0 4632 860 ? Ss 16:16 0:00 sh -c trap 'kill -9 0' TERM; /etc/cf-assets/envoy/envoy -c /etc/cf-assets/envoy_config/envoy.yaml --drain-time-s
root 106 1.5 0.0 3284028 55696 ? Sl 16:16 0:02 /etc/cf-assets/envoy/envoy -c /etc/cf-assets/envoy_config/envoy.yaml --drain-time-s 900 --log-level critical
vcap 253 0.0 0.0 4644 804 ? S 16:16 0:00 sh -c node node_modules/@sap/approuter/approuter.js
vcap 254 0.5 0.0 854028 77320 ? Sl 16:16 0:00 node node_modules/@sap/approuter/approuter.js
root 265 0.0 0.0 706256 4896 ? Ssl 16:16 0:00 /etc/cf-assets/healthcheck/healthcheck -port=8080 -timeout=1000ms -liveness-interval=30s
vcap 275 0.0 0.0 70388 4016 pts/0 Ss 16:17 0:00 /bin/bash
vcap 287 0.0 0.0 86284 3304 pts/0 R+ 16:19 0:00 ps aux

but I don't see my app there, although the app is available via URL, e.g.:

%HOST%.launchpad.cfapps.eu10.hana.ondemand.com/UUID.app-name-0.0.10/index.html

So, for which PID I have to execute kill -usr1 XXX?

gregorw
Active Contributor
Looks like you are connected to the approuter and not to your backend.
MikeB
Contributor
0 Kudos
gregorwolf, 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.
dhiraj_more
Participant
0 Kudos
Hi arley.trianamorin Nice blog. Really looking for it for long time. few questions below.

  1. can we set the breakpoint for specific user, or it will only work for the user on which SSH is enabled by default.

  2. Do we have to restart the service everytime after SSH is enabled or it's one time activity.


Thanks,

Dhiraj M
Arley
Product and Topic Expert
Product and Topic Expert
0 Kudos

  1. If you set an application breakpoint, the code will stop for all users unless you set a conditional breakpoint.

  2. A restart is usually required only after enabling SSH access. Once SSH is enabled, a restart isn't required.

pravin_kumar_v1
Explorer
0 Kudos

Dear arley.trianamorin, 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 rather

user: remotetestapp $ cf ssh remotetestapp-srv
vcap@36cc5bb8-1a96-413a-7756-a942:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1112 4 ? Ss 05:24 0:00 /tmp/garden-init
vcap 7 1.8 0.0 801996 73584 ? Ssl 05:24 0:00 npm start
vcap 13 0.0 0.0 724192 9860 ? Ssl 05:24 0:00 /tmp/lifecycle/diego-sshd --allowedKeyExchanges= --address=0.0.0.0:
root 21 0.0 0.0 4640 856 ? Ss 05:24 0:00 sh -c trap 'kill -9 0' TERM; /etc/cf-assets/envoy/envoy -c /etc/cf-
root 86 0.6 0.0 2759492 52416 ? Sl 05:24 0:00 /etc/cf-assets/envoy/envoy -c /etc/cf-assets/envoy_config/envoy.yam
vcap 186 0.0 0.0 4644 836 ? S 05:24 0:00 sh /home/vcap/tmp/start-6e172f3b.sh
vcap 187 2.7 0.0 11225584 94108 ? Sl 05:24 0:00 node /home/vcap/app/node_modules/.bin/cds run
root 198 0.0 0.0 714632 4216 ? Ssl 05:24 0:00 /etc/cf-assets/healthcheck/healthcheck -port=8080 -timeout=1000ms -
vcap 209 0.0 0.0 70392 3768 pts/0 Ss 05:24 0:00 /bin/bash
vcap 220 0.0 0.0 86288 3348 pts/0 R+ 05:25 0:00 ps aux

Although I continue by killing PID 187, then followed port forwarding
PFB attached Log

Debugger listening on ws://127.0.0.1:9229/da338c78-3e2e-4c1f-8d04-63c3cf8be3ae

2. After successful Port forwarding, I cant find the source code and  process.env.ADDR =undefined
launch.json :

    {
"name": "Attach to a Cloud Foundry Instance on Port 9229",
"port": 9229,
"request": "attach",
"type": "node",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/home/vcap/app"
},

Terminal :

[cds] - using auth strategy: {kind: 'xsuaa'} 

cds.version
'6.3.2'
process.ppid
186
process.env.ADDR
undefined

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

 

Arley
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Arley,

do you know if there is a similar way how to do remote debugging of CAP applications on Kubernetes?

Thanks,
Christopher
Arley
Product and Topic Expert
Product and Topic Expert
0 Kudos

Yes, it is possible in a similar way to do remote debugging of CAP Applications (Node.js Stack) at Runtime on Kubernetes.

pieterjanssens
Active Participant
One liner, once ssh is enabled on the application, this needs to be repeated after each start/restart(/crash):
cf ssh APP_NAME -c 'kill -usr1 $(pgrep node)' && cf ssh -N -T -L 9229:127.0.0.1:9229 APP_NAME
dhiraj_more
Participant
0 Kudos
Thanks arley.trianamorin 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.
mayank_thakursap
Explorer
0 Kudos
HI arley.trianamorin ,

After Cf ssh 'app name' , below is the out put :

 

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1112 512 ? Ss 08:45 0:00 /tmp/garden-init
vcap 7 0.0 0.0 725300 11776 ? Ssl 08:45 0:00 /tmp/lifecycle/diego-sshd --allowedKeyExchanges= --address=0.0.0.0:2222 --allowUnauthenticatedClients=false --inheritDaemonEnv=true -
vcap 13 1.7 0.0 766412 64656 ? Ssl 08:45 0:00 npm start
root 44 0.1 0.0 2888 1536 ? Ss 08:45 0:00 sh -c trap 'kill -9 0' TERM; /etc/cf-assets/envoy/envoy -c /etc/cf-assets/envoy_config/envoy.yaml --drain-time-s 900 --log-level crit
root 87 3.1 0.0 3274604 49664 ? Sl 08:45 0:01 /etc/cf-assets/envoy/envoy -c /etc/cf-assets/envoy_config/envoy.yaml --drain-time-s 900 --log-level critical
vcap 271 0.0 0.0 2900 1536 ? S 08:45 0:00 sh -c -- ./node_modules/@sap/cds/bin/cds.js run --profile ${CAP_PROFILE}
vcap 272 10.0 0.0 11412020 98600 ? Sl 08:45 0:04 node ./node_modules/@sap/cds/bin/cds.js run --profile production
root 283 0.0 0.0 713716 3584 ? Ssl 08:45 0:00 /etc/cf-assets/healthcheck/healthcheck -port=8080 -timeout=1000ms -liveness-interval=30s
vcap 294 0.0 0.0 85048 3584 pts/0 Ss 08:46 0:00 /bin/bash
vcap 301 0.0 0.0 87484 3072 pts/0 R+ 08:46 0:00 ps aux

 

Can you please help me which one should i select because I am not getting option of
/home/vcap/app/node_modules/.bin/cds run

 

Thanks,

 

Mayank
hobin
Explorer
0 Kudos

Hello arley.trianamorin ,

This is a great document, My debugger got attached to CLF , but one issue i am havingis the breakpoints are not getting stopped. It is showing as "Unbound breakpoint". The call is happening from Post man.

Regards

Hobin Thomas