persisting application logs: LUW independent using a service connection
If you want to persist a log to the database for later analysis, regardless of LUW handling or ownership of the LUW, you may benefit using a secondary database connection. More specifically, in this case, a service connection.
What do I mean when I say "regardless of LUW handling or ownership of the LUW"? There are times when you write code for others to consume, and in doing so, you can't always, with certainty, know if it is ok to use COMMIT WORK.
or ROLLBACK WORK.
statements (or any other explicit/implicit transaction-influencing statements). You might end up breaking the LUW of the calling program, which could lead to inconsistencies (or worse).
There are ways around this. You could, for example:
- Merge logs (fiddling with instances and implementations, maybe manually merging them, yes - i know - interfaces exist)
- Allow for a pass-through of log instances (could also result in fiddling)
- Expose your commit control via parameters
- Add delimiter messages making it clear who is logging what (i.e., when adding messages to existing log instances)
While all of these approaches have their merits, they do not solve the issue I'm referring to. You are still dependent on how the LUW is managed by someone else, and you rely on this someone to willingly accept your messages/logs and adding/persisting them accordingly (that includes error scenarios).
So what does that leave us with?
aside: application log in question
When talking about logging, I refer to any and all classes that make use of the classical BAL (Business Application Log). In EWM the class /SCWM/CL_LOG
comes to mind, which is often used as a base class (or as a composite) for a custom class.
If you don't want to build your own, there are a few modern logging wrappers out there, publicly available on GitHub:
- open-abap-bal
- abap-message-logger and last but not least
- abap-logger
using the service connection
To utilize the service connection in BAL you only need the good old function module BAL_DB_SAVE
. It has two rather unknown and therefore also mostly unused parameters that make this possible:
i_2th_connection
andi_2th_connection_commit
.
If you've used the class /SCWM/CL_LOG
in EWM, you may need to add this option of saving logs yourself, as it is not made available there by default.
Using this service connection allows us to persist our log independently, including an actual COMMIT
, without violating the current active LUW and thereby avoiding issues or inconsistencies for the LUW owner.
" Regular, sync approach
" ... add messages
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_t_log_handle = handles
EXCEPTIONS
log_not_found = 1
save_not_allowed = 2
numbering_error = 3
OTHERS = 4.
COMMIT WORK. " ⚠️ Could break caller's LUW
" Service connection approach - LUW independent
" ... add messages
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_t_log_handle = handles
i_2th_connection = abap_true
i_2th_connection_commit = abap_true
EXCEPTIONS
log_not_found = 1
save_not_allowed = 2
numbering_error = 3
OTHERS = 4.
" No COMMIT needed - handled internally via service connection
Visual learner? (click me)

By making use of the parameter i_2th_connection
the FM BAL_DB_SAVE
uses the internal FM BAL_DB_INTERNAL_NO_UPDATE_TASK
for persisting the logs. In there, all ABAP SQL statements make use of the CONNECTION
keyword.
In general, the FM BAL_DB_SAVE
allows you to save your logs
- sync
- sync via service connection
- async using UPDATE TASK
Please note: This isn't supposed to be a full, extensive & exhaustive analysis or documentation of BAL_DB_SAVE
. So, if in doubt, have a look at the code and documentation yourself!
aside: DB connections
The service connection used by BAL can be found in the corresponding include (depending on environment) SBAL_CONSTANTS
and is called R/3*SAP_2TH_CONNECT_APPL_LOG
. You can identify it as a service connection by its prefix of R/3*
(yes, this prefix is also used in S/4 systems). As you can see by its name, this is a very specific connection for exactly this task. If you have a similar use case for a service connection, you may create and name it however you see fit (as long as you follow the conventions in the docs).
There are scenarios where using service connection may not make sense. Some examples could be:
- Performance and resource considerations: as opening and managing database connections is not for free
- Transactional cohesion: the log is tightly coupled with the LUW and should not exist on its own (e.g., audit logs, financial transactions)
- Testing scenarios or simulations
You can review your system's primary and secondary database connections, as well as its service connections, using transaction DBACOCKPIT
.
References/Links