Standard or Custom Class for Application Logs? – Part 1 (2024)

Or as an alternative title ‘Why Do ABAP Developers Write Their Own Classes for Application Logs?

This is a blog series about Business Application Log, consisting of the following chapters:

  • Drag Race Between Three Classes
  • Displaying an Application Log in a Resizable Window
  • Customizing Log Display Using Display Profiles
  • A Custom Class for Application Log

Pre-race

In a very normal world, we create log objects to collect messages (from the SYST structure, exceptions, BAPI, or batch input). We then save the log and optionally display it. This means we basically have 4 steps: create, collect, save, and display. In some scenarios, we may have additional requirements such as deleting or inserting messages.

As a developer, I prefer to use a pure standard class that is present in every system and does not contain any specific logic. Does such a class exist? Let’s find the answer.

It is possible to reach a list of classes that can be related by searching with CL*LOG* and CL*MESSAGE* patterns in transaction SE24. Eventually something like the following list remains:

  • CL_BAL_LOG
  • CL_BAL_LOGGER
  • CL_BAL_LOGGING
  • CL_BAL_LOGOBJ 🏎️
  • CL_LOG_PPF
  • CL_PTU_MESSAGE 🏎️
  • CL_PTU_MESSAGE_N
  • CL_RECA_MESSAGE_LIST 🏎️
  • CL_SBAL_LOGGER

Let’s include those written in bold text in a drag race¹ and see how functional they are. Others were eliminated because they did not have adequate methods to participate in the race.

⚠️ Note that not all of these classes may be available on your system.

Drag Race Between Three Classes

First, we will compare some methods of the selected classes. Second, we will write sample code for each of them. Let’s see which one crosses the finish line first, 402 meters away. 🏁

Method Comparison

CL_BAL_LOGOBJCL_PTU_MESSAGECL_RECA_MESSAGE_LIST
PurposeMethodMethodMethod
Create log– CONSTRUCTOR– CONSTRUCTOR

ℹ️ There is a factory class for creating a log.

CF_RECA_MESSAGE_LIST=> CREATE

Add text

– ADD_STATUSTEXT

– ADD_ERRORTEXT

– ADD_TEXT

– ADD_TIME_STAMP

– ADD_EMPTY_LINE

N/A
Add message– ADD_MSG

– ADD_MESSAGE

– ADD_MESSAGE_SIMPLE

– ADD_MESSAGE_COMPLETE

– ADD

– ADD_SYMSG

Add exception

– ADD_EXCEPTION

ℹ️ Previous messages in the exception chain are not added.

N/A

– ADD_FROM_EXCEPTION

ℹ️ Previous messages in the exception chain are not added.

Add BAPI messagesN/A

– ADD_BAPIRET2

– ADD_BAPIRET2_TAB

– ADD_FROM_BAPI
Add batch input messagesN/AN/AN/A
Insert messageN/AN/A– INSERT
Set level of detail

– DECREMENT_DETLEVEL

– INCREMENT_DETLEVEL

Yes, as an input parameter in related methods– SET_DETAIL_LEVEL
Cumulate messagesN/AYes, as an input parameter in related methodsYes, as an input parameter in related methods
Delete message (from memory)N/AN/A– DELETE_MESSAGE
Delete all messages (from memory)– REFRESH– DELETE_MESSAGES– CLEAR
Delete log (from DB)N/A– DELETE_LOGN/A
Get log handle– GET_HANDLE– GET_HANDLE– GET_HANDLE
Get log numberYes, as a return parameter when the log savedYes, as a return parameter when the log savedN/A
Get log headerN/A– GET_LOG_HEADER– GET_HEADER
Get all messagesN/A– GET_MESSAGES

– GET_LIST

– GET_LIST_X

– GET_LIST_AS_BAPIRET

Get statisticsN/A– GET_MESSAGES– GET_STATISTICS

Has messages?

Is empty?

N/A– HAS_MESSAGES

– IS_EMPTY

– COUNT

Save log– SAVE– SAVE_LOG– STORE
Display log

– DISPLAY

✅ Display profiles can be used.

– DISPLAY_LOG

⚠️ Display profiles can not be used.

ℹ️ There is no method to display the log, but function RECA_GUI_MSGLIST_POPUPcan be used.

N/A: Non available

Now let’s take a look at some simple code examples of how to use these classes.

↑ Top

Usage example of theCL_BAL_LOGOBJclass

📄 ABAP code

TRY. " Create the log DATA(appl_log) = NEW cl_bal_logobj( i_log_object = 'APPL_LOG' i_default_subobject = 'OTHERS' i_extnumber = 'CL_BAL_LOGOBJ' ). " Add a message MESSAGE s361(00) INTO DATA(msgtext). appl_log->add_msg( i_probclass = if_bal_logger=>c_probclass_none ). " Add an exception TRY. RAISE EXCEPTION TYPE cx_demo_constructor. CATCH cx_demo_constructor INTO DATA(exception). appl_log->add_exception( exception ). ENDTRY. " Save the log appl_log->save( IMPORTING et_lognumbers = DATA(log_numbers) ). " Display the log appl_log->display( ). CATCH cx_bal_exception.ENDTRY."TRY ." cl_demo_output=>write( |CL_BAL_LOGOBJ log number: { log_numbers[ 1 ]-lognumber }| )." cl_demo_output=>write( |CL_BAL_LOGOBJ log handle: { log_numbers[ 1 ]-log_handle }| )." cl_demo_output=>display( )." CATCH cx_root."ENDTRY.

🖥️ Output

Standard or Custom Class for Application Logs? – Part 1 (1)

💭 Comments

This class is included in SAP standard. (Package: SZAL, Application Component: BC-SRV-BAL).Although it does not contain methods for adding BAPI and BDC messages, it can be used for basic needs. Note that there is no method that returns the collected messages. Therefore, this class can be used to collect messages and to save and display logs.

☢️ Important note

This class also has a method called ADD_DEBUG_MESSAGE which can be used to add a message with the call stack. If this method is used with the parameter I_DETLEVEL and the log is displayed with the display profile “hierarchy by message detail level”, a runtime error CONVT_NO_NUMBER occurs. This is because the following line in CL_BAL_LOG_BASE->IF_BAL_LOGGER~ADD_DEBUG_MESSAGE has an incorrect assignment:

l_s_msg-detlevel = if_bal_logger~mv_loghandle.

The runtime error occurs in the DETLEVEL_FILL macro in LSBAL_DISPLAY_BASEF05. (Line 344). Therefore, the ADD_DEBUG_MSG method should not be used when messages are to be displayed by detail level.

An example code to reproduce the error:

DATA display_profile TYPE bal_s_prof.CALL FUNCTION 'BAL_DSP_PROFILE_DETLEVEL_GET' IMPORTING e_s_display_profile = display_profile.TRY. DATA(log) = NEW cl_bal_logobj( ). log->add_debug_msg( i_detlevel = '1' ). log->display( i_disp_profile = display_profile ). CATCH cx_bal_exception .ENDTRY.

↑ Top

Usage example of the CL_PTU_MESSAGE class

📄 ABAP code

" Create the logDATA appl_log TYPE REF TO cl_ptu_message.DATA(log_header) = VALUE bal_s_log( object = 'APPL_LOG' subobject = 'OTHERS' extnumber = 'CL_PTU_MESSAGE' ).CREATE OBJECT appl_log EXPORTING is_log = log_header EXCEPTIONS OTHERS = 3.CHECK appl_log IS BOUND." Add a messageMESSAGE s361(00) INTO DATA(msgtext).appl_log->add_message_simple( EXPORTING iv_level = CONV #( if_bal_logger=>c_probclass_none ) )." Add BAPI messagesDATA bapiret2_tab TYPE bapiret2_tab.CALL FUNCTION 'BAPI_FLIGHT_GETDETAIL' EXPORTING airlineid = VALUE bapisflkey-airlineid( ) connectionid = VALUE bapisflkey-connectid( ) flightdate = VALUE bapisflkey-flightdate( ) TABLES return = bapiret2_tab.appl_log->add_bapiret2_tab( EXPORTING it_bapiret2 = bapiret2_tab )." Save the logappl_log->save_log( IMPORTING es_new_lognumber = DATA(log_number) EXCEPTIONS OTHERS = 2 )." Display the logappl_log->display_log( EXPORTING iv_as_popup = abap_true iv_use_grid = abap_true EXCEPTIONS OTHERS = 2 )."cl_demo_output=>write( |CL_PTU_MESSAGE log number: { log_number-lognumber }| )."cl_demo_output=>write( |CL_PTU_MESSAGE log handle: { log_number-log_handle }| )."cl_demo_output=>display( ).

🖥️ Output

Standard or Custom Class for Application Logs? – Part 1 (2)

💭 Comments

Although it is possible to collect BAPI return messages with this class, it does not include a method for collecting BDC messages. There is also no method for collecting exception messages. The inability to use display profiles is another disadvantage.

↑ Top

Usage example of the CL_RECA_MESSAGE_LIST class

📄 ABAP code

" Create the logDATA(msg_list) = cf_reca_message_list=>create( id_object = 'APPL_LOG' id_subobject = 'OTHERS' id_extnumber = 'CL_RECA_MESSAGE_LIST' ).CHECK msg_list IS BOUND.DATA(log_header) = msg_list->get_header( ).log_header-params-altext = 'Appl. log: Standard text'.msg_list->change_header( EXPORTING is_msg_header = log_header EXCEPTIONS OTHERS = 2 )." Add a messageMESSAGE s361(00) INTO DATA(msgtext).msg_list->add_symsg( EXPORTING id_probclass = if_bal_logger=>c_probclass_none )." Add BAPI messagesDATA bapiret2_tab TYPE bapiret2_tab.CALL FUNCTION 'BAPI_FLIGHT_GETDETAIL' EXPORTING airlineid = VALUE bapisflkey-airlineid( ) connectionid = VALUE bapisflkey-connectid( ) flightdate = VALUE bapisflkey-flightdate( ) TABLES return = bapiret2_tab.msg_list->add_from_bapi( EXPORTING it_bapiret = bapiret2_tab )." Add an exceptionTRY. RAISE EXCEPTION TYPE cx_demo_constructor. CATCH cx_demo_constructor INTO DATA(exception). msg_list->add_from_exception( io_exception = exception ).ENDTRY." Save the logmsg_list->store( EXPORTING if_in_update_task = abap_false EXCEPTIONS OTHERS = 2 )." Display the logCALL FUNCTION 'RECA_GUI_MSGLIST_POPUP' EXPORTING io_msglist = msg_list."cl_demo_output=>write( |CL_RECA_MESSAGE_LIST log number: Who knows? | )."cl_demo_output=>write( |CL_RECA_MESSAGE_LIST log handle: { msg_list->get_handle( ) }| )."cl_demo_output=>display( ).

🖥️Output

Standard or Custom Class for Application Logs? – Part 1 (3)

💭 Comments

This is the richest class in terms of method in the race. Strangely, it has no method for adding free text. Like other classes, it has no method for collecting BDC messages. The good thing is that there is a method for inserting messages. An original feature is the possibility to display the log in a resizable window. (The next chapter is about it)

⚠️This class may not be available in every system.

↑ Top

Conclusion

As you can see, each class has different methods. One has a method for collecting BAPI return messages, while the other has a method for collecting exception messages. One does not have a method to add custom text, while the other includes a method to add a message with a date/time stamp. However, not all three classes have a method for collecting batch input messages.

So who is the winner? Although none of the classes in the race really ticked all the boxes, the winner seems to be CL_RECA_MESSAGE_LIST.

Before we take a custom class to the next race, let’s make a pit stop here and take a look at a nice feature of the winner: Displaying an Application Log in a Resizable Window.

See you in the next chapter.

↑ Top

More Resources
  • For more resources on ABAP development, you can visit the ABAP Development topic page here, ask a question, or follow the ABAP Development blog here.
  • Please follow my profile for future posts and feel free to share your feedback or thoughts in a comment.
Endnotes
  • ¹ Drag racingis a type of motorsport that involves vehicles competing to see who can accelerate faster over a short distance, typically a quarter-mile (402 meters) or an eighth-mile (201 meters) straight track.

Trademarks

  • SAP®, ABAP® are the trademarks or registered trademarks of SAP SE or its affiliates in Germany and in other countries.

Disclaimer

  • All source code available in this blog post is provided “as is” without warranty of any kind, and any use of such source code is at your own risk.
Standard or Custom Class for Application Logs? – Part 1 (2024)

FAQs

What are SAP application logs? ›

The ABAP Application Log is used by applications to log messages regarding information, warning or errors. Using SAP Focused Run you can monitor the application log for different applications to be aware of critical messages, to proactively address errors and warnings in your ABAP system.

What are examples of application logs? ›

Generally, computer software records information to application logs when an event occurs. Examples can be a web server logging a data transfer, a database instance logging successful backup completion, or a firewall logging unsuccessful connection requests.

What is included in application logs? ›

Put simply, an application log is a file that contains information about events that have occurred within a software application. These events are logged out by the application and written to the file. They can include errors and warnings as well as informational events.

How do I view SAP application logs? ›

For convenience, there is a specific viewer for application log entries created by SAP Gateway processes. You can start the report in transaction /IWFND/APPS_LOG in the SAP NetWeaver SAP Gateway hub system or /IWBEP/VIEW_LOG in the SAP Business Suite backend system.

Where do I find application logs? ›

View the Windows application log
  • On the Search bar, type Event Viewer, and then select the Event Viewer desktop app.
  • In Event Viewer, expand the Windows Logs folder, and select the Application event log.
Feb 28, 2023

How do you access your application log files in SAP? ›

In the navigation area on the left, browse Log Files → Old Log Files and from the subdirectory whose name contains the time stamp of the session you want to view, select the log file you want to view.

How do you create an application log in SAP? ›

Step 1: Go to transaction SLG0. Step 2: Select the entry “/AIF/LOG” and double-click on “Sub-objects”. Step 3: Go to edit mode and create a new entry for interface IC0029 along with its namespace and Save. An entry for IC0029 gets created in SLG0.

Top Articles
Latest Posts
Article information

Author: Maia Crooks Jr

Last Updated:

Views: 6056

Rating: 4.2 / 5 (63 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Maia Crooks Jr

Birthday: 1997-09-21

Address: 93119 Joseph Street, Peggyfurt, NC 11582

Phone: +2983088926881

Job: Principal Design Liaison

Hobby: Web surfing, Skiing, role-playing games, Sketching, Polo, Sewing, Genealogy

Introduction: My name is Maia Crooks Jr, I am a homely, joyous, shiny, successful, hilarious, thoughtful, joyous person who loves writing and wants to share my knowledge and understanding with you.