From e5e558a312ed43bd71500c999b20b1fc9a978898 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 27 Mar 2021 11:57:57 +0200 Subject: [PATCH] Log refactoring, part 1 (#4676) * log: new features * log in exception * log via gui_services Co-authored-by: Lars Hvam --- src/ui/core/zcl_abapgit_gui.clas.abap | 17 ++ ...t_gui_html_processor.clas.testclasses.abap | 2 + .../core/zif_abapgit_gui_services.intf.abap | 5 + ...l_abapgit_ui_injector.clas.locals_imp.abap | 3 + src/utils/zcl_abapgit_log.clas.abap | 112 ++++++++-- .../zcl_abapgit_log.clas.testclasses.abap | 196 ++++++++++++++++++ src/utils/zif_abapgit_log.intf.abap | 32 ++- src/zcx_abapgit_exception.clas.abap | 12 +- 8 files changed, 363 insertions(+), 16 deletions(-) diff --git a/src/ui/core/zcl_abapgit_gui.clas.abap b/src/ui/core/zcl_abapgit_gui.clas.abap index 337501ac4..d776d9b41 100644 --- a/src/ui/core/zcl_abapgit_gui.clas.abap +++ b/src/ui/core/zcl_abapgit_gui.clas.abap @@ -72,6 +72,7 @@ CLASS zcl_abapgit_gui DEFINITION DATA mi_html_processor TYPE REF TO zif_abapgit_gui_html_processor . DATA mi_html_viewer TYPE REF TO zif_abapgit_html_viewer . DATA mo_html_parts TYPE REF TO zcl_abapgit_html_parts . + DATA mi_common_log TYPE REF TO zif_abapgit_log . METHODS cache_html IMPORTING @@ -303,6 +304,11 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. IF li_gui_error_handler IS BOUND AND li_gui_error_handler->handle_error( ix_exception ) = abap_true. " We rerender the current page to display the error box render( ). + ELSEIF ix_exception->mi_log IS BOUND. + mi_common_log = ix_exception->mi_log. + IF mi_common_log->get_log_level( ) >= zif_abapgit_log=>c_log_level-warning. + zcl_abapgit_log_viewer=>show_log( mi_common_log ). + ENDIF. ELSE. MESSAGE ix_exception TYPE 'S' DISPLAY LIKE 'E'. ENDIF. @@ -476,6 +482,17 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_gui_services~get_log. + + IF iv_create_new = abap_true OR mi_common_log IS NOT BOUND. + CREATE OBJECT mi_common_log TYPE zcl_abapgit_log. + ENDIF. + + ri_log = mi_common_log. + + ENDMETHOD. + + METHOD zif_abapgit_gui_services~register_event_handler. ASSERT ii_event_handler IS BOUND. INSERT ii_event_handler INTO mt_event_handlers INDEX 1. diff --git a/src/ui/core/zcl_abapgit_gui_html_processor.clas.testclasses.abap b/src/ui/core/zcl_abapgit_gui_html_processor.clas.testclasses.abap index 414a121c5..5866bb9a0 100644 --- a/src/ui/core/zcl_abapgit_gui_html_processor.clas.testclasses.abap +++ b/src/ui/core/zcl_abapgit_gui_html_processor.clas.testclasses.abap @@ -29,6 +29,8 @@ CLASS ltcl_gui_mock IMPLEMENTATION. ENDMETHOD. METHOD zif_abapgit_gui_services~get_html_parts. ENDMETHOD. + METHOD zif_abapgit_gui_services~get_log. + ENDMETHOD. METHOD get_asset. rs_asset = ms_last_cache_signature. diff --git a/src/ui/core/zif_abapgit_gui_services.intf.abap b/src/ui/core/zif_abapgit_gui_services.intf.abap index c5f4e0361..a51ce5f73 100644 --- a/src/ui/core/zif_abapgit_gui_services.intf.abap +++ b/src/ui/core/zif_abapgit_gui_services.intf.abap @@ -25,4 +25,9 @@ INTERFACE zif_abapgit_gui_services METHODS get_html_parts RETURNING VALUE(ro_parts) TYPE REF TO zcl_abapgit_html_parts . + METHODS get_log + IMPORTING + iv_create_new TYPE abap_bool DEFAULT abap_false + RETURNING + VALUE(ri_log) TYPE REF TO zif_abapgit_log. ENDINTERFACE. diff --git a/src/ui/zcl_abapgit_ui_injector.clas.locals_imp.abap b/src/ui/zcl_abapgit_ui_injector.clas.locals_imp.abap index a6025a079..37255155a 100644 --- a/src/ui/zcl_abapgit_ui_injector.clas.locals_imp.abap +++ b/src/ui/zcl_abapgit_ui_injector.clas.locals_imp.abap @@ -20,4 +20,7 @@ CLASS lcl_gui_services_dummy IMPLEMENTATION. ENDMETHOD. METHOD zif_abapgit_gui_services~get_html_parts. ENDMETHOD. + METHOD zif_abapgit_gui_services~get_log. + ENDMETHOD. + ENDCLASS. diff --git a/src/utils/zcl_abapgit_log.clas.abap b/src/utils/zcl_abapgit_log.clas.abap index c5e0f687b..d06cf5986 100644 --- a/src/utils/zcl_abapgit_log.clas.abap +++ b/src/utils/zcl_abapgit_log.clas.abap @@ -5,16 +5,22 @@ CLASS zcl_abapgit_log DEFINITION PUBLIC SECTION. INTERFACES zif_abapgit_log . + + METHODS constructor + IMPORTING + iv_title TYPE string OPTIONAL. + + CLASS-METHODS from_exception + IMPORTING + io_x TYPE REF TO cx_root + RETURNING + VALUE(ro_log) TYPE REF TO zcl_abapgit_log. + PROTECTED SECTION. - TYPES: - BEGIN OF ty_msg, - text TYPE string, - type TYPE sy-msgty, - END OF ty_msg . TYPES: BEGIN OF ty_log, "in order of occurrence - msg TYPE ty_msg, + msg TYPE zif_abapgit_log=>ty_msg, rc TYPE sy-subrc, item TYPE zif_abapgit_definitions=>ty_item, exception TYPE REF TO cx_root, @@ -37,6 +43,24 @@ ENDCLASS. CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. + METHOD constructor. + + zif_abapgit_log~set_title( iv_title ). + + ENDMETHOD. + + + METHOD from_exception. + + CREATE OBJECT ro_log. + + IF io_x IS BOUND. + ro_log->zif_abapgit_log~add_exception( io_x ). + ENDIF. + + ENDMETHOD. + + METHOD get_messages_status. DATA lr_msg TYPE REF TO zif_abapgit_log=>ty_msg. @@ -73,6 +97,17 @@ CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. -item = is_item. -exception = ix_exc. + CASE iv_type. + WHEN 'E' OR 'A' OR 'X'. + -msg-level = zif_abapgit_log=>c_log_level-error. + WHEN 'W'. + -msg-level = zif_abapgit_log=>c_log_level-warning. + WHEN 'S' OR 'I'. + -msg-level = zif_abapgit_log=>c_log_level-info. + WHEN OTHERS. "unknown + ASSERT 0 = 1. + ENDCASE. + ENDMETHOD. @@ -90,7 +125,7 @@ CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. DATA lx_exc TYPE REF TO cx_root. DATA lv_msg TYPE string. - lx_exc ?= ix_exc. + lx_exc = ix_exc. DO. lv_msg = lx_exc->get_text( ). zif_abapgit_log~add( iv_msg = lv_msg @@ -142,6 +177,17 @@ CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_log~clone. + + DATA lo_log TYPE REF TO zcl_abapgit_log. + + CREATE OBJECT lo_log EXPORTING iv_title = mv_title. + lo_log->mt_log = mt_log. + ri_log = lo_log. + + ENDMETHOD. + + METHOD zif_abapgit_log~count. rv_count = lines( mt_log ). ENDMETHOD. @@ -185,6 +231,24 @@ CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_log~get_log_level. + + FIELD-SYMBOLS LIKE LINE OF mt_log. + + rv_level = zif_abapgit_log=>c_log_level-empty. + + LOOP AT mt_log ASSIGNING . + IF -msg-level = zif_abapgit_log=>c_log_level-error. + rv_level = zif_abapgit_log=>c_log_level-error. + EXIT. + ELSEIF -msg-level > rv_level. + rv_level = -msg-level. + ENDIF. + ENDLOOP. + + ENDMETHOD. + + METHOD zif_abapgit_log~get_messages. DATA ls_msg TYPE zif_abapgit_log~ty_log_out. FIELD-SYMBOLS TYPE ty_log. @@ -202,22 +266,22 @@ CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. METHOD zif_abapgit_log~get_status. DATA lr_log TYPE REF TO ty_log. - rv_status = 'S'. + rv_status = zif_abapgit_log=>c_status-ok. LOOP AT mt_log REFERENCE INTO lr_log. CASE lr_log->msg-type. WHEN 'E' OR 'A' OR 'X'. - rv_status = 'E'. "not okay + rv_status = zif_abapgit_log=>c_status-error. EXIT. WHEN 'W'. - rv_status = 'W'. "maybe + rv_status = zif_abapgit_log=>c_status-warning. CONTINUE. WHEN 'S' OR 'I'. - IF rv_status <> 'W'. - rv_status = 'S'. "okay + IF rv_status <> zif_abapgit_log=>c_status-warning. + rv_status = zif_abapgit_log=>c_status-ok. ENDIF. CONTINUE. WHEN OTHERS. "unknown - CONTINUE. + ASSERT 0 = 1. ENDCASE. ENDLOOP. @@ -240,7 +304,29 @@ CLASS ZCL_ABAPGIT_LOG IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_log~merge_with. + + DATA lo_log TYPE REF TO zcl_abapgit_log. + DATA lt_log_temp LIKE lo_log->mt_log. + + IF ii_log IS BOUND. + lo_log ?= ii_log. + IF iv_min_level > 0. + lt_log_temp = lo_log->mt_log. + DELETE lt_log_temp WHERE msg-level < iv_min_level. + APPEND LINES OF lt_log_temp TO mt_log. + ELSE. + APPEND LINES OF lo_log->mt_log TO mt_log. + ENDIF. + ENDIF. + + ri_log = me. + + ENDMETHOD. + + METHOD zif_abapgit_log~set_title. mv_title = iv_title. + ri_log = me. ENDMETHOD. ENDCLASS. diff --git a/src/utils/zcl_abapgit_log.clas.testclasses.abap b/src/utils/zcl_abapgit_log.clas.testclasses.abap index 1937b3b01..d23c5e975 100644 --- a/src/utils/zcl_abapgit_log.clas.testclasses.abap +++ b/src/utils/zcl_abapgit_log.clas.testclasses.abap @@ -7,7 +7,13 @@ CLASS ltcl_test DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS FINAL. METHODS: setup, + from_x FOR TESTING, + get_status FOR TESTING, + get_log_level FOR TESTING, + merge_with FOR TESTING, + merge_with_min_level FOR TESTING, empty FOR TESTING, + clone FOR TESTING, add FOR TESTING. ENDCLASS. @@ -58,4 +64,194 @@ CLASS ltcl_test IMPLEMENTATION. ENDMETHOD. + METHOD get_status. + + DATA lo_x TYPE REF TO zcx_abapgit_exception. + + mi_cut->add_success( 'success' ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_status( ) + exp = zif_abapgit_log=>c_status-ok ). + + mi_cut->add_warning( 'warn' ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_status( ) + exp = zif_abapgit_log=>c_status-warning ). + + mi_cut->add_error( 'err' ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_status( ) + exp = zif_abapgit_log=>c_status-error ). + + mi_cut->clear( ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_status( ) + exp = zif_abapgit_log=>c_status-ok ). + + CREATE OBJECT lo_x EXPORTING msgv1 = 'x'. + mi_cut->add_exception( lo_x ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_status( ) + exp = zif_abapgit_log=>c_status-error ). + + ENDMETHOD. + + METHOD merge_with. + + DATA li_secondary_log LIKE mi_cut. + DATA lt_act_msgs TYPE zif_abapgit_log=>ty_log_outs. + + CREATE OBJECT li_secondary_log TYPE zcl_abapgit_log. + + mi_cut->add_success( 'success' ). + li_secondary_log->add_warning( 'warn' ). + mi_cut->merge_with( li_secondary_log ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->count( ) + exp = 2 ). + + lt_act_msgs = mi_cut->get_messages( ). + + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY text = 'success'. + cl_abap_unit_assert=>assert_subrc( ). + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY text = 'warn'. + cl_abap_unit_assert=>assert_subrc( ). + + ENDMETHOD. + + METHOD merge_with_min_level. + + DATA li_secondary_log LIKE mi_cut. + DATA lt_act_msgs TYPE zif_abapgit_log=>ty_log_outs. + + CREATE OBJECT li_secondary_log TYPE zcl_abapgit_log. + + mi_cut->add_success( 'success' ). + li_secondary_log->add_warning( 'warn' ). + mi_cut->merge_with( + ii_log = li_secondary_log + iv_min_level = zif_abapgit_log=>c_log_level-error ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->count( ) + exp = 1 ). + + lt_act_msgs = mi_cut->get_messages( ). + + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY text = 'success'. + cl_abap_unit_assert=>assert_subrc( ). + + " change level to warning + mi_cut->merge_with( + ii_log = li_secondary_log + iv_min_level = zif_abapgit_log=>c_log_level-warning ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->count( ) + exp = 2 ). + + lt_act_msgs = mi_cut->get_messages( ). + + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY text = 'success'. + cl_abap_unit_assert=>assert_subrc( ). + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY text = 'warn'. + cl_abap_unit_assert=>assert_subrc( ). + + ENDMETHOD. + + METHOD from_x. + + DATA lo_x TYPE REF TO zcx_abapgit_exception. + DATA lt_act_msgs TYPE zif_abapgit_log=>ty_log_outs. + + " Uninitialized + mi_cut = zcl_abapgit_log=>from_exception( lo_x ). + cl_abap_unit_assert=>assert_equals( + act = mi_cut->count( ) + exp = 0 ). + + " Notmal exception + TRY. + zcx_abapgit_exception=>raise( 'Error!' ). + CATCH zcx_abapgit_exception INTO lo_x. + mi_cut = zcl_abapgit_log=>from_exception( lo_x ). + ENDTRY. + + cl_abap_unit_assert=>assert_bound( mi_cut ). + cl_abap_unit_assert=>assert_equals( + act = mi_cut->count( ) + exp = 1 ). + + lt_act_msgs = mi_cut->get_messages( ). + + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY type = 'E'. + cl_abap_unit_assert=>assert_subrc( ). + READ TABLE lt_act_msgs TRANSPORTING NO FIELDS WITH KEY text = 'Error!'. + cl_abap_unit_assert=>assert_subrc( ). + + ENDMETHOD. + + METHOD get_log_level. + + DATA lo_x TYPE REF TO zcx_abapgit_exception. + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_log_level( ) + exp = zif_abapgit_log=>c_log_level-empty ). + + mi_cut->add_success( 'success' ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_log_level( ) + exp = zif_abapgit_log=>c_log_level-info ). + + mi_cut->add_warning( 'warn' ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_log_level( ) + exp = zif_abapgit_log=>c_log_level-warning ). + + mi_cut->add_error( 'err' ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_log_level( ) + exp = zif_abapgit_log=>c_log_level-error ). + + CREATE OBJECT lo_x EXPORTING msgv1 = 'x'. + mi_cut->add_exception( lo_x ). + + cl_abap_unit_assert=>assert_equals( + act = mi_cut->get_log_level( ) + exp = zif_abapgit_log=>c_log_level-error ). + + ENDMETHOD. + + METHOD clone. + + DATA li_clone TYPE REF TO zif_abapgit_log. + + mi_cut->add( 'Hello' ). + mi_cut->set_title( 'My log' ). + + li_clone = mi_cut->clone( ). + + mi_cut->add( 'World' ). + mi_cut->set_title( 'My log CHANGED' ). + + cl_abap_unit_assert=>assert_equals( + act = li_clone->count( ) + exp = 1 ). + + cl_abap_unit_assert=>assert_equals( + act = li_clone->get_title( ) + exp = 'My log' ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/utils/zif_abapgit_log.intf.abap b/src/utils/zif_abapgit_log.intf.abap index 455050e33..e24e9e01d 100644 --- a/src/utils/zif_abapgit_log.intf.abap +++ b/src/utils/zif_abapgit_log.intf.abap @@ -1,6 +1,20 @@ INTERFACE zif_abapgit_log PUBLIC . + CONSTANTS: + BEGIN OF c_status, + ok TYPE sy-msgty VALUE 'S', + error TYPE sy-msgty VALUE 'E', + warning TYPE sy-msgty VALUE 'W', + END OF c_status. + + CONSTANTS: + BEGIN OF c_log_level, + empty TYPE i VALUE 0, + info TYPE i VALUE 1, + warning TYPE i VALUE 2, + error TYPE i VALUE 3, + END OF c_log_level. TYPES: BEGIN OF ty_log_out, @@ -17,6 +31,7 @@ INTERFACE zif_abapgit_log BEGIN OF ty_msg, text TYPE string, type TYPE sy-msgty, + level TYPE i, END OF ty_msg . TYPES: ty_msgs TYPE STANDARD TABLE OF ty_msg @@ -76,10 +91,25 @@ INTERFACE zif_abapgit_log METHODS get_status RETURNING VALUE(rv_status) TYPE sy-msgty . + METHODS get_log_level + RETURNING + VALUE(rv_level) TYPE i . METHODS get_title RETURNING VALUE(rv_title) TYPE string . METHODS set_title IMPORTING - !iv_title TYPE csequence . + !iv_title TYPE csequence + RETURNING + VALUE(ri_log) TYPE REF TO zif_abapgit_log. + METHODS merge_with + IMPORTING + ii_log TYPE REF TO zif_abapgit_log + iv_min_level TYPE i DEFAULT 0 + RETURNING + VALUE(ri_log) TYPE REF TO zif_abapgit_log. + METHODS clone + RETURNING + VALUE(ri_log) TYPE REF TO zif_abapgit_log. + ENDINTERFACE. diff --git a/src/zcx_abapgit_exception.clas.abap b/src/zcx_abapgit_exception.clas.abap index 135d5bdc4..ae6df16de 100644 --- a/src/zcx_abapgit_exception.clas.abap +++ b/src/zcx_abapgit_exception.clas.abap @@ -27,6 +27,7 @@ CLASS zcx_abapgit_exception DEFINITION DATA msgv3 TYPE symsgv READ-ONLY . DATA msgv4 TYPE symsgv READ-ONLY . DATA mt_callstack TYPE abap_callstack READ-ONLY . + DATA mi_log TYPE REF TO zif_abapgit_log READ-ONLY. "! Raise exception with text "! @parameter iv_text | Text @@ -36,6 +37,7 @@ CLASS zcx_abapgit_exception DEFINITION IMPORTING !iv_text TYPE clike !ix_previous TYPE REF TO cx_root OPTIONAL + !ii_log TYPE REF TO zif_abapgit_log OPTIONAL RAISING zcx_abapgit_exception . "! Raise exception with T100 message @@ -57,6 +59,7 @@ CLASS zcx_abapgit_exception DEFINITION VALUE(iv_msgv2) TYPE symsgv DEFAULT sy-msgv2 VALUE(iv_msgv3) TYPE symsgv DEFAULT sy-msgv3 VALUE(iv_msgv4) TYPE symsgv DEFAULT sy-msgv4 + !ii_log TYPE REF TO zif_abapgit_log OPTIONAL !ix_previous TYPE REF TO cx_root OPTIONAL RAISING zcx_abapgit_exception . @@ -69,6 +72,7 @@ CLASS zcx_abapgit_exception DEFINITION IMPORTING !textid LIKE if_t100_message=>t100key OPTIONAL !previous LIKE previous OPTIONAL + !ii_log TYPE REF TO zif_abapgit_log OPTIONAL !msgv1 TYPE symsgv OPTIONAL !msgv2 TYPE symsgv OPTIONAL !msgv3 TYPE symsgv OPTIONAL @@ -110,7 +114,7 @@ ENDCLASS. -CLASS ZCX_ABAPGIT_EXCEPTION IMPLEMENTATION. +CLASS zcx_abapgit_exception IMPLEMENTATION. METHOD constructor ##ADT_SUPPRESS_GENERATION. @@ -121,6 +125,7 @@ CLASS ZCX_ABAPGIT_EXCEPTION IMPLEMENTATION. me->msgv2 = msgv2. me->msgv3 = msgv3. me->msgv4 = msgv4. + me->mi_log = ii_log. CLEAR me->textid. IF textid IS INITIAL. @@ -299,7 +304,9 @@ CLASS ZCX_ABAPGIT_EXCEPTION IMPLEMENTATION. split_text_to_symsg( lv_text ). - raise_t100( ix_previous = ix_previous ). + raise_t100( + ii_log = ii_log + ix_previous = ix_previous ). ENDMETHOD. @@ -321,6 +328,7 @@ CLASS ZCX_ABAPGIT_EXCEPTION IMPLEMENTATION. RAISE EXCEPTION TYPE zcx_abapgit_exception EXPORTING textid = ls_t100_key + ii_log = ii_log msgv1 = iv_msgv1 msgv2 = iv_msgv2 msgv3 = iv_msgv3