Building robust SAP applications goes beyond just implementing business logic observability matters too. Knowing what happened, when, and who triggered it is essential in any enterprise application.
The ABAP RESTful Application Programming Model (RAP) is SAP's strategic framework for building cloud ready, transactional applications on S/4HANA and BTP. As RAP applications handle real business operations, we need a reliable way to track and audit those operations at runtime.
This is where Application Logging comes in.
In this blog, we walk through implementing Application Logging inside a RAP Business Object using Determinations as the trigger and the classic BAL function module API to write structured, queryable logs giving your application a solid audit trail from day one.
Assume you are working on a RAP Business Object that handles day to day business transactions such as employee records, purchase orders, or sales data exposed as a Fiori Elements UI.
The requirement is every time a record is created, modified, or deleted, the system must automatically capture a log entry recording the operation performed and the user who triggered it, for audit and compliance purposes.
To achieve this, we implement Application Logging inside RAP Determinations which fire automatically on each CRUD operation, write a structured log entry using the BAL function module API, and store it persistently queryable anytime via Transaction SLG1.
The Application Log (also known as BAL, Business Application Log) is SAP's built in, structured logging framework for capturing runtime messages within ABAP programs. It provides a centralized, persistent store for messages generated during application processing errors, warnings, informational messages, and success confirmations.
Unlike simple WRITE statements or MESSAGE commands that display output on screen, Application Logs are:
In the classic ABAP world, Application Logs are managed using the BAL family of function modules. In the ABAP Cloud / S/4HANA Cloud world, SAP has introduced the newer object oriented API using CL_BALI_LOG. In this blog, we use the classic BAL API, which is fully supported in on premise S/4HANA systems.
Application Logs serve a wide range of practical purposes in enterprise SAP development:
Audit Trail Track who created, changed, or deleted a business record. This is critical for compliance in HR, Finance, and Procurement scenarios.
Error Tracking Capture exceptions and error messages during background processing so that administrators can investigate failures without needing a debugger.
Data Monitoring Record the state of key fields at the time of a business operation, providing a historical snapshot for analysis.
User Activity Logging Monitor which users are performing which operations, useful for security reviews and access audits.
Troubleshooting Support Give basis teams and functional consultants a self-service tool to check what went wrong, without needing developer involvement every time.
Background Job Monitoring Attach logs to Application Jobs so that job output is neatly stored and reviewable after execution.
In our scenario, we use Application Logs to build an automatic audit trail for all CRUD operations on the Employee Business Object a requirement common in virtually every enterprise SAP project.
Goto Tcode : SLG0, object and click ‘New Entries’
Enter the Object and Object text and save it , now select the object click Sub object and click new entries and save it.
SLG1 is used to track based on log and sub object.
Using determination in Behaviour definition
determination data_log_create on modify { create; }
determination data_log_update on modify { update; }
determination data_log_delete on modify { delete; } Implementing Application log in implementation class
creating helper class
CLASS lcl_log_helper DEFINITION.
PUBLIC SECTION.
CLASS-METHODS write_log
IMPORTING
iv_emp_id TYPE string
iv_operation TYPE string
iv_msgty TYPE symsgty DEFAULT 'I'.
ENDCLASS.
CLASS lcl_log_helper IMPLEMENTATION.
METHOD write_log.
DATA: lv_log_handle TYPE balloghndl,
ls_log TYPE bal_s_log,
ls_msg TYPE bal_s_msg,
lt_handles TYPE bal_t_logh.
" Log Header
ls_log-object = 'ZNVT_LOG5'.
ls_log-subobject = 'ZNVT_SUB5'.
ls_log-aldate = sy-datum.
ls_log-altime = sy-uzeit.
ls_log-aluser = sy-uname.
ls_log-alprog = sy-repid.
" Create Application Log
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = ls_log
IMPORTING
e_log_handle = lv_log_handle
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
RETURN.
ENDIF.
" Message
CLEAR ls_msg.
ls_msg-msgty = iv_msgty.
ls_msg-msgid = 'ZNVT_MSG_01'.
ls_msg-msgno = '003'.
ls_msg-msgv1 = iv_emp_id.
ls_msg-msgv2 = iv_operation.
ls_msg-msgv3 = sy-uname.
" Add Message to Log
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = lv_log_handle
i_s_msg = ls_msg
EXCEPTIONS
OTHERS = 1.
" Save Log
APPEND lv_log_handle TO lt_handles.
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_client = sy-mandt
i_t_log_handle = lt_handles
EXCEPTIONS
OTHERS = 1.
ENDMETHOD.
ENDCLASS. " CREATE LOG
METHOD data_log_create.
CHECK keys IS NOT INITIAL.
READ ENTITIES OF znvt_i_demo1
ENTITY znvt_i_demo1
FIELDS ( Id Name Place )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_entities)
FAILED DATA(ls_failed).
LOOP AT lt_entities INTO DATA(ls_entity).
lcl_log_helper=>write_log(
iv_emp_id = CONV string( ls_entity-Id )
iv_operation = 'created'
iv_msgty = 'S' ).
ENDLOOP.
ENDMETHOD.
" UPDATE LOG
METHOD data_log_update.
CHECK keys IS NOT INITIAL.
READ ENTITIES OF znvt_i_demo1
ENTITY znvt_i_demo1
FIELDS ( Id Name Place )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_entities)
FAILED DATA(ls_failed).
LOOP AT lt_entities INTO DATA(ls_entity).
lcl_log_helper=>write_log(
iv_emp_id = CONV string( ls_entity-Id )
iv_operation = 'updated'
iv_msgty = 'I' ).
ENDLOOP.
ENDMETHOD.
" DELETE LOG
METHOD data_log_delete.
CHECK keys IS NOT INITIAL.
LOOP AT keys INTO DATA(ls_key).
lcl_log_helper=>write_log(
iv_emp_id = CONV string( ls_key-Id )
iv_operation = 'deleted'
iv_msgty = 'W' ).
ENDLOOP.
ENDMETHOD.
execute the tcode SLG1 with Object and Sub object
Create
Performed Create operation in RAP now checking SLG1
Update
Performed Update operation in RAP, checking logs in SLG1
Delete
Deleted the record, and checking logs in SLG1
In this blog, we implemented a complete, Application Logging solution inside a RAP Business Object. Here is a summary of everything we covered:
We started with the Application Log infrastructure understanding what it is, why it matters, and how to configure Log Objects and Sub objects in SLG0. We then built the Behavior Definition using Determinations as the clean, non-intrusive hook for triggering log writes on Create, Update, and Delete operations. Inside the implementation class, we used a reusable helper class pattern to keep the logging logic maintainable and walked through each BAL function module BAL_LOG_CREATE, BAL_LOG_MSG_ADD, and BAL_DB_SAVE understanding their role, parameters, and sequence. Finally, we verified the output end to end in SLG1.
This approach gives your RAP application a professional grade audit trail with minimal overhead. The helper class pattern makes it trivial to extend logging to new entities or operations, and the use of message types (S/I/W) provides instant visual clarity in SLG1 for anyone monitoring the system.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 85 | |
| 41 | |
| 23 | |
| 20 | |
| 17 | |
| 14 | |
| 10 | |
| 10 | |
| 10 | |
| 10 |