As an experienced trouble-shooting expert you certainly encountered the ABAP statement LOG-POINT.
Using statement LOG-POINT in ABAP you can

  • log the content of nearly all kinds of variables – including internal tables
  • specify an arbitrary subkey for log event aggregation
  • switch on logging dynamically by using transaction SAAB

But as this kind of logging uses dedicated ABAP statements the source code has to be prepared beforehand. However, there is lots of ABAP code around, which is not prepared for logging yet.

What if you need to analyze such code without the possibility to change it, e.g. in a productive system?

New: Setting logpoints dynamically

With dynamic logpoints (available with SAP NW ABAP 7.5) you can now set logpoints dynamically -much like you set breakpoints- at arbitrary source code positions and even in productive systems (as long as you have the necessary privileges).
To set a dynamic logpoint simply right-click the marker bar next to the source code line, where you usually set a breakpoint. In the context menu simply click on “Add Logpoint…”.

DLP1.jpg

In the “Add Logpoint” dialog you can choose between different predefined activities for different use cases, like “Log Simple Variable Values”, “Log Call Stack” and more or you can use the more advanced “User-Defined Logging”, where you can enter the variables to be logged, the key for aggregation and an optional condition in a free-style way.

DLP_2.jpg

But let us first have a look at a simple example.

Example 1: Logging simple variables

Function module RS_TABLE_LIST_CREATE is used by transaction SE16 to create, generate and call the ABAP report needed to display the individual database table contents. It takes a parameter TABLE_NAME, which is the name of the database table to be displayed.

We now want to know, which database tables are being displayed in our system and how often.

Therefore, set a dynamic logpoint at the first executable line of the function module RS_TABLE_LIST_CREATE, choose activity “Log Simple Variable” for your logpoint and specify variable TABLE_NAME as variable to be logged:

DLP_3.jpg

Don’t limit the logpoint activation for specific users or application servers. Just leave the “Activation” section as is and press “finish”. Now your logpoint is activated for all users at all servers and the system collects the log data for you.

In the source code, you can now see the red logpoint symbol in the marker bar. Hover over the symbol and you’ll see the logpoint properties at a glance.

DLP_4.jpg

After a while you want to see your log results, so switch to the logpoint view. Refresh the display by using the “Collect logs …” button:

DLP_5.jpg

In the example described here 7 log events have been collected after a while.

DLP_6.jpg

If you now highlight the logpoint entry of RS_TABLE_LIST_CREATE, the result display comes up at the right side of the logpoint view:

DLP_7.jpg

You can now see the individual database table names and how often they have been displayed in the system using transaction SE16.

Example 2: Who is calling my service? (Log Call Stack)

If you need to change the behavior of a specific service  (e.g. a function module or method), you should know, who is calling it. The information of the direct caller might be sufficient sometimes, but often you need to know the complete ABAP call stack for a deeper analysis.

How can we tackle such a task with dynamic logpoints?

Assume that we are interested in a special service that is the UTC time stamp conversion to system time implemented in method CL_ABAP_TSTMP=>SYSTEMTSTMP_UTC2SYST. We now want to analyze, who is calling the service and how often.

This is rather simple. Just set a dynamic logpoint at e.g. the first line of the method implementation and use the predefined activity “Log Call Stack”.

DLP_8.jpg

Activate the logpoint and after a while switch to the logpoint view to have a look at the results.

It may look like this.

DLP_9.jpg

On the left side of the result display hash key values can be found, representing all individual ABAP stack hierarchies the method CL_ABAP_TSTMP=>SYSTEMTSTMP_UTC2SYST was called from. The “Log Events” column on the right side tells you how often this has happened. If you navigate into the details of one result display row, you can see the involved ABAP stack in the column “Field Values”.

So you just need a few clicks to get complete information about how often a dedicated service was called in a system and who called it along with detailed information about the ABAP call stack.

But now you may ask yourself:

Where do the hash key values come from and what they are good for?

To answer this, we first need to look at the more advanced activity “User-Defined Logging” in the next example.

Example 3: Log the number of ALV items displayed by the transactions executed in the system

In this example you will see, how easy it is to detect the transactions in your system, which are using ALV and how many list items they show. A glimpse of the content displayed by ALV can also easily be added.

To realize this you should use the activity “User-Defined Logging”, with the input fields “Key Definition”, “Field Values” and an “Optional Condition”.

Now set a dynamic logpoint at the first executable line of function module REUSE_ALV_GRID_DISPLAY. Parameter T_OUTTAB contains the data to be displayed.

DLP_10.jpg

In the key definition specify the built-in functions req_type() and req_entrypoint(), which are returning the request type and the name of the current request (e.g. “TA” and “SM50”). Then the literal ‘ALV lines:’ is used for better readability and finally the built-in function lines( ) puts the number of lines of table T_OUTTAB[] into the key string.

In the Field Value section specify the first line of table T_OUTTAB[], just to get an idea what kind of data is displayed in the current transaction.

Last but not least you may want to limit the logging to certain users, which can be done in the condition, like it is shown above.

After a while you get results like this:

DLP_11.jpg

You can now clearly see what requests/transactions are using ALV, how many lines they are showing and how often they have been called in the system.

In this example, we used the built-in functions

  • req_type( )
  • req_entrypoint( )
  • lines ( )

But there are more.

Other useful built-in function are for example

  • stack_hash( )
  • stack( )

The stack_hash( ) function returns a hash key of the current ABAP stack, while function stack( ) delivers the current ABAP stack itself in an internal table.

Now you can understand, what the activity “Log Call Stack” in example 2 is doing: It pre-fills the “Key Definition” input field with stack_hash( ) and writes function stack( ) into the “Field Values”.

The unique hash value returned by stack_hash() makes the system to count similar and collect different ABAP stacks, while function stack( ) puts the ABAP stack into the “Field Values” of the result display by returning an internal table, filled with the ABAP stack.

Summary

You have seen how easy it is to configure, start and display your individual tailor-made analysis with dynamic logpoints.

Use the predefined activities, like “Log Simple Variable Values” or “Log Call Stack”, wherever it is sufficient for you and use the full-fledged flexibility of the “User Defined Logging”, where you need it. There is nearly nothing you can not do with dynamic logpoints.

And the best thing is: you not even have to change the source code for it!

To report this post you need to login first.

8 Comments

You must be Logged on to comment or reply to a post.

  1. Vitaliy Tarusin

    Hi, Christoph,

    powerful feature!

    Thanks!

    Since information collected on the Application servers,

    it must be possible to set such Dynamic Logpoints also via SAPGUI Editor.

    Isn’t it?

    (0) 
    1. Christoph Stoeck Post author

      Hi Vitaliy,

      no, ABAP developers should use this feature in ADT.

      We don’t have a  full-fledged support of Dynamic Logpoints in SAPGui, sorry.

      Best Regards,

      Christoph

      (0) 
  2. Christian Guenter

    Hi Christoph,

    nice blog about a powerful feature. Thanks for that.

    I asked myself whether it is possible to log the whole content of “simple” internal tables. So i did a short experiment. Consider the following code

    DATA(rnd) = cl_abap_random_int=>create(

                        seed = CONV #( sy-uzeit )
                        min  = 0
                        max  = 100 ).

    DATA(random_numbers) = VALUE int_tab1(

                             FOR n = 0

                             WHILE n < 10

                             ( rnd->get_next( ) ) ).

    I’d like to log the “random_numbers” internal table. I did it with the following settings.

    2016-02-17 19_39_53-Logpoint hinzufügen.png

    And executed the code 3 times. This is the result.

    2016-02-17 19_36_50-ABAP - Programm Z_TEST_DEBUG [A4H] - Aktiv - A4H_001_developer_en_1 - Eclipse.png

    So my conclusion is that it is not possible to track the content of whole internal tables, right? Or did i something wrong? Or is it possible with User-Defined Logging to log whole internal tables?

    I’m on 7.50 SP01 and ADT 2.54.8.

    Thanks for clarifying.

    Regards Christian

    P.s. Sorry for the german text in the screenshots. My eclipse installation always mixes german and english up and i don’t know why…

    (0) 
    1. Armin Beil

      Hi Christian,

      The predefined activity “Log Simple Variable Values” is only suitable for simple (non-structured) variables. If you want to log the values of structures or internal tables you should use the activity “User-Defined Logging” and add the variable names to the “Field Values”. For objects you can not enter the object name (as far as I know) but instead you have to use the attribute names and add “objectname->attribute” to the “Field Values”.

      Best regards,

      Armin

      (0) 
      1. Christian Guenter

        Hi Armin,

        thanks for the hint. With the “User-Defined Logging it works as expected. Now i have another question. If logpoint was reached 2 times and i want to inspect both logs, at first sight it seems to me that i only can inspect the last log. Is this right or am i missing the obvious?

        For example this log point. There are 2 log events, but i can only see the values of the last one.

        2016-05-20 10_01_32-ABAP_2 - Program Z_TEST_LOGPOINT [DVE] - active - DVE_010_guenterc_en - Eclipse.png

        Thank you for your support.

        Regards Christian

        (0) 
        1. Armin Beil

          Hi Christian,

          whatever you define in the section “Key Definition” will be used as key for aggregation. In your example the key definition is empty and therefore the two results are aggregated. That means the number of log events increases to 2 and the logged field values of the first execution are overwritten by the second execution.

          Try to enter “system_info( TstmpS )” into the section “Key Definition” during logpoint creation in order to log the field values for both executions. For more information about built in functions like “system_info” you can also check the F1 help within eclipse.

          Best regards,

          Armin

          (1) 

Leave a Reply