{"id":13698828,"url":"https://github.com/neooblaster/zcl_log_util","last_synced_at":"2025-05-07T05:47:05.291Z","repository":{"id":143805411,"uuid":"311622564","full_name":"neooblaster/zcl_log_util","owner":"neooblaster","description":"An another ABAP logging class allowing programs to focus on their functionality rather than being buried under lines of logging code","archived":false,"fork":false,"pushed_at":"2024-11-20T12:38:30.000Z","size":416,"stargazers_count":18,"open_issues_count":6,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-19T19:05:15.370Z","etag":null,"topics":["abap","logging","messages","oo"],"latest_commit_sha":null,"homepage":"","language":"ABAP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neooblaster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-11-10T10:26:15.000Z","updated_at":"2025-02-12T09:26:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"5d592698-d243-47bc-80e5-3424e4d16ab5","html_url":"https://github.com/neooblaster/zcl_log_util","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neooblaster%2Fzcl_log_util","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neooblaster%2Fzcl_log_util/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neooblaster%2Fzcl_log_util/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neooblaster%2Fzcl_log_util/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neooblaster","download_url":"https://codeload.github.com/neooblaster/zcl_log_util/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252823685,"owners_count":21809707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abap","logging","messages","oo"],"created_at":"2024-08-02T19:00:53.552Z","updated_at":"2025-05-07T05:47:05.234Z","avatar_url":"https://github.com/neooblaster.png","language":"ABAP","funding_links":[],"categories":["Categories"],"sub_categories":["📝 Logging"],"readme":"# ABAP Logging Class ZCL_LOG_UTIL\n\n\u003e An another ABAP logging class allowing programs to focus on their functionality\n\u003e rather than being buried under lines of logging code.\n\n**Link to download latest versions** :\n\n* Latest : [v0.1.2 (Latest)](https://github.com/neooblaster/zcl_log_util/releases/tag/latest)\n* Latest ABAP 7.30 : [v0.1.1 for ABAP 7.30 (Latest)](https://github.com/neooblaster/zcl_log_util/releases/tag/latest-7.30)\n\n\n## Summary\n\n[](BeginSummary)\n* [Summary](#summary)\n* [Features Overview](#features-overview)\n* [Introduction : Genesis of this class](#introduction-:-genesis-of-this-class)\n* [Installation](#installation)\n* [Getting Start](#getting-start)\n    * [Initialization](#initialization)\n    * [Logging \u0026 Display](#logging-\u0026-display)\n* [Detailed documentation](#detailed-documentation)\n    * [Definition of log message](#definition-of-log-message)\n    * [Instantiation methods](#instantiation-methods)\n    * [Logging methods](#logging-methods)\n        * [Logging system message](#logging-system-message)\n        * [Logging next to statement ``MESSAGE``](#logging-next-to-statement-message)\n        * [Logging a structure](#logging-a-structure)\n        * [Logging a table](#logging-a-table)\n        * [Logging using message class](#logging-using-message-class)\n        * [Logging a free text message](#logging-a-free-text-message)\n        * [Quick loggers](#quick-loggers)\n        * [Adding non message components to your log entries](#adding-non-message-components-to-your-log-entries)\n    * [Logging in the Application Log (`SLG1`)](#logging-in-the-application-log-slg1)\n        * [Configuration](#configuration)\n            * [Set the main object](#set-the-main-object)\n            * [Set the sub-object](#set-the-sub-object)\n            * [Set the external number](#set-the-external-number)\n            * [Set the log retention time](#set-the-log-retention-time)\n        * [Enabling / Disabling](#enabling-/-disabling)\n        * [Display Application Log](#display-application-log)\n    * [Overloading Log Messages](#overloading-log-messages)\n        * [Explanations about overloading feature (Theoretical Part)](#explanations-about-overloading-feature-theoretical-part)\n            * [Set Overloading Rules with Modes](#set-overloading-rules-with-modes)\n                * [Altering the message component(s) (Mode `O`)](#altering-the-message-components-mode-o)\n                * [Skipping the error message (Mode `I`)](#skipping-the-error-message-mode-i)\n                * [Appending an extra message (Mode `A`)](#appending-an-extra-message-mode-a)\n        * [Configuration (Technical Part)](#configuration-technical-part)\n            * [Enabling / Disabling](#enabling-/-disabling)\n            * [Set pre-filters](#set-pre-filters)\n            * [Using Spot ID](#using-spot-id)\n            * [Using Extra parameters](#using-extra-parameters)\n            * [Using your own custom setting table](#using-your-own-custom-setting-table)\n            * [Overloading an already filled log table](#overloading-an-already-filled-log-table)\n    * [Managing batch mode outputs](#managing-batch-mode-outputs)\n        * [Managing output for the spool](#managing-output-for-the-spool)\n        * [Managing output for the protocol](#managing-output-for-the-protocol)\n    * [Set your own definitions](#set-your-own-definitions)\n        * [Set a custom log table type or unregistred SAP standard type](#set-a-custom-log-table-type-or-unregistred-sap-standard-type)\n        * [Set a custom setting table that storing overloading rules](#set-a-custom-setting-table-that-storing-overloading-rules)\n    * [Extra feature](#extra-feature)\n        * [Display the content of any kind of internal table](#display-the-content-of-any-kind-of-internal-table)\n[](EndSummary)\n\n\n\n## Features Overview\n\n* Logging messages in own internal table type :\n    * Next to statement ``MESSAGES``.\n    * System message stored in global structure ``SY``.\n    * Standard **BAPI** return structure or table (eg `BAPIRET2`).\n    * Custom return structure or table.\n    * A free message text.\n    * A message using a message class.\n* Logging messages in **Application Log** (TCODE : `SLG1`) .\n* Displaying logs in the report :\n    * In an ALV grid from your own log table.\n        * The method can be used to display any kind of internal table.\n    * In the same presentation of ``SLG1`` from **Application Log**.\n* Managing logs between **foreground** and **background** execution (**batch**) :\n    * For **batch** mode, you can easily set which message type must be displayed \n    in the **spool** and in the **protocol** in an independent way.\n* The best for the end, overloading logs messages using provided settings table\nor your own one :\n    * Update messages components on the fly according to the rules in settings table.\n    * Skip messages.\n    * Appending an extra message.\n    * Messages can be uniquely identified by using a Spot ID in your program. \n\n\n\n## Introduction : Genesis of this class\n\nAs part of the development of ABAP interfaces program executed by batch, \nwe have been confronted several times with subjects around error logs.\nFirst, we had problems with their display between the area of ​​the job \nexecution protocol and those to display in the spool to send an email. \nLater we had a request to handle standard BAPI error messages being significant \nas false positive. \nFinally for an advanced follow-up for possible anomaly analysis in production, \nthe use of the application can be a precious help.\n\nAll of its subjects are at the very close ABAP level (message management) \nbut the implementation varies greatly depending on the nature of the subject. \nThe reuse of codes is very complex because of its processive implementation.\n\nThe need to develop a class designed to cover all needs, \nwithout modifying the way of logging into the program and leaving the core of \nthe program readable has become evident. \nIt is for this reason that I decided to develop the ``ZCL_LOG_UTIL`` class. \nIt is intended to be easy to use (minimum configuration) \nwhile offering a range of functions (requires more configuration, \nbut always wants to be as simple as possible). \nDue to this complexity,\nplease find detailed documentation of the class and its use.\n\n\n## Installation\n\n1. Install this project via [ABAPGit](http://abapgit.org/).\n2. Create **Application Log object** in transaction code ``SLG0`` :\n    * Object : ``ZLOGUTIL`` (`Main default object for entries registred with ZCL_LOG_UTIL`).\n3. Run the report : ``ZCL_LOG_UTIL_INSTALL`` to fill the default table \n`ZLOG_UTIL_OVERLO` of the class for example report.\n4. The table maintenance view must be created manually thanks to transaction `SE11` (See: [Table Maintenance Generator](https://blogs.sap.com/2022/06/17/getting-started-with-abap-table-maintenance-generator/))\n\nNow you're ready to get started.\n\n\n## Getting Start\n\nThe ``ZCL_LOG_UTIL`` project comes with an example program that contains and \nuses all of the functionality offered by the class. \nIts goal is to allow all users to have an example of a precise use, \nmethod call or implementation of a feature for their projects. \nThere is nothing worse than having the method without understanding how to use \nit.\n\nFirst follow the guide to understand its use in its simplest form before using \nthe ``ZCL_LOG_UTIL_EXAMPLES`` (``SE38`` / ``SE80``) example program.\nI will mention which demo contain the appropriate code explain in this guide.\n\n\n### Initialization\n\nFor the simplest possible use,\nI advise you to use the type of log table provided with the class.\nInstantiation works in the same way as that of an ALV grid of class \n``CL_SALV_TABLE`` :\n\n````abap\n\" Data declaration :\nDATA: lt_log_table TYPE TABLE OF zcl_log_util=\u003ety_log_table ,\n      lr_log_util  TYPE REF TO   zcl_log_util               .\n\n\" Instanciation\nzcl_log_util=\u003efactory(\n    IMPORTING\n        e_log_util  = lr_log_util\n    CHANGING\n        c_log_table = lt_log_table\n).\n````\n\n\u003e Available in ``Demo 010``.\n\n\n\n### Logging \u0026 Display\n\nTo log messages, there are a number of different ways to proceed.\nI advise you to do it in the following way.\nThis method offers the advantage of being able to do the where-used on the\nmessage class and on the message number, \na powerful feature of SAP.\n\n````abap\n\" Creating a variable to catch generated message\nDATA: lv_dummy TYPE string .\n\n\" Raising message :\n\"   - 1.) Message texte is available in lv_dummy.\n\"   - 2.) Log raised message\nMESSAGE e504(vl) INTO lv_dummy.\nlr_log_util-\u003elog( ).\n\n\" Display you log table\nlr_log_util-\u003edisplay( ).\n````\n\n**Hints** : When you use statement ``MESSAGE``, SAP automatically feed\nstructure ``SY``. Using `lr_log_util-\u003elog( )` will log message using the message \ncomponents available in structure ``SY``.\nWhen a standard **Function Module** or **BAPI** implicitely\nstored errors in ``SY`` you can log system message using `log( )` method\nwithout writing statement ``MESSAGE``.\n\n\u003e Available in ``Demo 010``.\n\n\n\n\n\n\n## Detailed documentation\n\n\n### Definition of log message\n\nA log message in **SAP** is an integral part of the system which is very\nwell designed.\nIn the most basic usage case, they are used to handle the program logic errors\nto inform (`I`), warn (`W`) or interrupt (`E` or `A`) the program.\n\nTexts messages are stored in a **class message** (`ID`) which associates them\nto a **number**. The message text can have until four variables placeholders (`\u0026`).\n\nThe class message also handle the internationalization.\n\nThe best practice is to use class message to manage your own custom messages.\nYou can raised the message by specifying the **type** or generate a text message\nfor a **log registry** (internal table for final display or any purpose).\n\nKeep in mind the following message components with their roles :\n\n* ``TYPE`` : Defines the kind of the message :\n    * ``A`` (`Abort`) which will interrupt the program.\n    * ``E`` (`Error`) which will interrupt the program.\n    * ``W`` (`Warning`) which will display a warning in status bar.\n    It did not interrupt the rest of the program.\n    * ``I`` (`Information`) which will display a information popup.\n    It did not interrupt the rest of the program.\n* ``ID`` : specifies the class message which contain the text\n* ``NUMBER`` : This is the number of the message to get in the provided class\nmessage (`ID`)\n* ``MESSAGE VALUE 1`` : The message text variable to put in placeholders\n(first `\u0026` or `\u00261`).\n* ``MESSAGE VALUE 2`` : The message text variable to put in placeholders\n(second `\u0026` or `\u00262`).\n* ``MESSAGE VALUE 3`` : The message text variable to put in placeholders\n(third `\u0026` or `\u00263`).\n* ``MESSAGE VALUE 4`` : The message text variable to put in placeholders\n(fourth `\u0026` or `\u00264`).\n\n\n\n### Instantiation methods\n\nThere are two ways to instantiate the ``ZCL_LOG_UTIL`` class.\nThe first method will be the most frequent method.\nThe second method makes it possible to defer the association of the internal \ntable to a later moment in the processing of the program.\nIt also offers a way to change log tables at any time which allows you to use \na single instance to manage different internal tables.\n\n* First method : classic way, same as chapter ``Getting Start``\n\n````abap\n\" Data declaration :\nDATA: lt_log_table TYPE TABLE OF zcl_log_util=\u003ety_log_table ,\n      lr_log_util  TYPE REF TO   zcl_log_util               .\n\n\" Instanciation (making link between instance and internal table)\nzcl_log_util=\u003efactory(\n    IMPORTING\n        e_log_util  = lr_log_util\n    CHANGING\n        c_log_table = lt_log_table\n).\n````\n\n\u003e Available in ``Demo 010``.\n\n* Second method : differed way, for multiple log table in one report.\n\n````abap\n# -----[ Instanciation ]---------------------------------------\n\" Data declaration :\nDATA: lr_log_util  TYPE REF TO   zcl_log_util .\n\n\" Instanciation\nzcl_log_util=\u003efactory(\n    IMPORTING\n        e_log_util  = lr_log_util\n).\n````\n\n````abap\n# -----[ Linking log table ]-----------------------------------\n\" Data declaration :\nDATA: lt_log_table TYPE TABLE OF zcl_log_util=\u003ety_log_table .\n\n\" Linking log table :\nlr_log_util-\u003eset_log_table(\n    CHANGING\n        t_log_table = lt_log_table\n).\n````\n\n\u003e Available in ``Demo 065``.\n\n\n\n### Logging methods\n\nThe main objective of this class is to provide the maximum possibility of\nlogging different message sources with different format types using only one method.\nHere are the ways to log messages using the instance reference `lr_log_util`\nof class ``zcl_log_util``.\n\n\n#### Logging system message\n\nBy definition, system message are stored in the global system structure ``SY``.\nCalling the method ``log( )``, without import parameter will add the \nsystem message to the linked log table :\n\n````abap\n\" Log system message\nlr_log_util-\u003elog( ).\n````\n\n\u003e Available in ``Demo 010``.\n\n\n\n#### Logging next to statement ``MESSAGE``\n\nAs mentioned previously, the statement ``MESSAGE`` will update\nthe global system structure.\nSo to log the message in the log table simplify do as following :\n\n````abap\n\" Done like this, the message will be redirected into lv_dummy as string.\nMESSAGE i123(zmm01) WITH 'message' 'components' INTO DATA(lv_dummy).\nlr_log_util-\u003elog( ).\n````\n\n\u003e Available in ``Demo 010``.\n\nFrom my point of view, this is the best way to register an entry in the log table,\nbecause the here before statement will respond to the _where-used_ case.\n\n\n\n#### Logging a structure\n\nYou can log any kind of **structure** as long as you have defined the field roles.\nThe ``zcl_log_util`` class already knows the field roles of the SAP standard\nmessage structure (and table).\n\n[](#import\u003ezcl_log_util_known_structure.md)\nPlease find below structure which are natively handle by ``zcl_log_util`` :\n\n| Name | Msg. Text | Msg. Type | Msg. ID | Msg. Number | Msg. Val. 1 | Msg. Val. 2 | Msg. Val. 3 | Msg. Val. 4 |\n|---|---|---|---|---|---|---|---|---|\n| zcl_log_util=\u003ety_log_table | MESSAGE | TYPE | ID | NUMBER | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n| sy | - | MSGTY | MSGID | MSGNO | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n| prott | - | MSGTY | MSGID | MSGNO | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n| bapiret1 | MESSAGE | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bapiret2 | MESSAGE | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bapi_coru_return | - | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bapi_order_return | - | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bdcmsgcoll | - | MSGTYP | MSGID | MSGNR | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n\nSee chapter ``Set your own definitions`` / `Set a custom log table type or unregistred SAP standard type`\nto register a unknown structure. [Jump](README.md#)\n\n[](#import\u003czcl_log_util_known_structure.md)\n\n````abap\nDATA ls_bapiret2 TYPE bapiret2.\n\n\" Considering ls_bapiret2 is not initial\nlr_log_util-\u003elog( ls_bapiret2 ).\n````\n\n\n\n#### Logging a table\n\nYou can log any kind of **table** as long as you have defined the field roles.\nThe ``zcl_log_util`` class already knows the field roles of the SAP standard\nmessage structure (and table).\n\n[](#import\u003ezcl_log_util_known_structure.md)\nPlease find below structure which are natively handle by ``zcl_log_util`` :\n\n| Name | Msg. Text | Msg. Type | Msg. ID | Msg. Number | Msg. Val. 1 | Msg. Val. 2 | Msg. Val. 3 | Msg. Val. 4 |\n|---|---|---|---|---|---|---|---|---|\n| zcl_log_util=\u003ety_log_table | MESSAGE | TYPE | ID | NUMBER | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n| sy | - | MSGTY | MSGID | MSGNO | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n| prott | - | MSGTY | MSGID | MSGNO | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n| bapiret1 | MESSAGE | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bapiret2 | MESSAGE | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bapi_coru_return | - | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bapi_order_return | - | TYPE | ID | NUMBER | MESSAGE_V1 | MESSAGE_V2 | MESSAGE_V3 | MESSAGE_V4 | \n| bdcmsgcoll | - | MSGTYP | MSGID | MSGNR | MSGV1 | MSGV2 | MSGV3 | MSGV4 | \n\nSee chapter ``Set your own definitions`` / `Set a custom log table type or unregistred SAP standard type`\nto register a unknown structure. [Jump](README.md#)\n\n[](#import\u003czcl_log_util_known_structure.md)\n\n````abap\nDATA lt_bapiret2 TYPE TABLE OF bapiret2.\n\n\" Considering lt_bapiret2 is not initial\nlr_log_util-\u003elog( lt_bapiret2 ).\n````\n\n\u003e Available in ``Demo 040``.\n\n\n\n#### Logging using message class\n\nThe class offer the possibility to register a new entry in your log table \nby passing message components directly in the import parameter of the\nmethod ``log( )``.\n\nBe aware that \"where-used\" will not be able to find the message\n\n````abap\nlr_log_util-\u003elog(\n    IMPORTING\n        i_log_msgid = 'zmm01'\n        i_log_msgno = '123'\n        i_log_msgty = 'I'\n        i_log_msgv1 = 'Message'\n        i_log_msgv2 = 'Component'\n*        i_log_msgv3 = 'optional'\n*        i_log_msgv4 = 'optional'\n)\n````\n\n\n\n#### Logging a free text message\n\nIf you have a simple text or a variable which contains your text message\nyou can register it in the log table.\n\nNote : The class is not able to find back the message components, so in the log\ntable you will only find the message in the message column.\n\n````abap\nlr_log_util-\u003elog( 'My free text message' ).\n````\n\n\n\n#### Quick loggers\n\n\u003e Available in ``Demo 090``.\n\n\n\n#### Adding non message components to your log entries\n\n\u003e Available in ``Demo 030``, `Demo 050`, `Demo 060`.\n\n\n\n\n\n\n### Logging in the Application Log (`SLG1`)\n\nThe ``zcl_log_util`` class can be used as library\nto handle logging throught **Application Log**. \nIndeed, all registered messages from method ``log( )``,\ncan be stored in a **Application Log** ledger.\n\nThis is not the maim purpose of this class,\nso some settings steps must be perform to enable\n**Application Log**.\n\n\n#### Configuration\n\nAt least, to create a **Application Log** register,\nwe have to set the **main object** and eventually one of its\n**sub-object**.\n\nBy default, ``zcl_log_util`` use the default **main object**\n``ZLOGUTIL`` which you have created in during `Installation` step\nthanks to ``SLG0``.\n\nSo at least, you can simply **enable** the **Application log**,\nbut I advise to use your own ``SLG`` objects.\n\nTo handle **Application Log** from ``zcl_log_util``,\nyou can define a local reference to simplify the code writing \nor make direct call from your instance.\n\nHere we will use a local reference `lr_slg` to increase code readability :\n\n````abap\nDATA lr_slg TYPE REF TO zcl_log_util_slg.\n\nlr_slg = lr_log_util-\u003eslg( ).\n````\n\n\u003e Available in ``Demo 070``.\n\n\n##### Set the main object\n\nTo set/change your own **main object**,\nsimply use the method ``set_object( )`` :\n\n````abap\n\" Main object ZMYPO must be exist in SLG0.\nlr_slg-\u003eset_object( 'ZMYPO' ).\n````\n\n\u003e Available in ``Demo 070``.\n\n\n\n##### Set the sub-object\n\nTo set/change the **sub-object**,\nsimply use the method ``set_sub_object( )`` :\n\n````abap\n\" Sub-object 'PO_CHANGE' must be a sub-obecjt of 'ZMYPO'.\nlr_slg-\u003eset_sub_object( 'PO_CHANGE' ).\n````\n\n\u003e Available in ``Demo 070``.\n\n\n\n##### Set the external number\n\nThe **external number** is optionnal.\nIts helps to reduce result when you search for log in ``SLG1``.\nFor instance, you can set the **PO Number** as **external number** :\n\n````abap\nlr_slg-\u003eset_external_number( '4500001189' ).\n````\n\n\u003e Available in ``Demo 070``.\n\n\n\n##### Set the log retention time\n\nThe retention delay is required for the garbage collector\nto delete old log.\nBy default, the retention is set to ``30`` days.\n\n````abap\nlr_slg-\u003eset_retention( 60 ).\n````\n\n\u003e Available in ``Demo 070``.\n\n\n\n\n\n\n#### Enabling / Disabling\n\nYou can enable / disable at anytime the recording of log message\nin the **Application Log**.\n\nSimply use method ``enable( )`` to activate the functionality and\n``disabled( )`` to turn off recording.\n\n````abap\n\" Turn on Application Log\nlr_slg-\u003eenable(  ).\n````\n````abap\n\" Turn off Application Log\nlr_slg-\u003edisable(  ).\n````\n\n\u003e Available in ``Demo 070`` and `080`.\n\nEnabling / Disabling **Application Log** will not close the register.\nRegister is saved at the end of the program.\n\n\n\n#### Display Application Log\n\nIf you want to display the **Application Log** in your report\nto avoid using TCODE ``SLG1``, simply call method `display( )`.\n\n````abap\n\" Display the Application Log register\nlr_slg-\u003edisplay(  ).\n````\n\n\u003e Available in ``Demo 070``.\n\nResult in your own log table :\n\n![](lib/img/slg_result_in_log_table_01.png)\n\nResult in **Application Log** using ``display( )`` :\n\n![](lib/img/slg_result_in_app_log_01.png)\n\n\n\n\n\n\n### Overloading Log Messages\n\nThis functionality is the most complex of the class and this is the need which\nlead me to create it.\n\nThis feature must be used with parsimony, because rewriting messages\nis not harmless. This a very powerful functionality which is configured\nthanks to a customizing table. So, once in production, issues can became\nmore complex for analysis.\n\nSo the programs which use overloading must be well documented in functional and\ntechnical documentation (SFD / STD) and as possible in the program using comments.\n\n\n\n#### Explanations about overloading feature (Theoretical Part)\n\nThe overloading consist to alter the log message which is registering\nwith method ``log( )`` (also with `message( )`) according to rules set in\nthe customization table.\n\nAlteration can be one of the following :\n- **Change** the error message\n- **Skipping** the error message\n- **Append** an extra message\n\nFor instance, in our case, an interface program calls a **BAPI**\nwhich returns an error message.\nHowever, our processing was successfully done/commit in **SAP**.\nThe customer asked us to consider this error message as false positive\n(and some other ones).\n\nFor this message we only change the message **type** from ``E`` to `W`.\n\nAnother example that can explain overloading functionality is if you want\nto return a more speaking message for end users than those **SAP** which can\nbe a little bit too technical. \n\nAll components which compose a log message (Cf `Definition of log message`)\ncan be overloaded (one to many at once).\n\n\n##### Set Overloading Rules with Modes\n\nOverloading must be managed using a customizing table.\nThe class ``ZCL_LOG_UTIL`` allows you to reuse your own customizing table,\nbut if you do not have this kind of table, she is delivered with\nher own table ``ZLOG_UTIL_OVERLO``.\n(See chapter `Using your own custom setting table` to set your own table).\n\nAt least, the customizing table must have **four** inputs fields\nand **three** outputs fields - marked as **Obligatory** - to be functional,\nbut please find all configurable fields with their role.\nYou can find the corresponding field of table ``ZLOG_UTIL_OVERLO``\nbetween brackets. \n\n* Input fields :\n    * **Obligatory** :\n        * To set the ``Message ID`` of registering message to overload. [`INPUT1`]\n        * To set the `Message Number` of registering message to overload. [`INPUT2`] \n        * To set the `Message Type` of registering message to overload. [`INPUT3`]\n        * To set the ``Spot ID``. We will see this feature later. [`INPUT4`]\n    * **Optional** :\n        * For pre-filtering : (identifying you development subject)\n            * One standing for **development code**. [`CODE`]\n            * One standing for **development domain**.  [`DOMAINE`]\n            * One standing for **kind of data**.  [`DATA`]\n        * For extra parameters :\n            * Extra parameter 1.  [`INPUT5`]\n            * Extra parameter 2.  ``No set``\n* Output fields :\n    * **Obligatory** :\n        * To set the new value of the ``Message ID``. [`OUTPUT1`]\n        * To set the new value of the ``Message Number``. [`OUTPUT2`]\n        * To set the new value of the ``Message Type``. [`OUTPUT3`]\n    * **Optional** :\n        * To set the new value of the ``Message value 1``. [`OUTPUT4`]\n        * To set the new value of the ``Message value 2``. [`OUTPUT5`]\n        * To set the new value of the ``Message value 3``. [`OUTPUT6`]\n        * To set the new value of the ``Message value 4``. [`OUTPUT7`]\n        * To set the overloading mode. [`OUTPUT8`]\n\n![Default Customizing Table](lib/img/overload_default_custo_tab.png)\n\n\u003e **Important** : If the field standing for overloading mode is not defined\n\u003e all rules will be processed as mode ``O`` (Overloading).\n\n\nThe overloading allows you to restrict rules to a dedicated scope using\n**pre-filters** and **extra-parameters**.\n\nWhen you instantiate a reference of ``zcl_log_util``,\nrules are loaded on the first call of method ``log( )``.\nIt selects rules from customizing table using **pre-filters** and stores them\nin an internal table of the instance.\nOverloading only works with rules internally stored to prevent many queries.\n**Pre-filters** allows you to get overloading rules for you program.\n\nEventually, if you want to have variants of rule,\nyou can use - by settings up at anytime - in your program until two extra parameters\nto fine the rule selection.\nIt can be useful to manage rules in different language.\n\nPlease find below a chart showing how fields are used\nto fine the selection :\n\n![Rule selection diagram](lib/img/chart3.png)\n\n\u003e Available in ``Demo 105``.\n\n\n###### Altering the message component(s) (Mode `O`)\n\nThis mode offer you to edit one to many component of the message.\n\nConsidering you are logging the following message ``e508(vl)`` and you have\nthis rule in the customizing table :\n\n| INPUT1 | INPUT2 | INPUT3 | INPUT4 | OUTPUT1 | OUTPUT2 | OUTPUT3 |\n|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n| VL | 508 | E  |  |  |  | W | \n\nWith this rule the message will be logged / displayed as ``w508(vl)``\n\nNote : The overloading mode is not set (available) in the rule, so\nthis is this mode which used.\n\n\n\n###### Skipping the error message (Mode `I`)\n\nThis mode offer the possibility to mute message which respond to \na rule set in customization table.\n\nNote : The **mode** field must be defined\n\nConsidering you are logging the following message ``w010(02)`` and you have\nthis rule in the customizing table :\n\n| INPUT1 | INPUT2 | INPUT3 | INPUT4 | OUTPUT1 | OUTPUT2 | OUTPUT3 | OUTPUT8 |\n|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n| 02 | 010 | W  |  |  |  |  | I |\n\nWith this rule the message will be ignored (no entry in table / no display)\n\n\n\n###### Appending an extra message (Mode `A`)\n\nThis mode offer the possibility to add an extra message to those\nresponding to the rule.\n\nConsidering you are logging the following message ``e001(vn)`` and you have\nthis rule in the customizing table :\n\n| INPUT1 | INPUT2 | INPUT3 | INPUT4 | OUTPUT1 | OUTPUT2 | OUTPUT3 | OUTPUT8 |\n|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n| VN | 001 | E  |  | 01 | 012 | E | A |\n\nWith this rule you will have both error message :\n* ``e001(vn)``\n* ``e012(01)``\n\nNote : This mode is most designed when logs are registered in log table\ninstead of raising message even if that works as well.\n\n\n\n\n\n\n#### Configuration (Technical Part)\n\nEven if the overloading functionality seams to be complex\nand powerful, the configuration is very easy.\n\nIn the program, the minimal configuration to do is\nto **enable** the feature. The rest is handle in the customization table.\n\n\n##### Enabling / Disabling\n\nBy default, overloading functionality is not enabled.\nUse the following statement to activate it.\n\n**Note** : You can enable / disabled the feature at any time in the program\ndepending of your need.\n\n````abap\n\" Direct method\nlr_log_util-\u003eoverload( )-\u003eenable( ).\n\n\" Using intermediate reference\nDATA: lr_log_util_overload TYPE REF TO zcl_log_util_overload\nlr_log_util_overload = lr_log_util-\u003eoverload( ).\nlr_log_util_overload-\u003eenable( ).\n````\n\nTo disable :\n\n````abap\nlr_log_util_overload-\u003edisable( ).\n````\n\n\u003e Available in ``Demo 100``.\n\n\n\n##### Set pre-filters\n\nThe purpose of **pre-filters** is to reduce / restrict rules to a \nspecific scope (mainly a program).\n\n![Rule selection diagram](lib/img/chart3.png)\n\nThe idea is to set pre-filter in the ``INITIALIZATION`` event.\nThen overloading through method ``log( )`` will only use\nrule responding to **pre-filters**.\n\nTo set filter, please use these methods. You can you them in an independent\nway depending of your need and your customizing table.\n\n````abap\nlr_log_util-\u003eoverload( )-\u003eset_filter_devcode_value( 'ZCLLOGUTIL' ).\nlr_log_util-\u003eoverload( )-\u003eset_filter_domain_value( 'BC' ).\nlr_log_util-\u003eoverload( )-\u003eset_filter_data_value( 'OVER_LOG' ).\n````\n\n\u003e Available in ``Demo 140``.\n\n\n\n##### Using Spot ID\n\nThe **Spot ID** is a special and dedicated parameter to use a specific\nrule from your customizing table during overloading.\n\nImagine you use a BAPI ``W_DELIVERY_UPDATE_2`` more than one time\nlead by specific managements rules.\nIn one case the error message is a false positive\n(little modification) and in the other case, the error message is a real issue.\nYou may want to have a overloading rule for both case.\n\n**Spot ID** is design to identified a precise moment in your program.\nIt's inspired from **Enhancement Point**.\n\nYou can set and change the **Spot ID** at any time in the program.\nYou can easily enable or disable the **Spot ID**.\n\nConsidering the following entries in your customization table :\n\n| INPUT1 | INPUT2 | INPUT3 | INPUT4 | OUTPUT1 | OUTPUT2 | OUTPUT3 | OUTPUT8 |\n|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n| VN | 001 | E  |  | VN | 001 | W | O |\n| VN | 001 | E  | MGT1 |   |  |   | I |\n| VN | 001 | E  | MGT2 | 01 | 012 | E | O |\n\nPlease find below how to use **Spot ID** and\nthe resulting behavior.\n\n1. Logging without using **Spot ID** :\n    ````abap\n    lr_log_util-\u003ee( \n        i_log_msgid = 'VN'\n        i_log_msgno = '001'\n    ).\n    \" Output message -\u003e w001(vn) (Table Line 1)\n    ````\n2. Setting \u0026 enabling **Spot ID**\n    ````abap\n    \" Set Spot ID and enable it\n    lr_log_util-\u003espot( 'MGT1' )-\u003estart( ).\n    lr_log_util-\u003ee( \n        i_log_msgid = 'VN'\n        i_log_msgno = '001'\n    ).\n    \" Result is no message will be raised/display/log\n    \" because table line 2 indicating mode I (ignoring the message)\n    ````\n3. Changing **Spot ID**\n    ````abap\n    \" Spot is already enabled. Just change the Spot ID\n    lr_log_util-\u003espot( 'MGT2' ).\n    lr_log_util-\u003ee( \n        i_log_msgid = 'VN'\n        i_log_msgno = '001'\n    ).\n    \" Result is two message : e001(vn) (Original one)\n                              e012(01) (Appended message from table line 3)\n                                       (Mode A = Append)\n    ````\n4. Stopping **Spot ID**\n    ````abap\n    \" Spot is already enabled. Just change the Spot ID\n    lr_log_util-\u003espot( )-\u003estop( ).\n    lr_log_util-\u003ee( \n        i_log_msgid = 'VN'\n        i_log_msgno = '001'\n    ).\n    \" Output message -\u003e w001(vn) (Table Line 1)\n    ````\n\n\u003e Available in ``Demo 120`` and `Demo 105`.\n\n\n\n##### Using Extra parameters\n\n\n\n##### Using your own custom setting table\n\n\u003e Available in ``Demo 110``.\n\n\n\n##### Overloading an already filled log table\n\n\u003e Available in ``Demo 130``.\n\n\n\n\n\n\n### Managing batch mode outputs\n\n\n#### Managing output for the spool\n\n\u003e Available in ``Demo 150``.\n\n\n\n#### Managing output for the protocol\n\n\u003e Available in ``Demo 160``.\n\n\n\n\n\n\n### Set your own definitions\n\n\n#### Set a custom log table type or unregistred SAP standard type\n\n\u003e Available in ``Demo 020``.\n\n\n#### Set a custom setting table that storing overloading rules\n\n\u003e Available in ``Demo 110``.\n\n\n\n\n\n\n### Extra feature\n\n\n#### Display the content of any kind of internal table\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneooblaster%2Fzcl_log_util","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneooblaster%2Fzcl_log_util","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneooblaster%2Fzcl_log_util/lists"}