Google Search - Blog...........

ABAP - Working With Application Logs In Report Programming.

This Code Snippets will clarify some general process of working with application log when ABAP programmming. Such as creating, adding, deleting, displaying, formatting application logs and saving it to the database.
When we do ABAP programming,sometimes we need to bring the situation arised at runtime to the attention of the end users, which are usually errors, warnings and successful information.To do this, we can use Application Log which is a set of Function Modules provided by SAP for collecting messages, saving, reading and deleting logs in the database and displaying logs.
1.Define application log objects
Application log objects are defined in the system. The object definition assigns a work area. An object can be divided into sub-objects .Logging is performed object-specifically, via function modules.Using transaction code SLG0, we can define our own object and subobject.For example, object: ZTEST, subobject: ZTEST01.
2.Create a log
Using Function Module 'BAL_LOG_CREATE', we can create a log where all messages should be added to.
DATA: gv_log_handle TYPE balloghndl. "Application Log: Log Handle
DATA: ls_log TYPE bal_s_log. "Log header data

* define some header data of this log
ls_log-extnumber = 'Application Log Demo'.
ls_log-object = 'ZTEST'.
ls_log-subobject = 'ZTEST01'.
ls_log-aldate = sy-datum.
ls_log-altime = sy-uzeit.
ls_log-aluser = sy-uname.
ls_log-alprog = sy-repid.

CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = ls_log
IMPORTING
e_log_handle = gv_log_handle
EXCEPTIONS
log_header_inconsistent = 1
OTHERS = 2.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
The function module 'BAL_LOG_CREATE' returns the log handle (LOG_HANDLE, CHAR22). The LOG_HANDLE is a globally unique identifier (GUID) which identifies a log uniquely. You can access this log with this handle, e.g. to change the header data or to put a message in the log.
3. Put a message in the log
Using Function Module 'BAL_LOG_MSG_ADD', we can add a message into the application log.This message is put in the log identified by the log handle GV_LOG_HANDLE, which is mostly the T100 information (message type, work area, message number, the 4 message variables).
DATA: L_S_MSG TYPE BAL_S_MSG.
* define data of message for Application Log
L_S_MSG-MSGTY = SY-MSGTY.
L_S_MSG-MSGID = SY-MSGID.
L_S_MSG-MSGNO = SY-MSGNO.
L_S_MSG-MSGV1 = SY-MSGV1.
L_S_MSG-MSGV2 = SY-MSGV2.
L_S_MSG-MSGV3 = SY-MSGV3.
L_S_MSG-MSGV4 = SY-MSGV4.

CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = gv_log_handle
i_s_msg = l_s_msg
EXCEPTIONS
log_not_found = 1
msg_inconsistent = 2
log_is_full = 3
OTHERS = 4.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
4. Display log
Using Function Module 'BAL_DSP_LOG_DISPLAY', we can display the collected messages. This function module can be called without parameters. All messages in memory are displayed in a standard format (this standard format is used e.g. in the transaction SLG1).
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXCEPTIONS
PROFILE_INCONSISTENT = 1
INTERNAL_ERROR = 2
NO_DATA_AVAILABLE = 3
NO_AUTHORITY = 4
OTHERS = 5.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
5. Save logs in the database
Using Function Module 'BAL_DB_SAVE, we can save all memory data in the database. The importing parameter I_SAVE_ALL should be set as 'X'.
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_save_all = 'X'
EXCEPTIONS
LOG_NOT_FOUND = 1
SAVE_NOT_ALLOWED = 2
NUMBERING_ERROR = 3
OTHERS = 4.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
6. Find logs in the database
Using Function Module 'BAL_DB_SEARCH, we can find logs in the database. We should pass the log header filter criteria (structure BAL_S_LFIL), and a table of log headers (structure BALHDR) which satisfy the criteria is returned.
DATA: gr_object TYPE bal_s_obj.
DATA: gr_extnumber TYPE bal_s_extn.
DATA: gs_log_filter TYPE bal_s_lfil.
DATA: gt_log_header TYPE balhdr_t.

* create a filter with all relevant criteria:
gr_object-sign = 'I'.
gr_object-option = 'EQ'.
gr_object-low = 'ZTEST'.
APPEND gr_object TO gs_log_filter-object.

gr_extnumber-sign = 'I'.
gr_extnumber-option = 'EQ'.
gr_extnumber-low = 'Application Log Demo'.
APPEND gr_extnumber TO gs_log_filter-extnumber.

* search on DB for these logs
CALL FUNCTION 'BAL_DB_SEARCH'
EXPORTING
i_s_log_filter = gs_log_filter
IMPORTING
e_t_log_header = gt_log_header
EXCEPTIONS
LOG_NOT_FOUND = 1
NO_FILTER_CRITERIA = 2.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
7. Load logs from the database
Using Function Module 'BAL_DB_LOAD', we can load logs from the database. By setting the importing parameter 'I_T_LOG_HEADER' with the return values from function module 'BAL_DB_SEARCH', we can specify which logs are to be loaded in memory.
DATA: gt_log_header TYPE balhdr_t.

* load these messages into memory
CALL FUNCTION 'BAL_DB_LOAD'
EXPORTING
i_t_log_header = gt_log_header
EXCEPTIONS
NO_LOGS_SPECIFIED = 1
LOG_NOT_FOUND = 2
LOG_ALREADY_LOADED = 3.

IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
8. Read log from database
Using Function Module 'APPL_LOG_READ_DB', we can read logs from database if we want to analyze the log ourselves. By setting the importing parameter OBJECT or SUBOBJECT etc., we can specify which logs are to be read.
DATA: P_NUMBER_OF_LOGS LIKE SY-TABIX.
* Log header data
DATA: BEGIN OF P_HEADER_DATA_TAB OCCURS 0.
INCLUDE STRUCTURE BALHDR.
DATA: END OF P_HEADER_DATA_TAB.
* Log parameters
DATA: BEGIN OF P_HEADER_PARA_TAB OCCURS 0.
INCLUDE STRUCTURE BALHDRP.
DATA: END OF P_HEADER_PARA_TAB.
* Log messages
DATA: BEGIN OF P_MESSAGE_TAB OCCURS 0.
INCLUDE STRUCTURE BALM.
DATA: END OF P_MESSAGE_TAB.
* Message parameters
DATA: BEGIN OF P_MESSAGE_PARA_TAB OCCURS 0.
INCLUDE STRUCTURE BALMP.
DATA: END OF P_MESSAGE_PARA_TAB.

CALL FUNCTION 'APPL_LOG_READ_DB'
EXPORTING
OBJECT = 'ZTEST'
SUBOBJECT = 'ZTEST01'
EXTERNAL_NUMBER = 'Application Log Demo'
IMPORTING
NUMBER_OF_LOGS = P_NUMBER_OF_LOGS
TABLES
HEADER_DATA = P_HEADER_DATA_TAB
HEADER_PARAMETERS = P_HEADER_PARA_TAB
MESSAGES = P_MESSAGE_TAB
MESSAGE_PARAMETERS = P_MESSAGE_PARA_TAB.
9. Delete logs from the database
Using Function Module 'BAL_DB_DELETE', we can delete logs from the application. By setting the importing parameter I_T_LOGS_TO_DELETE ' with the return values from function module 'BAL_DB_SEARCH', we can specify which logs are to be loaded in memory.
DATA: gt_log_header TYPE balhdr_t.

CALL FUNCTION 'BAL_DB_DELETE'
EXPORTING
I_T_LOGS_TO_DELETE = gt_log_header
EXCEPTIONS
NO_LOGS_SPECIFIED = 1
OTHERS = 2.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
10. Formatting Log Display
We can use the display profile (structure BAL_S_PROF) to specifiy how the logs are displayed. It contains field catalogs which describe which fields are to be in the list and in the levels of the navigation tree.
Application Log provides display profiles which you can get with the follwoing function modules:
BAL_DSP_PROFILE_DETLEVEL_GET
BAL_DSP_PROFILE_NO_TREE_GET
BAL_DSP_PROFILE_POPUP_GET
BAL_DSP_PROFILE_SINGLE_LOG_GET
BAL_DSP_PROFILE_STANDARD_GET
If no display profile is specified, the standard display profile from transaction SLG1 is used.
Let us take a look at these function modules one by one.
o BAL_DSP_PROFILE_DETLEVEL_GET
The messages are inserted into the navigation tree. The tree-level in which they appear is determined by field DETLEVEL of structure BAL_S_MSG (which is used when adding a message to the log, eg. with BAL_LOG_MSG_ADD).
o BAL_DSP_PROFILE_NO_TREE_GET:
Presentation of a log whithout a navigation tree next to it. This kind of presentation is usefull when there are not that many messages and therefore a navigation tree would make no sense.
o BAL_DSP_PROFILE_POPUP_GET:
Presentation of a log in a popup. This is similar to the previous point. No tree is shown (does not make sense in a popup, not enough space).
o BAL_DSP_PROFILE_SINGLE_LOG_GET:
the 'standard' profile to display one log:
In the tree the log header is displayed. One level below there are different categories for the problem classes of the messages. The user can easily select for example only
important messages. All messages of the log are displayed at once on the right side.
This profile is used in transaction SLG1 when only one log has been selected.
o BAL_DSP_PROFILE_STANDARD_GET:
The 'standard' profile to display many logs.
This is similar to the previous profile, the only diffrences are:
• On the right side the overview of log headers is not expanded down to the problem class level.
• No messages ar shown initially. The user has to choose a log (or a part of a log, e.g. the very important messages of a log)
This profile is used in transaction SLG1 when more than one log has been selected.
As the process of these function module is similar, let us take function module 'BAL_DSP_PROFILE_DETLEVEL_GET' as a example.
DATA: l_s_display_profile TYPE bal_s_prof.

* get a prepared profile
CALL FUNCTION 'BAL_DSP_PROFILE_DETLEVEL_GET'
IMPORTING
e_s_display_profile = l_s_display_profile
EXCEPTIONS
OTHERS = 1.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

* use grid for display if wanted
l_s_display_profile-use_grid = 'X'.
* set report to allow saving of variants
l_s_display_profile-disvariant-report = sy-repid.
* when you use also other ALV lists in your report,
* please specify a handle to distinguish between the display
* variants of these different lists, e.g:
l_s_display_profile-disvariant-handle = 'LOG'.

* call display function module
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXPORTING
i_s_display_profile = l_s_display_profile
EXCEPTIONS
PROFILE_INCONSISTENT = 1
INTERNAL_ERROR = 2
NO_DATA_AVAILABLE = 3
NO_AUTHORITY = 4
OTHERS = 5.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
11. Callback Routine
Using callback routines, we can affect the program flow at various events in Application Log. Callback routines can be FORM routines or function modules.
The following is a example which will popup a message whenever a message is sent to the application log.
DATA: g_s_configuration TYPE bal_s_conf.
DATA: g_s_log TYPE bal_s_log.
DATA: g_s_msg TYPE bal_s_msg.

* define callback to display a message when it occurs
PERFORM bal_callback_display_set
CHANGING
g_s_configuration.

* set this configuration
CALL FUNCTION 'BAL_GLB_CONFIG_SET'
EXPORTING
i_s_configuration = g_s_configuration
EXCEPTIONS
OTHERS = 0.

* create log
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = g_s_log
EXCEPTIONS
OTHERS = 0.

DO 3 TIMES.
g_s_msg-msgid = 'BL'.
g_s_msg-msgno = 326.
g_s_msg-msgty = 'E'.

* create message
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_s_msg = g_s_msg
EXCEPTIONS
OTHERS = 0.
ENDDO.

* display log
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXCEPTIONS
OTHERS = 1.

IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

*-------------------------------------------------------------------*
* FORM BAL_CALLBACK_DISPLAY_SET
*-------------------------------------------------------------------*
FORM bal_callback_display_set
CHANGING
c_s_configuration TYPE bal_s_conf.

* we want very important messages to occur immediately
c_s_configuration-display-callback-userexitt = ' '.
c_s_configuration-display-callback-userexitp = sy-repid.
c_s_configuration-display-callback-userexitf = 'BAL_CALLBACK_DISPLAY'.

ENDFORM. "bal_callback_display_set
*-------------------------------------------------------------------*
* FORM BAL_CALLBACK_DISPLAY
*-------------------------------------------------------------------*
FORM bal_callback_display
USING
i_s_msg TYPE bal_s_msg.

* issue a message
MESSAGE i325(bl) WITH 'BAL_CALLBACK_DISPLAY'.

ENDFORM. "bal_callback_display

No comments:

Post a Comment