abap-cloud-logger
A logging library for ABAP Cloud that wraps the released class CL_BALI_LOG in a chainable logger, collecting exceptions, messages and tables, with a stopwatch and a sticky context tag.
A logging library for ABAP Cloud that wraps the released class CL_BALI_LOG and hands back a chainable logger instead of a sequence of Application Log calls. One logger exists per Application Log object and subobject, and it collects exceptions, message-class messages, free strings, BAPIRET2 structures and tables, and whole internal tables serialised to JSON, before the log is saved. Beside the entries it carries a stopwatch that logs the duration of a code block and a sticky context tag that is prefixed to every later entry. Viewing is kept apart from logging: the log is displayed through a viewer class handed to display( ). It needs SAP S/4HANA 2023 or higher or the SAP BTP ABAP Environment, and the XCO library.
Facts
Where it sits
Who is behind it
In the atlas: maintains 4, contributes to 7@greltelmaintainerLars HvamContributes to this
In the atlas: maintains 13, contributes to 92, wrote 1@larshp1 contributor
What it declares
Every artifact
- Type
- Package
- Origin
- Independently maintained
As a package
- Where it runs
- Inside its host
- Distributed through
- abapGit
Connections
Seeing what a running service did, in a readable form
Git client written in ABAP that runs inside the system
Download
README
quoted from greltel/abap-cloud-logger under MIT, readABAP Cloud Logger
A fluent, unit-tested logging library for ABAP for Cloud Development (SAP S/4HANA Cloud,
SAP BTP ABAP Environment, S/4HANA on-premise with ABAP Cloud). It wraps the released
Application Log API (cl_bali_log) and adds the things you end up writing yourself every
time: chaining, an in-memory copy of the log, conversions to BAPIRET2 and RAP messages,
sticky context, a stopwatch, and a trail of the problems the logger itself swallowed.
DATA(logger) = zcl_cloud_logger=>get_instance( object = 'ZMYAPP'
subobject = 'IMPORT' ).
logger->set_context( |Order { order_id }|
)->log_string_add( `Validation started`
)->log_bapiret2_table_add( bapiret2_t = bapi_return
min_severity = zif_cloud_logger=>c_message_type-warning
)->log_exception_add( import_error
)->clear_context(
)->save_application_log( ).
Contents
- Why not
cl_bali_logdirectly? - Requirements
- Installation
- Quick start
- Usage
- API overview
- Errors
- Viewers
- Testing code that uses the logger
- Design
- Development
- Changelog and roadmap
- License and author
Why not cl_bali_log directly?
cl_bali_log is the right foundation and this library never hides it (get_log_handle( )
returns the if_bali_log object). What it adds:
| You want to | With cl_bali_log alone | With ABAP Cloud Logger |
|---|---|---|
| Share one log across classes of a process | pass the handle around | get_instance( ) returns the same instance for the same object / subobject / external id |
Log a string, a T100 message, sy-msg*, an exception, a BAPIRET2 table, any data as JSON | one setter class each, no filtering | one log_* method each, chainable, BAPIRET2 severity filter |
| Read back what was logged | get_all_items( ) and unpack setters | get_messages( ), get_messages_flat( ), get_messages_as_bapiret2( ), get_messages_rap( ) |
| Ask "did anything fail?" | loop over items | log_contains_error( ), get_message_count( 'E' ), search_message( ) |
| Tag entries with the document being processed | build the text yourself | set_context( ) / clear_context( ) |
| Know that a save or a mirror silently failed | you don't | get_internal_errors( ) |
| Unit-test the code that logs | mock if_bali_log | mock the small zif_cloud_logger interface |
Requirements
- SAP S/4HANA 2023 or higher, SAP S/4HANA Cloud, or SAP BTP ABAP Environment
- ABAP language version ABAP for Cloud Development for every object
- Released APIs only:
cl_bali_log,cl_bali_log_db,cl_abap_context_info, XCO
Installation
- Pull the repository with abapGit into a package of your choice (ABAP language version ABAP for Cloud Development).
- The Application Log object
Z_CLOUD_LOG_SAMPLE(sub-objectSETUP) ships with the repository and is used by the tests and the demo. For your own logs create an Application Log object in the Maintain Application Log Object app (Fiori) orSLG0(on-premise).db_save = abap_truerequires an object;db_save = abap_falseworks without one. - Run the ABAP Unit tests of
zcl_cloud_loggerandzcl_cloud_logger_view_console.
Quick start
Run zcl_cloud_logger_demo with F9 in ADT. It logs a small process (context, T100
message, filtered BAPIRET2 table, exception, JSON data, timer) and prints the result on the
console without persisting anything.
Usage
Every log_* method returns the logger, so calls chain. Every writing method raises
zcx_cloud_logger_error; wrap the logging block once instead of every call.
Get an instance
DATA(logger) = zcl_cloud_logger=>get_instance(
object = 'ZMYAPP' " Application Log object (required when db_save = abap_true)
subobject = 'IMPORT'
ext_number = |{ run_id }| " part of the instance key
db_save = abap_true " abap_false: save_application_log( ) is a no-op
expiry_date = CONV #( cl_abap_context_info=>get_system_date( ) + 30 )
enable_emergency_log = abap_false " abap_true mirrors every entry into a second log (see below)
trim_limit = 100 ). " cap of the internal error trail
The same object / subobject / external id always returns the same instance. Supplying a
different db_save, expiry_date, trim_limit or enable_emergency_log for an existing
instance raises config_mismatch; omitting a parameter means "no preference".
Emergency log
With enable_emergency_log = abap_true every entry is also written, immediately and
independently of your commit, into a second Application Log through the XCO BAL API (same
object and subobject; external id = yours, or a UUID when you gave none). It is meant for
the case where the main log never gets saved — a dump after logging, a rollback — and it is
best effort: a failed mirror goes to the internal error trail, never to the caller. Free text
is mirrored as message Z_CLOUD_LOGGER 001 so the severity survives; XCO records an
exception as five lines (text, class, source position), so counts in that log differ from
get_message_count( ).
Add entries
logger->log_string_add( `Free text` ). " default severity W
logger->log_string_add( string = `Failed` msgty = zif_cloud_logger=>c_message_type-error ).
logger->log_message_add( VALUE #( msgty = 'E' msgid = 'ZMYAPP' msgno = '001' msgv1 = order_id ) ).
MESSAGE e002(zmyapp) WITH order_id INTO DATA(dummy) ##NEEDED.
logger->log_syst_add( ). " takes sy-msg*
logger->log_exception_add( exception ). " default severity E
logger->log_exception_add( exception = exception severity = 'W' ).
logger->log_bapiret2_structure_add( bapiret2 ).
logger->log_bapiret2_table_add( bapiret2_t = bapiret2_table
min_severity = 'E' ). " keeps E, A, X
logger->log_data_add( any_structure_or_table ). " serialized to JSON via XCO
Initial structures and unbound exceptions are ignored, so chains do not need guards.
Exceptions that carry a T100 key (if_t100_message) keep their message class, number and
variables in the internal log, so search_message( ), get_messages_rap( ) and
get_messages_as_bapiret2( ) see the real message rather than free text.
Text length: the Application Log stores free text (log_string_add, log_data_add)
up to 200 characters, and the [context] prefix counts. Longer texts are cut in the
persisted log only; get_messages( ) and get_messages_flat( ) always return the full text.
Sticky context
logger->set_context( `Order 4711` ).
logger->log_string_add( `Price checked` ). " persisted as "[Order 4711] Price checked"
logger->clear_context( ).
Timer
logger->start_timer( ).
" ... work ...
logger->stop_timer( `Pricing` ). " logs "Timer Result: Pricing took 0.421 seconds."
Read the log
IF logger->log_contains_error( ). " E, A or X present
...
ENDIF.
DATA(errors) = logger->get_message_count( zif_cloud_logger=>c_message_type-error ).
DATA(found) = logger->search_message( VALUE #( msgid = 'ZMYAPP' msgno = '001' ) ).
DATA(entries) = logger->get_messages( ). " full internal log
DATA(lines) = logger->get_messages_flat( ). " "[ctx] E001(ZMYAPP) - text"
DATA(bapiret2) = logger->get_messages_as_bapiret2( ).
RAP
METHOD validate_order.
...
LOOP AT logger->get_messages_rap( ) INTO DATA(message).
APPEND VALUE #( %tky = order-%tky %msg = message ) TO reported-order.
ENDLOOP.
ENDMETHOD.
Free-text and exception entries are wrapped in message Z_CLOUD_LOGGER 001 (four 50-character
placeholders).
Save
logger->save_application_log( ).
COMMIT WORK.
The caller owns the commit. Where COMMIT WORK is not allowed (RAP), use
save_application_log( use_2nd_db_connection = abap_true ), which lets cl_bali_log_db
commit on its own connection. With db_save = abap_false the call does nothing and is
recorded in the internal error trail.
Attach to a persisted log
A log saved earlier — by a previous run, another session, a job step — can be picked up again by its handle and continued:
DATA(logger) = zcl_cloud_logger=>load( handle ). " BALLOGHNDL from get_handle( ) or the log tables
logger->log_string_add( `second run started` ). " appends to the persisted items
IF logger->log_contains_error( ). " queries see the persisted history
...
ENDIF.
logger->save_application_log( ). " updates the same log
The loaded logger is registered under the log's own object / subobject / external id, so a
later get_instance( ) with that key returns it. Persisted items become internal log
entries with the item's severity, text and T100 key; their item reference and context
stay initial and date/time are UTC (the Application Log stores UTC). Loading a log that is
still held by a live logger in the session — same handle or same key — raises
already_active (free( ) it first); an unknown handle raises error_in_loading.
Reset, merge, free
logger->reset_appl_log( ). " fresh log, same instance and configuration
logger->reset_appl_log( abap_true ). " also delete the persisted log
logger->merge_logs( other_logger ). " copies entries and trail, other stays unchanged
logger->free( ). " deregisters; any further write raises instance_released
Internal error trail
Problems the logger swallows on purpose (failed emergency mirror, no-op save, unresolvable message text, failed delete during reset) are not lost:
LOOP AT logger->get_internal_errors( ) INTO DATA(problem).
... " problem-timestamp, problem-method, problem-error_text
ENDLOOP.
logger->clear_internal_errors( ).
The trail is capped at trim_limit entries (default 100, oldest evicted first);
trim_limit = 0 switches the trail off.
High volume
Every entry is kept twice while the logger lives: as an Application Log item and as a row of
the internal log (get_messages( ) copies that table). For jobs that log hundreds of
thousands of lines, save and reset per batch — save_application_log( ) then
reset_appl_log( ) — instead of holding one log for the whole run, and keep trim_limit
at its default. get_messages_flat( ) renders every entry, so call it once, not per line.
zcl_cloud_logger_benchmark (F9) measures adding, rendering, counting, saving and deleting
entries entries on your system and checks the emergency-log mirror; raise the constant to
find your limit. Watch memory from outside (SM04 / SM50) — the memory utilities are not
released for ABAP Cloud.
Measured on S/4HANA 2023 FPS03 (on-premise, 2026-09-17), 20,000 entries, every 10th an error:
| Step | Time | Per entry |
|---|---|---|
log_string_add × 20,000 | 0.46 s | 0.023 ms |
get_messages_flat( ) (20,000 lines) | 0.016 s | 0.001 ms |
get_message_count( 'E' ) | 0.002 s | — |
save_application_log( ) + COMMIT WORK | 0.058 s | 0.003 ms |
reset_appl_log( abap_true ) + COMMIT WORK | 0.010 s | — |
Emergency-log mirror: 3 entries, 0 internal errors, visible in SLG1 without a commit. At these numbers the in-memory copy is not the bottleneck for typical jobs; save-and-reset per batch remains the advice for runs that keep hundreds of thousands of entries alive at once.
API overview
| Group | Methods |
|---|---|
| Instance | zcl_cloud_logger=>get_instance( ), zcl_cloud_logger=>load( handle ), free( ), reset_appl_log( ), merge_logs( ) |
| Add | log_string_add, log_message_add, log_syst_add, log_exception_add, log_bapiret2_structure_add, log_bapiret2_table_add, log_data_add |
| Context / timer | set_context, clear_context, start_timer, stop_timer |
| Query | log_is_empty, log_contains_messages, log_contains_error, log_contains_warning, get_message_count, search_message |
| Read | get_messages, get_messages_flat, get_messages_as_bapiret2, get_messages_rap, get_handle, get_log_handle |
| Persist / show | save_application_log, display( viewer ) |
| Diagnostics | get_internal_errors, clear_internal_errors, zif_cloud_logger=>c_version |
| Testing | zcl_cloud_logger_fake — in-memory implementation of the interface for consumer tests |
Every public method is documented with ABAP Doc; hover in ADT for parameters and behaviour.
Errors
All failures surface as zcx_cloud_logger_error. Check if_t100_message~t100key against
the class constants:
| textid | Message | When |
|---|---|---|
error_in_creation | 003 | cl_bali_log refused to create the log or header (e.g. unknown log object) |
object_required | 006 | db_save = abap_true without an Application Log object |
invalid_trim_limit | 008 | negative trim_limit |
config_mismatch | 007 | an instance with the same key exists with different settings |
error_in_logging | 004 | the Application Log rejected an entry |
error_release | 002 | cl_bali_log_db could not save the log |
error_in_emergency_log | 005 | the XCO emergency log could not be created |
instance_released | 009 | writing method called after free( ) |
error_in_loading | 010 | load( ) found no log for the handle (log_handle names it) |
already_active | 011 | load( ) for a log still held by a live logger in this session (same handle or key) |
The original cx_bali_runtime / XCO exception is chained in previous, and log_object
names the Application Log object concerned; the message texts show it as &1.
Viewers
display( viewer ) hands the logger to any implementation of zif_cloud_logger_viewer
(one method: view( logger )).
zcl_cloud_logger_view_console– writes header, entries and internal error trail to anif_oo_adt_classrun_outconsole.- Your own – e.g. an ALV popup on an SAP GUI system, a Fiori app or a monitoring endpoint.
get_messages( )andget_messages_flat( )give you the data in table form.
Testing code that uses the logger
Depend on zif_cloud_logger, not on the class, and inject it:
CLASS zcl_import DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS constructor IMPORTING logger TYPE REF TO zif_cloud_logger OPTIONAL.
...
ENDCLASS.
In the test, inject zcl_cloud_logger_fake: an in-memory implementation of the whole
interface that never touches the Application Log or the database. Fluent methods return the
fake, the query methods work on what was logged, saves and resets are counted, and the
released-instance contract is mimicked.
METHOD given_missing_price_then_error_logged.
DATA(logger) = NEW zcl_cloud_logger_fake( ).
DATA(cut) = NEW zcl_import( logger ).
cut->import( order_without_price ).
cl_abap_unit_assert=>assert_equals( act = logger->zif_cloud_logger~log_contains_error( )
exp = abap_true
msg = `A missing price must be logged as error` ).
cl_abap_unit_assert=>assert_equals( act = logger->save_calls
exp = 1
msg = `The log must be saved once` ).
ENDMETHOD.
cl_abap_testdouble=>create( 'zif_cloud_logger' ) works as well when you need to script
specific return values. The library's own tests show that style with hand-written doubles
for the two internal seams (zif_cloud_logger_system, zif_cloud_logger_persistence).
Design
- Multiton. One instance per object / subobject / external id, created lazily by
get_instance( ), removed byfree( ). A released instance is dead: writes raiseinstance_released, queries return empty results. - Two seams. All environment access (date, time, time stamp, user,
sy-msg*) goes throughzif_cloud_logger_system; all database access throughzif_cloud_logger_persistence. Production defaults are injected by the constructor; the tests inject fixed-clock and spy doubles, so the unit tests never touch the database or a real clock. - Never bring the caller down. Problems inside the logger (emergency mirror, text resolution, no-op save, delete during reset) are recorded in the internal error trail instead of raised. Problems in the Application Log API itself are raised, wrapped.
- Strategy for output. The logger knows nothing about UIs; viewers implement
zif_cloud_logger_viewer. - Clean ABAP. No Hungarian notation, final classes, ≤ 3 parameters where the API
allows it (
get_instanceis the documented exception), ABAP Doc on every public element. Clean Core: released APIs only, checked by abaplint with thesteampunk-2305-apisnapshot.
Development
The repository runs off-stack without an SAP system:
npm ci
npm run lint # abaplint, full rule set curated to Clean ABAP, language version Cloud
npm test # transpiles to JavaScript and runs the ABAP Unit tests on Node.js
GitHub Actions runs both on every push and pull request. Some things only the real compiler catches; see CONTRIBUTING.md for the list and for the pull-request checklist.
Quality and verification
| Check | Result | Where |
|---|---|---|
| ABAP Unit | 92 tests, all green | ADT on S/4HANA 2023 FPS03 (ABAP 7.58), off-stack on every commit |
ATC, variant ABAP_CLOUD_READINESS | 0 findings | ADT on S/4HANA 2023 FPS03, 2026-09-16 |
ATC, variant S4HANA_READINESS_2023 | 0 findings | ADT on S/4HANA 2023 FPS03, 2026-09-16 |
abaplint, 178 rules, language version Cloud, API snapshot steampunk-2305-api | 0 findings | GitHub Actions |
Verified on:
| System | Status |
|---|---|
| SAP S/4HANA 2023 FPS03 on-premise, ABAP for Cloud Development | verified with every release |
| SAP BTP ABAP Environment | not yet verified — a pull and an ABAP Unit run on a BTP system would be a welcome contribution (issue template) |
| SAP S/4HANA Cloud Public Edition | not yet verified |
The library uses released APIs only; the checks above are what backs that statement, and the table says exactly where it has been run.
Changelog and roadmap
The version history lives in CHANGELOG.md. Planned:
- Load a persisted log into an instance (
cl_bali_log_db=>load_log). - Enqueue / dequeue support of
cl_bali_log_db. - Asynchronous saving via the Background Processing Framework for high-volume scenarios.
- A RAP service and Fiori dashboard for log analysis.
Issues and pull requests are welcome.
License and author
MIT. Created and maintained by George Drakos.
History
Features 3, Changed 1, Fixes 1, Other 1
Notes
Added
zcl_cloud_logger=>load( handle ): attaches to a persisted Application Log and continues writing to it. Persisted items become internal log entries (severity, text, T100 key;item/contextinitial, date/time UTC), the instance is registered under the log's key,save_application_log( )updates the same log. New textidserror_in_loading(010, carrieslog_handle) andalready_active(011, raised before the database is touched when the log is still held by a live logger of the session).zif_cloud_logger_persistence~load_log( )and theloaded_logstructure; the production adapter mapsif_bali_item_getter/if_bali_message_getteritems.zcl_cloud_logger_benchmark(F9): timing of add / render / count / save / delete for a configurable number of entries, plus an emergency-log probe.
Fixed
- Emergency log: free text is mirrored as message
Z_CLOUD_LOGGER 001with its severity; XCO'sadd_texthas none, so mirrored errors used to show as success.
Measured
- S/4HANA 2023 FPS03, 20,000 entries: add 0.46 s, render 0.016 s, save 0.058 s, delete 0.010 s; emergency-log mirror persisted and visible in SLG1 without a commit. Numbers and setup in the README.
Changed
- Off-stack pipeline: the transpiler no longer runs its own syntax check
(
ignoreSyntaxCheck); abaplint against the SAP API snapshot is the syntax authority. Threeload( )integration tests run in ADT only.
Features 4, Changed 1, Fixes 2
Notes
Added
zcl_cloud_logger_fake: in-memory implementation ofzif_cloud_loggerfor unit tests of consuming code. Fluent methods return the fake, queries work on what was logged,save_calls/reset_calls/releasedare exposed, the released-instance contract is mimicked. No Application Log, no database.log_exception_add( )keeps the T100 key and variables of exceptions that implementif_t100_message, sosearch_message( ),get_messages_rap( )andget_messages_as_bapiret2( )see the real message instead of free text.zcx_cloud_logger_error=>log_objectnames the Application Log object concerned; messages 002, 003, 004, 005, 007 and 009 show it as&1.- README: text-length limit of the Application Log,
trim_limit = 0, high-volume guidance, testing with the fake.
Fixed
- Messages with number
000were treated as free text byget_messages_flat( ),get_messages_rap( )and the exception-key extraction (000is the initial value of the NUMC field). The message class alone decides now. get_instance( )compares the effective expiry date, so spelling out the default explicitly is no longer reported asconfig_mismatch.
Changed
- Emergency-log policy documented: a failure at creation raises (an explicit
request that cannot be honoured), a failure during
reset_appl_log( )is only trailed so the main log survives.
Removed 1, Fixes 6
Notes
Fixed
free( )on a stale reference (after a new instance with the same key was created) no longer removes the new instance from the registry.merge_logs( )with the logger itself as input is ignored instead of duplicating every entry.log_message_add( )with an initial severity defaults to warning; such entries were invisible tolog_contains_*andget_message_count( ).- The merged internal error trail is kept chronological, so trimming evicts the oldest entries.
user_namein log entries falls back to the technical user name when no alias is maintained (typical on-premise).c_default_message_attributes-typeis spelled as a literal; the off-stack runtime resolved the previous constant reference to blank, so default-severity behaviour differed between the pipeline and the system.
Removed
- Unused text symbol 001 of
zcl_cloud_logger.
Breaking 7, Features 8, Changed 3, Fixes 3
Notes
Breaking
- A logger released with
free( )is dead. Every writing method (log_*,merge_logs,save_application_log,reset_appl_log,start_timer,stop_timer) raiseszcx_cloud_logger_errorwith textidinstance_released(message 009) instead of silently discarding the call. Queries (get_*,log_is_empty,search_message, ...) return empty results. Request a new instance withzcl_cloud_logger=>get_instance( ). log_message_add:symsgis mandatory. An initial structure is still ignored.log_data_add,start_timer,stop_timer,merge_logsnow declareRAISING zcx_cloud_logger_error(raised only forinstance_released; serialization and Application Log problems keep going to the log / internal trail).- RETURNING parameters renamed to
self(fluent methods) andresult(queries,get_instance). Callers are unaffected; classes that implementzif_cloud_loggerthemselves (e.g. test doubles) must rename the assignments. - Removed the unused constants
c_message_type-error_patternandc_message_type-warning_pattern. - Removed
zcl_cloud_logger_view_alv(SAP GUI ALV popup, Standard ABAP). The library is ABAP for Cloud Development only; an ALV viewer is a few lines on top ofzif_cloud_logger_viewerandget_messages( )in your own package. log_syst_addignores an empty SY message instead of adding a blank entry.
Added
- ABAP Doc on every public type, constant and method of
zif_cloud_logger,zif_cloud_logger_viewerand the exception classes. merge_logsandsave_application_logreturn the logger for chaining.- Specific exception textids:
object_required(006,db_save = abap_truewithout an Application Log object),invalid_trim_limit(008),instance_released(009). zif_cloud_logger_system/zcl_cloud_logger_system: single point of access to date, time, time stamp, user and the SY message.zif_cloud_logger_persistence/zcl_cloud_logger_persistence: single point of access tocl_bali_log_db. Both seams are injectable via the constructor.- Constants
c_version,c_default_expiry_days,c_free_text_message. zcl_cloud_logger_view_console: viewer for the ADT console (if_oo_adt_classrun_out), usable in ABAP for Cloud Development.zcl_cloud_logger_demo: runnable F9 demo of the typical flow.
Fixed
- An unknown or malformed message class no longer dumps in
log_message_add,get_messages_flatorget_messages_rap; the raw message components are rendered instead and the problem is recorded in the internal error trail. - Constructor validation errors report their real cause instead of "Log object could not be created".
- Timer duration is computed with plain date/time arithmetic on the UTC time
stamps;
cl_abap_tstmp=>subtractrejected the long stamps withcx_parameter_invalid_*on S/4HANA 2023, sostop_timerlogged "Error calculating timer duration" instead of the duration.
Changed
- Test suite rewritten: behaviour-named tests,
msgon every assertion, noWAIT, no database access, plus an isolated test class that runs the logger against fixed-clock and persistence doubles. - Off-stack pipeline: full abaplint rule set curated to Clean ABAP (178 rules),
API snapshot
steampunk-2305-api, Error-level backstop for non-Cloudsyfields, Dependabot for the npm toolchain. - README rewritten for 2.0.0; version history moved to this file; CONTRIBUTING.md and issue templates added.
- A logger released with
Features 5, Fixes 6, Performance 1
Notes
Added
- Internal error trail:
get_internal_errors( )/clear_internal_errors( )expose previously swallowedcx_bali_runtimeexceptions; capped at 100 entries, FIFO. - Strict multiton validation:
get_instanceraisesconfig_mismatchon conflicting configuration instead of returning a mismatched instance. save_application_logrecords a no-op (db_save = abap_false) in the trail.start_timerdouble-call detection.- Sticky context applies to every entry point, not only free text.
Fixed
- Internal log no longer truncates messages to 50 characters.
- Emergency log dispatcher picks the correct XCO API per source type.
create_emergency_logstopped mutatingext_number.free( )andreset_appl_log( )clear timer, context and recreate the emergency log.merge_logsno longer dumps on an unbound input.- Constructor raises when
db_save = abap_trueis requested without an object.
Performance
- Removed the unused secondary key on the internal log; simplified
get_messages_flat;log_contains_messagesno longer copies the items table.
- Internal error trail:
Features 1
Notes
Added
- Sticky context (
set_context/clear_context) appended to all subsequent entries.
- Sticky context (
Features 1
Notes
Added
display( viewer )withzif_cloud_logger_viewer(Strategy pattern); ALV viewer.
Features 1
Notes
Added
- Initial release: messages, strings, exceptions; fluent interface; Application Log (BAL) integration; ABAP Cloud / Clean Core compliance.
Others providing
Compare all 11 on the Logging page →- ABAP-LoggerABAP-LoggerA logging library for ABAP that records messages into the standard Application Log (BC-SRV-BAL) and displays them from there, installed through abapGit on ABAP 702 or higher.independent, abapLogging library for ABAP over the Application Log
- abap-log-exporterabap-log-exporterExports SAP NetWeaver logs from the Business Application Log to an external log system such as Graylog or Loki, converting entries to GELF or Loki format through a separately configured reader, converter and connector.independent, abapExports Business Application Log entries to Graylog or Loki
- ABAP-PRCABAP-PRCA framework for custom multi-step ABAP processes: a process class declares the states, and the framework runs each document through them and monitors the run.independent, abapFramework for multi-step ABAP processes with monitoring
- abap-logabap-logA logging library for ABAP with one logger interface in front of several targets, from the Application Log and the job log to database tables, files and the Eclipse console.independent, abapABAP logging library with one interface across output targets
- ABAP_LOGGINGABAP_LOGGINGAn object-oriented wrapper around SAP's Business Application Log (BAL) for ABAP NetWeaver, chaining texts, messages and exceptions onto a log header that persists in its own or the same connection.independent, abapObject-oriented wrapper around the Business Application Log
- abap-fm-loggerabap-fm-loggerA logger for ABAP function modules (RFC) that stores each call's parameters as JSON in one table, with a viewer report to search the log and reprocess a record, akin to WE10 and WE19.independent, abapLogger storing RFC function module call parameters as JSON
- open-abap-balopen-abap-balApplication logging for ABAP code transpiled to JavaScript and run on Node.js, one of the runtime libraries open-abap.org lists.community org, abapApplication logging for ABAP transpiled to JavaScript on Node.js
- abap-fluentdabap-fluentdA Fluentd client written in ABAP for sending log lines from an ABAP system to a Fluentd collector, where entries are flushed with an explicit COMMIT WORK.independent, abapFluentd client in ABAP for sending log lines to a collector
- sap-usi-logging-apisap-usi-logging-apiAn object-oriented encapsulation around SAP's Application Log (transaction SLG1), controlled by customizing, with attachable data containers that SLG1 shows behind a detail button.independent, abapObject-oriented wrapper around SAP's Application Log (SLG1)
- abap-message-loggerabap-message-loggerA message logger for ABAP Cloud that collects T100 messages, BAPIRET2 structures, exceptions and plain text before saving them to the Application Log.independent, abapMessage logger for ABAP Cloud that saves to the Application Log
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
abaplint
Flavors
“SAP S/4HANA 2023 (or higher) OR SAP BTP ABAP Environment.” — greltel/abap-cloud-logger — README, Prerequisites
Contributors
History in the atlas
- First seen.
For your agent
- Ref
artifact:greltel-abap-cloud-logger- JSON
- /artifacts/greltel-abap-cloud-logger.json
- MCP
- Connecting an agent