Variante 1 (cf_reca_message_list)
* Kapselt im Paket RE_CA_BC die FuBas der Funktionsgruppe SBAL (Paket SZAL) * BAL-Message-Collector Objekt anlegen * id_object: BAL-Objekttyp (SLG0, SLG1) * id_subobject: BAL-Unterobjekttyp (SLG0, SLG1) * id_extnumber: Freitext für spätere Suche in der SLG1, i.d.R. Belegnummern * id_deldate: Verfallsdatum der Lognachricht (i.d.R. 30 Tage) DATA(o_msg_list) = cf_reca_message_list=>create( id_object = 'Z_TEST_LOG' id_subobject = 'Z_TEST_LOG_U1' id_extnumber = 'Identifier_01234' id_deldate = CONV #( sy-datum + 30 ) ). * Log-Eintrag dem Message-Objekt hinzufügen o_msg_list->add( EXPORTING id_msgty = 'I' id_msgid = 'OO' id_msgno = '000' id_msgv1 = 'Text1' id_msgv2 = 'Text2' id_msgv3 = '' id_msgv4 = '' ). TRY. * Division durch Null provozieren DATA(lv_div) = 1 / 0. CATCH cx_root INTO DATA(e_txt). * Log-Eintrag dem Message-Objekt hinzufügen o_msg_list->add_from_exception( e_txt ). ENDTRY. * Message-Liste im BAL speichern o_msg_list->store( ). * Protokoll als Applikation bzw. Popup anzeigen CALL FUNCTION 'RECA_GUI_MSGLIST_POPUP' EXPORTING io_msglist = o_msg_list.
Variante 2 (BAL_LOG_CREATE)
* Paket: SZAL * Demo: SBAL_DEMO_* * Vorteil: vollständige Parametrierung über bal_s_log (Externe Identifikation, Verfallsdatum...) * Link: https://wiki.scn.sap.com/wiki/display/Snippets/Using+Application+Log CLASS lcl_applog DEFINITION. PUBLIC SECTION. TYPES: BEGIN OF ty_s_msgtext, msgv1 TYPE symsgv, msgv2 TYPE symsgv, msgv3 TYPE symsgv, msgv4 TYPE symsgv, END OF ty_s_msgtext . * Message-Typen CONSTANTS: co_msg_type_error TYPE symsgty VALUE 'E'. CONSTANTS: co_msg_type_warning TYPE symsgty VALUE 'W'. CONSTANTS: co_msg_type_info TYPE symsgty VALUE 'I'. * Problemklassen (Domäne BALPROBCL) * 1 sehr wichtig * 2 wichtig * 3 mittel * 4 Zusatzinformationen * Sonstiges CONSTANTS: co_problem_class_high TYPE balprobcl VALUE '1'. CONSTANTS: co_problem_class_medium TYPE balprobcl VALUE '2'. CONSTANTS: co_problem_class_low TYPE balprobcl VALUE '3'. CONSTANTS: co_problem_class_info TYPE balprobcl VALUE '4'. CONSTANTS: co_problem_class_other TYPE balprobcl VALUE ' '. CLASS-METHODS: create IMPORTING i_bal_s_log TYPE bal_s_log RETURNING VALUE(rv_ok) TYPE abap_bool. CLASS-METHODS: add_message IMPORTING i_probclass TYPE balprobcl DEFAULT co_problem_class_info i_msgtype TYPE symsgty DEFAULT co_msg_type_error i_msgid TYPE symsgid DEFAULT '01' " Verwendung der generische Nachrichtenklasse mit & & & & i_msgno TYPE symsgno DEFAULT '319' " Verwendung der generische Nachrichtenklasse mit & & & & i_msgv1 TYPE symsgv OPTIONAL i_msgv2 TYPE symsgv OPTIONAL i_msgv3 TYPE symsgv OPTIONAL i_msgv4 TYPE symsgv OPTIONAL RETURNING VALUE(rv_ok) TYPE abap_bool. CLASS-METHODS: add_string IMPORTING i_probclass TYPE balprobcl DEFAULT co_problem_class_info i_msgtype TYPE symsgty DEFAULT co_msg_type_error i_msgid TYPE symsgid DEFAULT '01' " Verwendung der generische Nachrichtenklasse mit & & & & i_msgno TYPE symsgno DEFAULT '319' " Verwendung der generische Nachrichtenklasse mit & & & & i_msg_text TYPE string RETURNING VALUE(rv_ok) TYPE abap_bool. CLASS-METHODS: add_exception IMPORTING i_probclass TYPE balprobcl DEFAULT co_problem_class_info i_msgtype TYPE symsgty DEFAULT co_msg_type_error i_exception TYPE REF TO cx_root RETURNING VALUE(rv_ok) TYPE abap_bool. CLASS-METHODS: save RETURNING VALUE(rv_ok) TYPE abap_bool. CLASS-METHODS: delete RETURNING VALUE(rv_ok) TYPE abap_bool. CLASS-METHODS: display_current IMPORTING i_title TYPE baltitle OPTIONAL i_it_balnri TYPE ehsky_balnri. CLASS-METHODS: display IMPORTING iv_object TYPE balhdr-object DEFAULT space iv_subobject TYPE balhdr-subobject DEFAULT space iv_external_number TYPE balhdr-extnumber DEFAULT space iv_object_attribute TYPE i DEFAULT 0 iv_subobject_attribute TYPE i DEFAULT 0 iv_external_number_attribute TYPE i DEFAULT 0 iv_date_from TYPE balhdr-aldate DEFAULT sy-datum iv_time_from TYPE balhdr-altime DEFAULT '000000' iv_date_to TYPE balhdr-aldate DEFAULT sy-datum iv_time_to TYPE balhdr-altime DEFAULT sy-uzeit iv_suppress_selection_dialog TYPE abap_bool DEFAULT abap_false iv_title_selection_screen TYPE char255 DEFAULT space iv_title_list_screen TYPE char255 DEFAULT space. CLASS-METHODS: has_data RETURNING VALUE(rv_has) TYPE abap_bool. PRIVATE SECTION. CLASS-DATA: gv_log_handle TYPE balloghndl. ENDCLASS. CLASS lcl_applog IMPLEMENTATION. * Log erzeugen und Log-Handle ermitteln METHOD create. rv_ok = abap_false. CALL FUNCTION 'BAL_LOG_CREATE' EXPORTING i_s_log = i_bal_s_log IMPORTING e_log_handle = gv_log_handle EXCEPTIONS log_header_inconsistent = 1 OTHERS = 2. IF sy-subrc = 0. rv_ok = abap_true. ENDIF. ENDMETHOD. * Log-Message hinzufügen * Achtung: Die Stringlänge für die Parameter i_msgv1, i_msgv2, i_msgv3 und i_msgv4 ist jeweils max. 50 Zeichen! METHOD add_message. rv_ok = abap_false. DATA(lv_msg) = VALUE bal_s_msg( probclass = i_probclass msgty = i_msgtype msgid = i_msgid msgno = i_msgno msgv1 = i_msgv1 msgv2 = i_msgv2 msgv3 = i_msgv3 msgv4 = i_msgv4 ). CALL FUNCTION 'BAL_LOG_MSG_ADD' EXPORTING i_log_handle = gv_log_handle i_s_msg = lv_msg EXCEPTIONS log_not_found = 1 msg_inconsistent = 2 log_is_full = 3 OTHERS = 4. IF sy-subrc = 0. rv_ok = abap_true. ENDIF. ENDMETHOD. METHOD add_string. rv_ok = abap_false. * String (max. 200 Zeichen) -> TY_S_MSGTEXT (msgv1 ... msgv4) (max. 4 x 50 Zeichen) wandeln DATA(lv_msg_text) = CONV ty_s_msgtext( i_msg_text ). DATA(lv_msg) = VALUE bal_s_msg( probclass = i_probclass msgty = i_msgtype msgid = i_msgid msgno = i_msgno msgv1 = lv_msg_text-msgv1 msgv2 = lv_msg_text-msgv2 msgv3 = lv_msg_text-msgv3 msgv4 = lv_msg_text-msgv4 ). * altenativ: Verwendung von FuBa BAL_LOG_MSG_ADD_FREE_TEXT CALL FUNCTION 'BAL_LOG_MSG_ADD' EXPORTING i_log_handle = gv_log_handle i_s_msg = lv_msg EXCEPTIONS log_not_found = 1 msg_inconsistent = 2 log_is_full = 3 OTHERS = 4. IF sy-subrc = 0. rv_ok = abap_true. ENDIF. ENDMETHOD. * Log-Message anhand einer Exception hinzufügen METHOD add_exception. rv_ok = abap_false. DATA(lv_ex) = VALUE bal_s_exc( probclass = i_probclass msgty = i_msgtype exception = i_exception ). CALL FUNCTION 'BAL_LOG_EXCEPTION_ADD' EXPORTING i_log_handle = gv_log_handle i_s_exc = lv_ex EXCEPTIONS log_not_found = 1 msg_inconsistent = 2 log_is_full = 3 OTHERS = 4. IF sy-subrc = 0. rv_ok = abap_true. ENDIF. ENDMETHOD. * akt. Log auf der Datenbank speichern METHOD save. rv_ok = abap_false. DATA: it_log_handle TYPE bal_t_logh. APPEND gv_log_handle TO it_log_handle. * alternativ: Verwendung von FuBa APPL_LOG_WRITE_DB CALL FUNCTION 'BAL_DB_SAVE' EXPORTING i_t_log_handle = it_log_handle EXCEPTIONS log_not_found = 1 save_not_allowed = 2 numbering_error = 3 OTHERS = 4. IF sy-subrc = 0. rv_ok = abap_true. ENDIF. ENDMETHOD. * Log-Messages löschen METHOD delete. rv_ok = abap_false. CALL FUNCTION 'BAL_LOG_MSG_DELETE_ALL' EXPORTING i_log_handle = gv_log_handle EXCEPTIONS log_not_found = 1 OTHERS = 2. IF sy-subrc = 0. rv_ok = abap_true. ENDIF. ENDMETHOD. * akt. Log anhand Lognumber anzeigen METHOD display_current. IF sy-batch IS INITIAL. DATA: lv_bal_s_prof TYPE bal_s_prof. CALL FUNCTION 'BAL_DSP_PROFILE_STANDARD_GET' IMPORTING e_s_display_profile = lv_bal_s_prof EXCEPTIONS OTHERS = 1. lv_bal_s_prof-show_all = abap_true. lv_bal_s_prof-cwidth_opt = abap_true. DATA(it_lognumbers) = VALUE szal_lognumbers( FOR <l> IN i_it_balnri ( item = <l>-lognumber ) ). CALL FUNCTION 'APPL_LOG_DISPLAY_WITH_LOGNO' EXPORTING title_list_screen = i_title i_s_display_profile = lv_bal_s_prof TABLES lognumbers = it_lognumbers EXCEPTIONS no_authority = 1 OTHERS = 2. ENDIF. ENDMETHOD. * SLG1 aufrufen: gesamtes Appl. Log anhand von Suchkriterien anzeigen METHOD display. CALL FUNCTION 'APPL_LOG_DISPLAY' EXPORTING object = iv_object subobject = iv_subobject external_number = iv_external_number object_attribute = iv_object_attribute subobject_attribute = iv_subobject_attribute external_number_attribute = iv_external_number_attribute date_from = iv_date_from time_from = iv_time_from date_to = iv_date_to time_to = iv_time_to title_selection_screen = iv_title_selection_screen title_list_screen = iv_title_list_screen * COLUMN_SELECTION = '11112221122 ' suppress_selection_dialog = iv_suppress_selection_dialog * COLUMN_SELECTION_MSG_JUMP = '1' * EXTERNAL_NUMBER_DISPLAY_LENGTH = 20 * I_S_DISPLAY_PROFILE = * I_VARIANT_REPORT = ' ' * I_SRT_BY_TIMSTMP = ' ' * IMPORTING * NUMBER_OF_PROTOCOLS = EXCEPTIONS no_authority = 1 OTHERS = 2. ENDMETHOD. * sind für das akt. Log Daten verfügbar METHOD has_data. rv_has = abap_false. DATA: lv_statistics TYPE bal_s_scnt. CALL FUNCTION 'BAL_LOG_HDR_READ' EXPORTING i_log_handle = gv_log_handle IMPORTING e_statistics = lv_statistics EXCEPTIONS log_not_found = 1 OTHERS = 2. IF sy-subrc = 0. CLEAR: lv_statistics-msg_max_pc. IF NOT lv_statistics IS INITIAL. rv_has = abap_true. ENDIF. ENDIF. ENDMETHOD. ENDCLASS. ********************************************************************** * * PARAMETERS * ********************************************************************** PARAMETERS: p_show AS CHECKBOX DEFAULT abap_false. ********************************************************************** * * START-OF-SELECTION * ********************************************************************** START-OF-SELECTION. IF abap_false = p_show. * Log-Objekte und Subobjekte definieren -> Transaktion SLG0 --> es werden Transportaufträge generiert * extnumber: Freitext für spätere Suche in der SLG1, i.d.R. Belegnummern * aldate_del: Verfallsdatum der Lognachricht (i.d.R. 30 Tage) DATA(lv_bal_log) = VALUE bal_s_log( object = 'Z_TEST_LOG' subobject = 'Z_TEST_LOG_U1' extnumber = 'Identifier_01234' aldate_del = sy-datum + 30 ). * Legt eine Protokoll-Instanz an * Log-Objekte werden in der Transaktion SLG0 definiert -> es werden Transportaufträge generiert * Anlegen der Objekte erfolgt in den Tabellen * BALOBJ (Anwendungs-Log: Objekte) * BALSUB (Anwendungs-Log: Unterobjekte) IF abap_true = lcl_applog=>create( i_bal_s_log = lv_bal_log ). * Protokolleinträge hinzufügen -> Nachrichten werden in der Transaktion SE91 gefplegt * Beispiel: Verwendung der vordefinierten Nachrichtenklasse 'S_AUT', Nr. '128' lcl_applog=>add_message( i_probclass = lcl_applog=>co_problem_class_info i_msgtype = lcl_applog=>co_msg_type_info i_msgid = 'S_AUT' i_msgno = '128' ). * Beispiel: Verwendung der generische Nachrichtenklasse mit & & & & für die Parameter msgv1 - msgv4 lcl_applog=>add_message( i_probclass = lcl_applog=>co_problem_class_info i_msgtype = lcl_applog=>co_msg_type_warning i_msgv1 = 'Test1' i_msgv2 = 'Test2' i_msgv3 = 'Test3' i_msgv4 = 'Test4' ). * Beispiel: Verwendung der generische Nachrichtenklasse mit & & & & lcl_applog=>add_string( i_probclass = lcl_applog=>co_problem_class_medium i_msgtype = lcl_applog=>co_msg_type_error i_msg_text = 'Testeintrag' ). TRY. * Ausnahme auslösen DATA(result) = 1 / 0. CATCH cx_root INTO DATA(e_txt). * Fügt eine Ausnahme hinzu, wobei * i_probclass: 1 - sehr wichtig * 2 - wichtig * 3 - mittel * 4 - Zusatzinformationen lcl_applog=>add_exception( i_probclass = lcl_applog=>co_problem_class_high i_msgtype = lcl_applog=>co_msg_type_error i_exception = e_txt ). ENDTRY. * Schließt und persistiert (speichert) das Protokoll * Protokoll kann auch in der Transaktion SLG1 angeschaut werden * Speicherung der Log-Daten erfolgt in den Tabellen * BALHDR (Anwendungs-Log: Protokollkopf) * BALDAT (Anwendungs-Log: Daten eines Protokolls) DATA: it_balnri TYPE ehsky_balnri. * Log speichern IF abap_true = lcl_applog=>save( ). * Beispiel: Verwendung der generische Nachrichtenklasse mit & & & & lcl_applog=>add_string( i_probclass = lcl_applog=>co_problem_class_other i_msgtype = lcl_applog=>co_msg_type_warning i_msg_text = 'Testeintrag warning' ). * Log speichern IF abap_true = lcl_applog=>save( ). * Existieren Meldungen? IF abap_true = lcl_applog=>has_data( ). * Protokoll anzeigen lcl_applog=>display_current( i_title = 'Application-Log' i_it_balnri = it_balnri ). ELSE. WRITE: / 'Keine Statistik verfügbar.'. ENDIF. ELSE. WRITE: / 'Fehler beim Speichern des Logs.'. ENDIF. ELSE. WRITE: / 'Fehler beim Speichern des Logs.'. ENDIF. ELSE. WRITE: / 'Fehler beim Erzeugen des Logs.'. ENDIF. ELSE. * SLG1 aufrufen lcl_applog=>display( iv_object = 'Z_TEST_LOG' iv_subobject = 'Z_TEST_LOG_U1' ). ENDIF.