Working with Internal Sessions in ABAP Cloud

Estimated read time 20 min read

Introduction 

I have been writing code extensively in ABAP Cloud for some time now. As it’s a restricted version of ABAP, I encountered many challenges when trying to accomplish tasks that were simpler in the classical version. Nevertheless, some old technical aspects aren’t being replaced that easily. I’ve learned that returning to the unchanged fundamental concepts is always a good idea.

Developing in ABAP Cloud can be pretty demanding, mainly if you are used to powerful features in the classic ABAP version that are no longer available (such as using unreleased objects like CL_SESSION_INFO, functionalities like EPP passports, or more advanced tools for monitoring bgRFCs and background jobs). 

In this new programming world, I wanted to create some functionality to trace the ABAP internal sessions, spot any short dumps, receive automatic notifications, and measure execution performance. What follows is a description of how I achieved this.

 

Background

When I first started learning ABAP (too long ago), one of my main concerns was understanding the ABAP Application Server, its components, how to use its resources, and how to run the code I write in this environment. For many developers, the picture below is well-known:

Figure 1 – Sessions on the AS ABAP (from the official SAP Help  documentation)

In the classic ABAP version there are several options available for tracking the internal sessions:

Class CL_SESSION_INFO – which can provide a lot of valuable information like the session ID, type of user session, memory information, etc. ;Extended Passport (EPP) – which can also provide information about the internal session, but is also very useful in understanding the execution from one session to another; it can also be used for automatic analysis of short dumps;Others.

ABAP Cloud works with the same internal sessions, of course. A work process always executes the code you write in an ABAP internal session started by a plain old SAP program. However, these helpful tools are unavailable as they are not part of the released APIs.

Internal sessions manage SAP LUWs. Understanding how the SAP LUW concept works and how it can be leveraged helps developers create robust functionality.

In the classic ABAP version, you could use the RFC functionality in many practical ways. One of these was calling synchronous RFCs within the same system( destination NONE’), explicitly starting a new sequential SAP LUW without ending the current SAP LUW. This would easily allow you to “catch” a short dump. With the new bgPF framework in Cloud ABAP, this is not possible anymore.

Before I delve into my small utility project, there’s one more thing worth mentioning about ABAP Cloud. One of the strongest concepts introduced in this new cloud programming world, along with the Restful ABAP Programming Model, is the SAP Controlled LUW. This is a great feature but restrictive at the same time. It saves developers from manually handling transaction consistency (remember building CUD operations with CALL FUNCTION … IN UPDATE TASK?). It is by default embedded in RAP and bgPF controlled units and local consumption of RAP business events (though I wouldn’t even count the latter since it is also handled by controlled bgPF).

But what about other scenarios, like task automation or pipeline implementation and execution, where you must perform several tasks within the same ABAP internal session, split by sequential COMMIT WORK statements? If you find yourself in a SAP controlled LUW, that becomes impossible. Fortunately, you can also start ABAP internal sessions on the cloud AS ABAP that don’t “enforce” the controlled LUW part by default, or you can enforce the controlled part on your own when needed. 

These latter types of sessions are my focus in this article.

 

In summary, I wanted to be able to track in ABAP Cloud these kinds of uncontrolled LUW sessions for the following reasons:

There are missing tools from the classic ABAP version;It is impossible to spot runtime errors automatically;It is impossible to debug background jobs, so I need more info about that session, which I cannot debug.

Note: In both the BTP ABAP Cloud Environment and S/4HANA Public Cloud, I found some tools that facilitate the analysis of executed bgPF units or system work processes. However, these tools were insufficient – particularly the ‘Monitor bgRFC Queues’ app. The name itself is somewhat confusing, as bgRFC cannot be used in ABAP Cloud, where the bgPF framework is employed instead. Thus, I would have expected the term “RFC” to be avoided.

 

The solution to Track ABAP Cloud Internal Sessions

From my experience so far, I have identified the following common “types” of sessions used in ABAP Cloud (I use quotes here as this is my classification based on empirical research, not from any official SAP documentation; the list is not exhaustive) :

Sessions handled by dialog work processes (DIA WP):Started as an HTTP call (SAPMHTTP [system]    %_http_start [module pbo] screen 0010 ) – this refers to any Odata service call as part of RAP business objects (Fiori apps) or an external HTTP call of a published service;Started as a bgPF unit call (SAPMSSY1 [system]    %_rfc_start [module pbo] – screen 3004) – this is started by an explicit bgPF unit execution, or the local handling of a RAP business event;Sessions handled by background work processes (BCK WP):Started as a result of a background job running (RSBTCPT6    start-of-selection [event])

 

These sessions can be controlled( by the SAP frameworks themselves—like RAP or bgPF controlled launch—or by the developers using class CL_ABAP_TX ) or uncontrolled. My focus is on tracking the uncontrolled ones.

 For every session started within custom code on an AS ABAP in the cloud, I would like to know a few aspects:

When a session started and ended, and from what starting point;Whether a session has created other sequential sessions linked to it;How much time it took for a session to complete the logic;If a short dump or another runtime error prevented the session from being completed.

To achieve this, I have created a relatively simple class, with a few methods, called zcl_xx_session_tracker, which can be simply used in custom code:

Starting

 

 

METHOD start.
IF zcl_os_session_tracker=>tracker_activated = abap_false.
RETURN.
ENDIF.
TRY.
me->session_int_uuid =
cl_system_uuid=>if_system_uuid_static~create_uuid_x16( ).
CATCH cx_uuid_error.
” This should not interrupt the processing in any way. So in case of
error it just exits
RETURN.
ENDTRY.
DATA(stack_list) = _get_call_stack( ).
IF lines( stack_list ) >= 3.
me->stack_current_point = stack_list[ 3 ]->get_text( ).
ENDIF.
INSERT zos_sess_track FROM @(
VALUE #( uuid = me->session_int_uuid
session_id = me->session_id
work_process_type = COND #( WHEN sy-batch =
abap_true THEN ‘BCK’ ELSE ‘DIA’ )
stack_start_point = me->stack_start_point
stack_current_point = me->stack_current_point
started_at = me->_now( ) ) ).
IF sy-subrc = 0 AND commit = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.

 

 

 

Ending

 

 

METHOD end.
IF zcl_os_session_tracker=>tracker_activated = abap_false.
RETURN.
ENDIF.
TRY.
DATA(delete_after) = cl_abap_tstmp=>add( EXPORTING
tstmp = CONV timestampl( me->_now( ) )
secs = keep_track_log_in_minutes * 60 ).
CATCH cx_parameter_invalid_range cx_parameter_invalid_type.
ENDTRY.
UPDATE zos_sess_track SET ended_at = @( me->_now( ) ),
rec_delete_after = @delete_after,
is_finished =
WHERE uuid = ->session_int_uuid.
IF sy-subrc = 0 AND commit = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.

 

 

 

Linking sessions (example of linking a subsequent bgPF session):

 

 

METHOD link_subsequent_session.
IF zcl_os_session_tracker=>tracker_activated = abap_false.
RETURN.
ENDIF.
INSERT zos_sess_links FROM @(
VALUE #( parent_session_id = parent_sess_id
child_session_id = subseq_sess_id
bgpf_mon_string = bgpf_monitor_string
job_name = jobname
job_count = jobcount ) ).
IF sy-subrc = 0 AND commit = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.

 

 

All the information gathered with the class above is saved in custom database tables to be used and checked later.

Since I also want to catch possible runtime errors that might occur in the middle of a session, the start() and end() methods execute a COMMIT WORK by default (remember, I am using this in the uncontrolled scenario; for the controlled one, COMMIT WORK would not be possible, evidently). 

Below is a short sample of how the tool can be used for tracking sessions started from Eclipse by running the main() method:

 

 

METHOD if_oo_adt_classrun~main.

DATA(random) = cl_abap_random=>create( cl_abap_random=>seed( ) ).
DATA(current_session_id) = |TEST_BGPF_MAIN_{ random->int31( ) }|.

zcl_os_session_tracker=>session( current_session_id )->start( ).

_start_new_bgpf_udemo_unit( parent_sess_id = current_session_id ).

zcl_os_session_tracker=>session( current_session_id )->end( commit =
abap_false ).
COMMIT WORK.

out->write( ‘A new test for ABAP Session tracker was started. Check
also subsequent bgPF units’ ).

ENDMETHOD

 

 

All in all, this small project allows me to have a comprehensive view of the ABAP internal sessions that I start with my custom code in ABAP Cloud, as shown in the image below:

Figure 2 – Session-tracked data gathered by the tool

The information consists of the following fields: 

session ID – generated to identify a sessionWork Process type –  dialog or backgroundsession starting point – the first program in the call stack starting the sessioncurrent place in call stack – place where I call the start() method in the call stackstart time – timestampend time  – timestampdelete record after  – timestampsession is finished successfully – boolean bgPF monitor string – string generated by the bgPF framework when creating a new bgPF unitjob count – job informationjob name – job information

In addition to the start and end timestamps information, I also persist the job identifier (job name and count) for the background sessions and the bgPF monitor string generated when creating a new bgPF unit. This is very useful if I want to retrieve the status of that job/bgPF unit programmatically later.

Also, I assign these tracking records a lifetime value to avoid overcrowding the database. A background job automatically deletes these records when they expire.

The above-mentioned background job is running periodically and checks the sessions that were started more than one hour ago (for sessions processed by dialog WPs) or one day ago (for sessions processed by background WPs) and have not finished yet. This is how I identify potential failed sessions and send necessary alerts when needed.

Last but not least, this functionality can be activated and deactivated according to the developer’s needs as it may not always be necessary to have it active in a productive system. You can also use this tool for tracking sessions with controlled LUWs, but you must ensure that no commit work is executed, and be aware that runtime errors cannot be identified in this case.

 

Conclusion

I developed this small utility tool to help track and log internal sessions, measure performance, and identify potential runtime errors. This can also serve as a starting point for automating the maintenance of complex custom ABAP developments by monitoring ABAP internal sessions, gathering more information about them (started as bgPF or jobs), and sending alerts to the appropriate teams when vital processes exhibit unusual behavior.

As I conclude this small presentation, I would like to find out your thoughts and opinions on the topics mentioned.

 

References:

https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmemory_organization.htmhttps://help.sap.com/docs/abap-cloud/abap-concepts/controlled-sap-luwhttps://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenepp.htm 

This article also appeared on Linked-in: https://www.linkedin.com/pulse/working-internal-sessions-abap-cloud-octavian-mihail-savu-tkmlf/?trackingId=IfI%2BV54JTt%2BuSnpwmYUveg%3D%3D 

 

 

 

 

 

​ Introduction I have been writing code extensively in ABAP Cloud for some time now. As it’s a restricted version of ABAP, I encountered many challenges when trying to accomplish tasks that were simpler in the classical version. Nevertheless, some old technical aspects aren’t being replaced that easily. I’ve learned that returning to the unchanged fundamental concepts is always a good idea.Developing in ABAP Cloud can be pretty demanding, mainly if you are used to powerful features in the classic ABAP version that are no longer available (such as using unreleased objects like CL_SESSION_INFO, functionalities like EPP passports, or more advanced tools for monitoring bgRFCs and background jobs). In this new programming world, I wanted to create some functionality to trace the ABAP internal sessions, spot any short dumps, receive automatic notifications, and measure execution performance. What follows is a description of how I achieved this. BackgroundWhen I first started learning ABAP (too long ago), one of my main concerns was understanding the ABAP Application Server, its components, how to use its resources, and how to run the code I write in this environment. For many developers, the picture below is well-known:Figure 1 – Sessions on the AS ABAP (from the official SAP Help  documentation)In the classic ABAP version there are several options available for tracking the internal sessions:Class CL_SESSION_INFO – which can provide a lot of valuable information like the session ID, type of user session, memory information, etc. ;Extended Passport (EPP) – which can also provide information about the internal session, but is also very useful in understanding the execution from one session to another; it can also be used for automatic analysis of short dumps;Others.ABAP Cloud works with the same internal sessions, of course. A work process always executes the code you write in an ABAP internal session started by a plain old SAP program. However, these helpful tools are unavailable as they are not part of the released APIs.Internal sessions manage SAP LUWs. Understanding how the SAP LUW concept works and how it can be leveraged helps developers create robust functionality.In the classic ABAP version, you could use the RFC functionality in many practical ways. One of these was calling synchronous RFCs within the same system( destination NONE’), explicitly starting a new sequential SAP LUW without ending the current SAP LUW. This would easily allow you to “catch” a short dump. With the new bgPF framework in Cloud ABAP, this is not possible anymore.Before I delve into my small utility project, there’s one more thing worth mentioning about ABAP Cloud. One of the strongest concepts introduced in this new cloud programming world, along with the Restful ABAP Programming Model, is the SAP Controlled LUW. This is a great feature but restrictive at the same time. It saves developers from manually handling transaction consistency (remember building CUD operations with CALL FUNCTION … IN UPDATE TASK?). It is by default embedded in RAP and bgPF controlled units and local consumption of RAP business events (though I wouldn’t even count the latter since it is also handled by controlled bgPF).But what about other scenarios, like task automation or pipeline implementation and execution, where you must perform several tasks within the same ABAP internal session, split by sequential COMMIT WORK statements? If you find yourself in a SAP controlled LUW, that becomes impossible. Fortunately, you can also start ABAP internal sessions on the cloud AS ABAP that don’t “enforce” the controlled LUW part by default, or you can enforce the controlled part on your own when needed. These latter types of sessions are my focus in this article. In summary, I wanted to be able to track in ABAP Cloud these kinds of uncontrolled LUW sessions for the following reasons:There are missing tools from the classic ABAP version;It is impossible to spot runtime errors automatically;It is impossible to debug background jobs, so I need more info about that session, which I cannot debug.Note: In both the BTP ABAP Cloud Environment and S/4HANA Public Cloud, I found some tools that facilitate the analysis of executed bgPF units or system work processes. However, these tools were insufficient – particularly the ‘Monitor bgRFC Queues’ app. The name itself is somewhat confusing, as bgRFC cannot be used in ABAP Cloud, where the bgPF framework is employed instead. Thus, I would have expected the term “RFC” to be avoided. The solution to Track ABAP Cloud Internal SessionsFrom my experience so far, I have identified the following common “types” of sessions used in ABAP Cloud (I use quotes here as this is my classification based on empirical research, not from any official SAP documentation; the list is not exhaustive) :Sessions handled by dialog work processes (DIA WP):Started as an HTTP call (SAPMHTTP [system]    %_http_start [module pbo] screen 0010 ) – this refers to any Odata service call as part of RAP business objects (Fiori apps) or an external HTTP call of a published service;Started as a bgPF unit call (SAPMSSY1 [system]    %_rfc_start [module pbo] – screen 3004) – this is started by an explicit bgPF unit execution, or the local handling of a RAP business event;Sessions handled by background work processes (BCK WP):Started as a result of a background job running (RSBTCPT6    start-of-selection [event]) These sessions can be controlled( by the SAP frameworks themselves—like RAP or bgPF controlled launch—or by the developers using class CL_ABAP_TX ) or uncontrolled. My focus is on tracking the uncontrolled ones. For every session started within custom code on an AS ABAP in the cloud, I would like to know a few aspects:When a session started and ended, and from what starting point;Whether a session has created other sequential sessions linked to it;How much time it took for a session to complete the logic;If a short dump or another runtime error prevented the session from being completed.To achieve this, I have created a relatively simple class, with a few methods, called zcl_xx_session_tracker, which can be simply used in custom code:Starting:   METHOD start.
IF zcl_os_session_tracker=>tracker_activated = abap_false.
RETURN.
ENDIF.
TRY.
me->session_int_uuid =
cl_system_uuid=>if_system_uuid_static~create_uuid_x16( ).
CATCH cx_uuid_error.
” This should not interrupt the processing in any way. So in case of
error it just exits
RETURN.
ENDTRY.
DATA(stack_list) = _get_call_stack( ).
IF lines( stack_list ) >= 3.
me->stack_current_point = stack_list[ 3 ]->get_text( ).
ENDIF.
INSERT zos_sess_track FROM @(
VALUE #( uuid = me->session_int_uuid
session_id = me->session_id
work_process_type = COND #( WHEN sy-batch =
abap_true THEN ‘BCK’ ELSE ‘DIA’ )
stack_start_point = me->stack_start_point
stack_current_point = me->stack_current_point
started_at = me->_now( ) ) ).
IF sy-subrc = 0 AND commit = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.   Ending:    METHOD end.
IF zcl_os_session_tracker=>tracker_activated = abap_false.
RETURN.
ENDIF.
TRY.
DATA(delete_after) = cl_abap_tstmp=>add( EXPORTING
tstmp = CONV timestampl( me->_now( ) )
secs = keep_track_log_in_minutes * 60 ).
CATCH cx_parameter_invalid_range cx_parameter_invalid_type.
ENDTRY.
UPDATE zos_sess_track SET ended_at = @( me->_now( ) ),
rec_delete_after = @delete_after,
is_finished =
WHERE uuid = ->session_int_uuid.
IF sy-subrc = 0 AND commit = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.   Linking sessions (example of linking a subsequent bgPF session):   METHOD link_subsequent_session.
IF zcl_os_session_tracker=>tracker_activated = abap_false.
RETURN.
ENDIF.
INSERT zos_sess_links FROM @(
VALUE #( parent_session_id = parent_sess_id
child_session_id = subseq_sess_id
bgpf_mon_string = bgpf_monitor_string
job_name = jobname
job_count = jobcount ) ).
IF sy-subrc = 0 AND commit = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.  All the information gathered with the class above is saved in custom database tables to be used and checked later.Since I also want to catch possible runtime errors that might occur in the middle of a session, the start() and end() methods execute a COMMIT WORK by default (remember, I am using this in the uncontrolled scenario; for the controlled one, COMMIT WORK would not be possible, evidently). Below is a short sample of how the tool can be used for tracking sessions started from Eclipse by running the main() method:   METHOD if_oo_adt_classrun~main.

DATA(random) = cl_abap_random=>create( cl_abap_random=>seed( ) ).
DATA(current_session_id) = |TEST_BGPF_MAIN_{ random->int31( ) }|.

zcl_os_session_tracker=>session( current_session_id )->start( ).

_start_new_bgpf_udemo_unit( parent_sess_id = current_session_id ).

zcl_os_session_tracker=>session( current_session_id )->end( commit =
abap_false ).
COMMIT WORK.

out->write( ‘A new test for ABAP Session tracker was started. Check
also subsequent bgPF units’ ).

ENDMETHOD  All in all, this small project allows me to have a comprehensive view of the ABAP internal sessions that I start with my custom code in ABAP Cloud, as shown in the image below:Figure 2 – Session-tracked data gathered by the toolThe information consists of the following fields: session ID – generated to identify a sessionWork Process type –  dialog or backgroundsession starting point – the first program in the call stack starting the sessioncurrent place in call stack – place where I call the start() method in the call stackstart time – timestampend time  – timestampdelete record after  – timestampsession is finished successfully – boolean bgPF monitor string – string generated by the bgPF framework when creating a new bgPF unitjob count – job informationjob name – job informationIn addition to the start and end timestamps information, I also persist the job identifier (job name and count) for the background sessions and the bgPF monitor string generated when creating a new bgPF unit. This is very useful if I want to retrieve the status of that job/bgPF unit programmatically later.Also, I assign these tracking records a lifetime value to avoid overcrowding the database. A background job automatically deletes these records when they expire.The above-mentioned background job is running periodically and checks the sessions that were started more than one hour ago (for sessions processed by dialog WPs) or one day ago (for sessions processed by background WPs) and have not finished yet. This is how I identify potential failed sessions and send necessary alerts when needed.Last but not least, this functionality can be activated and deactivated according to the developer’s needs as it may not always be necessary to have it active in a productive system. You can also use this tool for tracking sessions with controlled LUWs, but you must ensure that no commit work is executed, and be aware that runtime errors cannot be identified in this case. ConclusionI developed this small utility tool to help track and log internal sessions, measure performance, and identify potential runtime errors. This can also serve as a starting point for automating the maintenance of complex custom ABAP developments by monitoring ABAP internal sessions, gathering more information about them (started as bgPF or jobs), and sending alerts to the appropriate teams when vital processes exhibit unusual behavior.As I conclude this small presentation, I would like to find out your thoughts and opinions on the topics mentioned. References:https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmemory_organization.htmhttps://help.sap.com/docs/abap-cloud/abap-concepts/controlled-sap-luwhttps://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenepp.htm This article also appeared on Linked-in: https://www.linkedin.com/pulse/working-internal-sessions-abap-cloud-octavian-mihail-savu-tkmlf/?trackingId=IfI%2BV54JTt%2BuSnpwmYUveg%3D%3D        Read More Application Development Blog Posts articles 

#SAP

You May Also Like

More From Author