Open Source Contribution: This project is community-driven and Open Source! 🚀
If you spot a bug or have an idea for a cool enhancement, your contributions are more than welcome. Feel free to open an Issue or submit a Pull Request.
- ABAP Cloud Logger
- Prerequisites
- License
- Contributors-Developers
- Motivation for Creating the Repository
- Usage Examples
- Design Goals-Features
- Changelog
- Roadmap
ABAP Logger Following Clean Core Principles.ABAP Cloud Logger is a modern, lightweight, and Clean Core-compliant logging library for SAP S/4HANA and SAP BTP ABAP Environment.
It acts as a fluent wrapper around the standard class CL_BALI_LOG, simplifying the Application Log API while ensuring strict adherence to ABAP Cloud development standards.
- SAP S/4HANA 2023 (or higher) OR SAP BTP ABAP Environment.
- XCO library availability
- Statement Compatibility from v758 and Cloud
This project is licensed under the MIT License.
The repository was created by George Drakos.
Logging is a tool I rely on almost every day while working with ABAP. I wanted to create a version that is not only simple and effective but also fully compatible with the ABAP Cloud environment. The goal is to provide an easy-to-use logger that fits naturally into cloud-ready development practices and can be integrated seamlessly into modern projects.
To start logging, get an instance of the logger by providing your Application Log Object and Subobject (defined in Eclipse as Application Log Object).
DATA(logger) = zcl_cloud_logger=>get_instance( object = 'Z_CLOUD_LOG_SAMPLE'
subobject = 'SETUP' ).TRY.
" Your business logic here
DATA(result) = 100 / 0.
CATCH cx_sy_zerodivide INTO DATA(error).
" Pass the exception object to the logger
lo_logger->log_exception_add( error ).
ENDTRY.logger->log_message_add( isymsg = VALUE #( msgty = 'W'
msgid = 'CL'
msgno = '000'
msgv1 = 'Test Message' ) ).logger->log_string_add( string = 'String Add'
msgty = 'E' ).logger->log_bapiret2_table_add(
bapiret2_t = return
min_severity = 'E' ).
logger->log_bapiret2_structure_add( VALUE #( ) ) .SELECT * FROM t001 INTO TABLE @DATA(company_codes) UP TO 10 ROWS.
" Log the whole table as JSON
lo_logger->log_data_add( company_codes ).DATA(message_count) = lo_logger->get_message_count( ).
DATA(messages_bapiret2) = lo_logger->get_messages_as_bapiret2( ).
DATA(messages) = lo_logger->get_messages( ).
DATA(messages_flat) = lo_logger->get_messages_flat( ).
DATA(messages_rap) = lo_logger->get_messages_rap( ).DATA(error_exists) = lo_logger->log_contains_error( ).
DATA(messages_exist) = lo_logger->log_contains_messages( ).
DATA(warning_exists) = lo_logger->log_contains_warning( ).
DATA(is_empty) = lo_logger->log_is_empty( ).DATA(handle) = logger->get_handle( ).
DATA(log_handle) = logger->get_log_handle( ).logger->save_application_log( ).data(specific_message_exists) = lo_logger->search_message( search = VALUE #( msgid = '00' ) )."Get a New Log Instance
DATA(new_logger) = zcl_cloud_logger=>get_instance( object = 'Z_MY_OBJECT_NEW'
subobject = 'Z_MY_SUBOBJECT_NEW' ).
"Add Message
new_logger->log_string_add( string = 'New Logger String'
msgty = 'E' ).
"Merge with Previous Log
logger->merge_logs( new_logger ).lo_logger->reset_appl_log( im_delete_from_db = abap_true )." 1. Start the stopwatch
logger->start_timer( ).
" 2. Execute a code block
"SELECT FROM.....
" 3. Stop and log the duration automatically
logger->stop_timer( 'Test Timer' ).logger->display( NEW zcl_cloud_logger_view_alv( ) ).logger->set_context( 'Order 100' ).
logger->log_string_add( 'Price checked' )."[Order 100] Price checked logged
logger->clear_context( ).- Install via ABAPGit
- ABAP Cloud/Clean Core compatibility.Passed SCI check variant S4HANA_READINESS_2023 and ABAP_CLOUD_READINESS/SAP_CP_READINESS
- Clean Code following Clean ABAP Style Guides
- Based on CL_BALI_LOG which is released for Cloud Development (could also use XCO_CP_BAL)
- Based on Multiton Design Pattern for efficient management of log instances
- Unit Tested
- Fluent Interface and method chaining
- Separate logging from viewing using the Strategy Pattern
- Internal error trail — new get_internal_errors() and clear_internal_errors() expose previously swallowed cx_bali_runtime exceptions. Bounded to 100 entries with FIFO eviction.
- Strict singleton validation — get_instance now raises zcx_cloud_logger_error on conflicting config instead of silently returning a mismatched instance.
- save_application_log no-op feedback — logs a warning when called with db_save = abap_false.
- start_timer double-call detection — warns when called twice without a stop_timer in between.
- Sticky context across all logging methods — set_context() now applies to every entry point, not only free-text.
- Long message truncation — internal log no longer truncates to 50 characters; full text is preserved.
- Emergency log payload loss — dispatcher now picks the correct XCO API per source type (add_exception, add_message, add_text).
- Memory leak in create_emergency_log — stopped mutating me->ext_number.
- Incomplete cleanup in free() and reset_appl_log() — both now clear timer_start, context, and recreate emergency_log.
- merge_logs short dump on unbound input — added IS BOUND check.
- Constructor silently overriding db_save — now raises an exception when db_save = abap_true is requested without an object.
- Removed unused secondary sorted key on log_messages — O(1) inserts, ~30–50% less memory per row.
- Simplified get_messages_flat — no more redundant symsg reconstruction.
- log_contains_messages no longer copies the full items table.
- Exception handling — read-only methods record exceptions in the trail instead of swallowing them.
- Test coverage — new tests for truncation, sticky context, config conflicts, timer double-call, db-disabled save, and emergency dispatch.
- Added "Sticky Tags" that are automatically appended to all subsequent messages within the instance context. Use set_context and clear_context methods
- Added support for custom Log Viewers via the
display()method, enabling UI-agnostic log visualization (Strategy Pattern)
- Added
start_timerandstop_timermethods for runtime measurement.
- Enhanced
log_bapiret2_table_addwithiv_min_severity. You can now filter logs directly during import (e.g., ignore all Success messages).
- JSON Serialization: New method
log_data_addallows logging of any data type (Structures/Tables). Data is automatically converted to JSON format using the XCO library.
- Basic logging capabilities (Messages, Strings, Exceptions).
- Fluent Interface support.
- ABAP Cloud & Clean Core compliance.
- Integration with SAP Application Log (BAL).
- HTML/JSON viewer.
- Load log using cl_bali_log_db=>load_log in the current instance.
- Use of enqueue/dequeue of cl_bali_log_db.
- Visualization: Development of a RAP OData Service and a Fiori Dashboard for graphical log analysis and monitoring.
- Async Performance: Implementation of asynchronous saving for high-volume scenarios to minimize runtime impact.