Another logger for SAP

Every programmer in his life should at least once write his own logger.
Popular saying
Today I would like to tell you how to use the application log in my developments, and also offer the community another bike designed to make life a little more comfortable.

Thus, Application Log, also known as SLG0, and SLG1...

SAP standard

The application log is a great help in debugging and supporting new developments, especially background tasks, web services and interfaces using WebDynpro technologies, that is, in cases where it is not always possible or simply inconvenient to use the debugger. Magazine is standard SAP functionality, so it is always at your service.

You can view the log in a transaction SLG1:

At the top, logs for the specified period are displayed, at the bottom - messages recorded in the selected log.


Each log has two main attributes: an object and a subobject . This allows you to share the entire mass of magazines created in the system by development area and specific application, for example: an object Z_WEB_SERVICESand a subobject EXCHANGE_RATEfor a service for receiving exchange rates.

To maintain objects and subobjects, transaction SLG0 is used.
Step 1. The record is added in two steps: on the first screen the name of the object is determined:

Step 2. Then for the new object, in the tree on the left, “Subobjects” are selected, and a subobject is created:

How to use it

To add log support to your application, it is enough to use the following functional modules:

  • BAL_LOG_CREATE - creates a new journal and returns its identifier
  • BAL_LOG_MSG_ADD - adds a message to the log by identifier
  • BAL_DB_SAVE - saves logs with the specified identifiers in the database

By the way, it BAL_DB_SAVEaccepts a list of identifiers as input and allows you to save several logs at once.

Sample code and result in SLG1 (View Log)
GitHub  Gist source code : z_log_test.abap

More about messages

In the previous examples, the log is not much different from a simple text file. However, in SAP logs, a message has a larger set of properties than date and text, and each of them can be used to filter and group records when viewing a journal, some of which are presented in the diagram:

  1. Message type - the icon color when viewing the log depends on this parameter
  2. Importance level - entries are automatically divided into categories by this attribute
  3. Sorting criteria - a three-character word, a sign for grouping and sorting messages
  4. Level of detail - a number from 1 to 9 inclusive, can participate in filters
  5. Additional information - an arbitrary set of parameters and a link to a functional module or procedure for displaying it. It can be used, for example, to attach the HTTP response header of a server to a data transmission error message, or to invoke a transaction with parameters

When viewing it, it looks as follows

Another logger

The more message properties are used, the more logging code grows, which is essentially secondary. To solve this problem, and just for the sake of convenience, developers often create auxiliary routines in separate inclusions or write their own functional modules and classes.

When designing my bike, I tried to find the optimal combination of functionality and convenience. It turned out to implement:

  • Writing messages from classes and just text from a string
  • Separation by importance, level of detail, specification of sorting criteria
  • Filter messages with a specified level of detail before logging
  • An easy way to define your own logic for displaying message details


First you need to get an instance of the object using the static method INSTANTIATE.
Arguments - object, subobject and external identifier:

CALL METHOD zbc_cl_log=>instantiate
    iv_object      = gc_object
    iv_subobject   = gc_subobject
    iv_external_id = gc_external_id
    ro_log         = go_log.

The external identifier parameter is displayed as text in a separate column of the list of magazines and helps you find the right one with your eyes.

Logging of messages is done by the method WRITE:

CALL METHOD go_log->write
    iv_type    = zbc_cl_log=>info
    iv_text    = 'Document Source (XML)'
    iv_class   = zbc_cl_log=>class_additional_information
    iv_level   = zbc_cl_log=>level_info
    iv_sort    = 'XML'
    iv_details = gv_xml_b
    iv_viewer  = 'ZBC_LOG_VIEWER_XML_XSTRING'.

The level of the message filter before writing to the log is determined using the method THRESHOLD, the only parameter of which can take any value from certain constants LEVEL_*or LEVEL_NO_THRESHOLD- in this case, all messages will be recorded. According to my observations, there are always a lot of magazines, and sooner or later there comes a moment when their mass affects the overall system performance. The level filter allows you to disable the recording of "superfluous" parts at the moment.

For the transmission of message details is used IV_DETAILS, and the name of the functional module that is responsible for displaying the display of this data on demand - IV_VIEWER. Inside the method WRITE, the data transferred toIV_DETAILS TYPE ANY, in XML with the help of transformation ID, and at the time of accessing them when viewing, the data is unpacked and transferred to the specified function module.

This approach gives rise to several features:

  • the WRITEvalue supplied to the method must be of a dictionary or elementary type;
  • the viewing function module must declare a parameter of the same type;
  • this parameter should be called I_DATA.

If it GV_XML_Bis of type XString, then the interface of the function module will be as follows:

FUNCTION zbc_log_viewer_xml_xstring .
*"*"Local Interface:
      xml_string = i_data
      OTHERS     = 0.

Instead of a conclusion

So far I have not had to try this solution on my project, and almost certainly there are bugs, shortcomings or even errors that have not yet been noticed, and I will be grateful for any comments on the development code and design. Sources are available on GitHub in the form of Nugget and Slinkee files - you can install yourself using SAPlink, an ABAP code exchange tool.

GitHub repository:
SAPlink homepage:

Also popular now: