SAP PI接口自定义监控应用

SXI_MONITOR需要区分接口是发送方还是接收方,查询没那么方便,可以自定义实现

直接通过业务单号匹配查询PI报文

1. 自定义PI接口日志表

公用配置表,定义每个PI接口的接口编码,对应PI接口INBOUND/OUTBOUND对象名,发送方接收方,对应FUNCTION功能模块名称,FM输入参数,FM输出参数,同步异步方式,分发系统等。

2. 封装PI接口公用类CLASS

ZCL_AB_INTERFACE 接口类(抽象类)

构造函数:

  METHOD check_interface_configuration.
    DATA(lv_fieldname) = VALUE string( ).

    IF iv_itfid IS INITIAL.
      lv_fieldname = 'ITFID'.
      ev_return_code = 4.
    ELSE.
      SELECT SINGLE * INTO ms_config
             FROM ztab0002
             WHERE itfid = iv_itfid.
      IF sy-subrc NE 0.
        ev_return_code = 4.
      ENDIF.
    ENDIF.

    "接口编码不存在
    IF ev_return_code = 4.
      RAISE EXCEPTION TYPE zcx_ab_interface_manager
        EXPORTING
          textid            = zcx_ab_interface_manager=>config_is_wrong "配置表不存在
          mv_intf_fieldname = CONV #( lv_fieldname ).
    ENDIF.

  ENDMETHOD.

保存PI LOG CLASS

定义公用属性

2.1 获取PI报文方法

初始化:

IV_MSGID    TYPE SXMSMGUID    XI:消息标识
IV_MANDT    TYPE SYMANDT    客户端标识
EV_PAYLOAD    TYPE STRING    Payload
EV_XPAYLOAD    TYPE XSTRING    
 

  METHOD get_payload.
    DATA:
    l_pro_s         TYPE        sxms_pro_s
  , l_pro_t         TYPE REF TO sxms_pro_t
  , l_manifest      TYPE REF TO cl_xms_msghdr30_manifest
  , string_data     TYPE        string
  , l_mf_s          TYPE        sxms_mf_s
  , l_mf_t          TYPE        sxms_mf_t
  , lt_message_ids  TYPE sxmscguid_t
  , lv_msgguid      TYPE sxmsmguid
  , lv_payload      TYPE string
  , l_resource      TYPE REF TO if_xms_resource.

*    REPLACE ALL OCCURRENCES OF  '-' IN iv_msgid WITH space.
    DATA(persist) = NEW cl_xms_persist( ).
    DATA(ls_filter) = VALUE sxi_message_filter( ).

    APPEND iv_msgid TO lt_message_ids.
    ls_filter-message_ids = lt_message_ids.
    ls_filter-client = iv_mandt.

    TRY.
        CALL METHOD cl_xi_ws_messmon=>get_message_list
          EXPORTING
            im_filter            = ls_filter
          IMPORTING
            ex_message_data_list = DATA(lt_message_data).

        DATA(ls_verstab) = VALUE sxmsvlst(
            mandt     = iv_mandt
            msgguid   = iv_msgid
*        pid       =
            version   = '000'
        ).

        IF lt_message_data[] IS NOT INITIAL.
          ls_verstab-pid = lt_message_data[ 1 ]-pid.
        ELSE.
          EXIT.
        ENDIF.

        CALL METHOD persist->read_msg_pub
          EXPORTING
            im_msgguid = ls_verstab-msgguid
            im_pid     = ls_verstab-pid
            im_version = ls_verstab-version
            im_client  = ls_verstab-mandt
          IMPORTING
            ex_message = DATA(lo_message).
      CATCH cx_xms_system_error INTO DATA(oref).
*        IF oref->previous IS NOT INITIAL.
*          oref = oref->previous.
*        ENDIF.
*       raise message only when no restart - on restart some versions might be deleted
*        IF gt_ucomm NE 'RESTART'.
*          MESSAGE oref  TYPE 'S' DISPLAY LIKE 'E'.
*        ENDIF.
*        lv_error = 'X'.
*        EXIT.
    ENDTRY.

    IF lo_message IS NOT INITIAL. " XI case
      l_pro_t = lo_message->getheaders( ).
      ASSIGN l_pro_t->* TO FIELD-SYMBOL(<fs1>).
    ENDIF.

    IF lo_message IS NOT INITIAL. " XI case
      l_pro_t = lo_message->getbodies( ).
*      ASSIGN l_pro_t->* TO FIELD-SYMBOL(<fs1>).
      ASSIGN l_pro_t->* TO <fs1>.
    ENDIF.

    LOOP AT <fs1> INTO l_pro_s.
      IF l_pro_s-lcname = cl_xms_manifest=>lcname.
        l_manifest ?= l_pro_s-prop.
        l_mf_t = l_manifest->get_payload_refs( ).

        LOOP AT l_mf_t INTO l_mf_s.
*      CLEAR ls_resource.
          l_resource = lo_message->getattachmentbyname( l_mf_s-href ).
          DATA(lv_xpayload) = l_resource->getbinarydata( ).

          DATA(conv) = cl_abap_conv_in_ce=>create( input = lv_xpayload ).
          conv->read( IMPORTING data = lv_payload len = DATA(len) ).

          ev_payload = lv_payload.
          ev_xpayload = lv_xpayload.
        ENDLOOP.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.

2.2 定义保存PI LOG method

  METHOD save_log.
    DATA:lv_msgid TYPE sxmsmguid,
         ls_stu   TYPE zsab0001.

    lv_msgid = ms_intf_log-msgid.
    IF lv_msgid IS INITIAL.
      RETURN.
    ENDIF.

*// 获取时间戳
    ls_stu = zcl_pubfm=>get_usrdt( ).

*// 获取返回报文GUID
    DATA(lt_msglist) = cl_xms_persist=>read_nested_msg( im_msgguid = lv_msgid ).
    DATA(ls_xiheader)     = VALUE sxmsmsglst_sorted( ).
    DATA(ls_xiheader_ref) = VALUE sxmsmsglst_sorted( ).
    LOOP AT lt_msglist INTO DATA(ls_msglist).
      IF ls_msglist-ref_to_msg IS INITIAL.
        ls_xiheader = ls_msglist.
      ELSE.
        ls_xiheader_ref = ls_msglist.
      ENDIF.
    ENDLOOP.
    ms_intf_log-refmsgid = ls_xiheader_ref-msgguid.  "返回报文GUID

    "时间戳
    ms_intf_log-cname     = ls_stu-cname.
    ms_intf_log-datum     = ls_stu-datum.
    ms_intf_log-uzeit     = ls_stu-uzeit.
    ms_intf_log-timestamp = ls_stu-timestamp.


*// 获取XML报文
    "获取PI 发送/接收报文
*    lv_msgid = ms_intf_log-msgid.
    zcl_pi_utility=>get_payload(
      EXPORTING
        iv_msgid    = lv_msgid
        iv_mandt    = sy-mandt
      IMPORTING
        ev_payload  = DATA(lv_payload)
        ev_xpayload = DATA(lv_xpayload) ).
    ms_intf_log-content = lv_payload.

    "获取PI 返回报文
    IF ms_intf_log-refmsgid IS NOT INITIAL.
      lv_msgid = ls_xiheader_ref-msgguid.
      CLEAR lv_payload.
      CLEAR lv_xpayload.
      zcl_pi_utility=>get_payload(
         EXPORTING
           iv_msgid    = lv_msgid
           iv_mandt    = sy-mandt
         IMPORTING
           ev_payload  = lv_payload
           ev_xpayload = lv_xpayload ).
      ms_intf_log-recontent = lv_payload.    "返回报文
    ENDIF.
    IF ms_intf_log-recontent IS INITIAL.
      ms_intf_log-recontent = mv_recontent.  "返回报文
    ENDIF.


*// 写入数据库
    MODIFY ztfi_intf_log FROM ms_intf_log.
    COMMIT WORK.


*// 清空变量
    FREE ms_intf_log.
    FREE mv_recontent.
  ENDMETHOD.
 

 call method save_log( ):

data po_pi1215   TYPE REF TO zvkco_si_pi1215_o_ecc_easzj_sa.

DATA: lv_msgid TYPE ztfi0025-msgid .
  DATA: lv_msgt TYPE string.

  IF po_pi1215 IS NOT INITIAL.  "空对象判断
    TRY.

       "XI:消息标识 
        po_protocol ?=  po_pi1215->get_protocol( if_wsprotocol=>message_id ).  
        lv_msgid   = po_protocol->get_message_id( ).

      CATCH cx_ai_system_fault.
    ENDTRY.
  ENDIF.

  zcl_fi_intf_log=>init_intf_log( is_intf_log = VALUE #( ywdj  = ps_z025-fkdnr
                                                         msgid = lv_msgid
                                                         itfid = 'PI1215_SAPPAYMENT_BILL'
                                                         mssgt = lv_msgt ) ).
  zcl_fi_intf_log=>save_log( ).

method get_usrdt.
  if if_crud is initial.
    rv_stru-cname = sy-uname.
    rv_stru-datum = sy-datum.
    rv_stru-uzeit = sy-uzeit.
    rv_stru-timestamp = date2tsp( ).
  else.
    rv_stru-uname = sy-uname.
    rv_stru-aedat = sy-datum.
    rv_stru-aezet = sy-uzeit.
    rv_stru-timestamp_upd = date2tsp( ).
  endif.
endmethod.
 

进站获取PI Message ID method:

  METHOD GET_MSGID_INBOUND.
    DATA:lo_protocol       TYPE REF TO if_wsprotocol_message_id,
         lo_server_context TYPE REF TO if_ws_server_context.

    "进站获取ABAP PROXY - GET MESSAGE ID - INBOUND
    TRY.
        lo_server_context = cl_proxy_access=>get_server_context( ).
        lo_protocol ?=  lo_server_context->get_protocol( if_wsprotocol=>message_id ).

        message_id = lo_protocol->get_message_id( ).
      CATCH cx_ai_system_fault.

    ENDTRY.
  ENDMETHOD.
 

转XML

  METHOD tr2_xml.

    TRY.
        CALL TRANSFORMATION id
                          OPTIONS value_handling = 'MOVE'   "防止内表中有N类型dump
                          SOURCE data = data
                          RESULT XML mv_recontent.
      CATCH cx_root INTO DATA(lo_root) .
    ENDTRY.
  ENDMETHOD.

3. 在需要业务端口调用保存PI LOG

如财务付款单PI接口或资金,凭证等其他接口

通过付款单作为业务单据号保存

 zcl_fi_intf_log=>init_intf_log( is_intf_log = VALUE #( ywdj  = <ls_impt>-payorder-fkdnr
                                                         msgid = lv_pi_msgid_out_raw
                                                         itfid = 'EASPAYMENTORDER4ZJ'
                                                         mssgt = lv_msgt ) ).
  zcl_fi_intf_log=>save_log( ).

如凭证信息接口保存:

  DATA lv_message_id TYPE sxmsmguid.                                " PI日志添加到自建表
  lv_message_id = zcl_fi_intf_log=>get_msgid_inbound( ).   

  LOOP AT is_input-i_request-message-header INTO DATA(ls_header).
    zcl_fi_intf_log=>init_intf_log( is_intf_log = VALUE #( ywdj  = ls_header-zbkpfid
                                                           msgid = lv_message_id
                                                           itfid = 'PI1022_DOCUMENT_DATA'
                                                           mssgt = '经营性凭证数据传输到ICP接口[ZPI1022]' ) ).
    zcl_fi_intf_log=>tr2_xml( data = es_output-e_response-returnstatus ).
    zcl_fi_intf_log=>save_log( ).
  ENDLOOP.

4. 定义PI报文查询报表

5. 自定义PI报文定期清理日志功能

************************************************************************
* TRANSATION ID        :
* PROGRAM TITLE        : ZFID_DELETE_LOG
* AUTHOR               :
* SUPPLIER             :
* DATE                 :
* DEVELOPMENT ID       : ZFID_DELETE_LOG
* CHANGE REQUEST (CTS) :
* DESCRIPTION          :
*=======================================================================
* COPIED FROM         : (CLONED PROGRAM)
* TITLE               : (PROGRAM TITLE)
* OTHER RELATED OBJ   : (OBJECT NAMES)
*=======================================================================
* CHANGE HISTORY LOG
*-----------------------------------------------------------------------
* MOD. NO.|  DATE    | NAME           | CORRECTION NUMBER  | CHANGE REFE
*-----------------------------------------------------------------------
* MOD-001 |YYYY.MM.DD| XXXXXXXXXXXXXX | XXXXXXXXXX         | XXXXXXXXXX
*
* DESCRIPTION:
*-----------------------------------------------------------------------
* MOD-002 |YYYY.MM.DD| XXXXXXXXXXXXXX | XXXXXXXXXX         | XXXXXXXXXX
*
* DESCRIPTION:
************************************************************************
REPORT zfid_delete_log MESSAGE-ID 00 NO STANDARD PAGE HEADING.
*---------------------------------------------------------------------*
* TABLES
*---------------------------------------------------------------------*
TABLES rsrd1.

*---------------------------------------------------------------------*
* SELECTION-SCREEN
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK blk WITH FRAME TITLE TEXT-001.

SELECT-OPTIONS s_tab FOR rsrd1-tbma_val OBLIGATORY.

SELECTION-SCREEN SKIP.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN COMMENT  1(79) TEXT-002.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN COMMENT  1(79) TEXT-003.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN COMMENT  1(79) TEXT-004.
SELECTION-SCREEN END OF BLOCK blk.
*---------------------------------------------------------------------*
* INITIALIZATION
*---------------------------------------------------------------------*
INITIALIZATION.
*---------------------------------------------------------------------*
* AT SELECTION-SCREEN
*---------------------------------------------------------------------*
AT SELECTION-SCREEN.
*---------------------------------------------------------------------*
* START-OF-SELECTION
*---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM frm_process_logic.
*&---------------------------------------------------------------------*
*&      Form  FRM_PROCESS_LOGIC
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_process_logic .
  DATA:lr_tabname TYPE RANGE OF tabname,
       lr_datum   TYPE RANGE OF datum,
       lv_datum   TYPE datum,
       lv_where   TYPE string.

*// 定期删除日志配置表
  SELECT * INTO TABLE @DATA(lt_ztfi_config_log) FROM ztfi_config_log WHERE disabled = '' AND tabname IN @s_tab.
  IF lt_ztfi_config_log IS INITIAL.
    MESSAGE '表ZTFI_CONFIG_LOG未找到配置' TYPE 'S' DISPLAY LIKE 'E'.
    REJECT.
  ENDIF.


*//  若存在配置表中代码未指定表,则报错。目的防止误删除。
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0462' ) ).              "财务业务接口日志表
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0382' ) ).              "EAS接口传输记录-日志表
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI_INTF_LOG' ) ).         "财务PI接口日志
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI_STATUS_LOG' ) ).       "财务单据-状态修改记录表
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI1241_LOG' ) ).          "作业ZFID1241ICP推送凭证信息到影像系统日志表
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0023_AUT_LOG' ) ).      "付款单自动签收日志表
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0480_LOG' ) ).          "ICP抽取IDP银行行号数据-推送外围系统日志
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0077_BG_LOG' ) ).       "ZFID025_02地物产值自动预提需求后台执行日志
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0490' ) ).              "账套主数据修改记录
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI0492' ) ).              "退款凭证未生成及房源启用标识更新日志表
  lr_tabname = VALUE #( BASE lr_tabname ( sign = 'I' option = 'EQ' low = 'ZTFI_PRO_UPD_LOG' ) ).      "付款单中项目分期和项目公司更新函数日志表

  DATA(lt_temp) = lt_ztfi_config_log.
  DELETE lt_temp WHERE tabname IN lr_tabname.

  IF lt_temp IS NOT INITIAL.
    WRITE:/ '执行失败:'.
    LOOP AT lt_temp INTO DATA(ls_temp).
      WRITE:/ '表',ls_temp-tabname,'未在代码指定不允许删除。'.
    ENDLOOP.
    RETURN.
  ENDIF.


*// 根据配置条件删除
  LOOP AT lt_ztfi_config_log INTO DATA(ls_ztfi_config_log).
    CASE ls_ztfi_config_log-tabname.
      WHEN 'ZTFI0382'.
        PERFORM frm_delete_ztfi0382 USING ls_ztfi_config_log.
        CONTINUE.
      WHEN 'ZTFI_INTF_LOG'.
        PERFORM frm_delete_ztfi_intf_log USING ls_ztfi_config_log.
        CONTINUE.
    ENDCASE.

    CLEAR lv_datum.
    CLEAR lr_datum.
    CLEAR lr_datum[].
    CLEAR lv_where.

    "计算日期
    lv_datum = sy-datum - ls_ztfi_config_log-zdays.
    lr_datum = VALUE #( ( sign = 'I' option = 'LE' low = |{ lv_datum  }| ) ).

    "删除条件
    lv_where = |{ ls_ztfi_config_log-filed_cond } IN LR_DATUM|.

    TRY.
        DELETE FROM (ls_ztfi_config_log-tabname) WHERE (lv_where).
        IF sy-subrc = 0.
          COMMIT WORK.
        ENDIF.

        DATA(lv_msg) = |表 { ls_ztfi_config_log-tabname }-{ ls_ztfi_config_log-filed_cond } <={ lv_datum },数据已删除成功,条目数{ sy-dbcnt }。|.
        WRITE:/ lv_msg.

      CATCH cx_root INTO DATA(oref).
        DATA(text) = oref->get_text( ).
        WRITE:/ '表',ls_ztfi_config_log-tabname,'删除失败&&',text.
    ENDTRY.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_DELETE_ZTFI0382
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LS_ZTFI_CONFIG_LOG  text
*----------------------------------------------------------------------*
FORM frm_delete_ztfi0382 USING VALUE(ls_ztfi_config_log) TYPE ztfi_config_log.
  DATA:lr_bizdate TYPE RANGE OF ztfi0382-bizdate.

  DO.
    lr_bizdate = VALUE #( ( sign = 'E' option = 'CP' low = |*{ sy-datum(4) }*| ) ).

    SELECT * INTO TABLE @DATA(lt_ztfi0382)
             FROM ztfi0382 UP TO 500000 ROWS
            WHERE bizdate IN @lr_bizdate.
    IF lt_ztfi0382 IS INITIAL.
      EXIT.
    ENDIF.

    LOOP AT lt_ztfi0382 INTO DATA(ls_ztfi0382) WHERE bizdate CS sy-datum(4).
      DATA(lv_tabix) = sy-tabix.
      DELETE lt_ztfi0382 INDEX lv_tabix.
    ENDLOOP.


    DELETE ztfi0382 FROM TABLE lt_ztfi0382.
    IF sy-subrc = 0.
      COMMIT WORK.
    ENDIF.

    DATA(lv_msg) = |表 { ls_ztfi_config_log-tabname }-{ ls_ztfi_config_log-filed_cond } <={ sy-datum(4) - 1 }1231,数据已删除成功,条目数{ sy-dbcnt }。|.
    WRITE:/ lv_msg.
  ENDDO.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_DELETE_ZTFI0382
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LS_ZTFI_CONFIG_LOG  text
*----------------------------------------------------------------------*
FORM frm_delete_ztfi_intf_log USING VALUE(ls_ztfi_config_log) TYPE ztfi_config_log.
  DATA:lr_datum TYPE RANGE OF ztfi0382-bizdate,
       lv_datum TYPE datum,
       lv_where TYPE string.
  "计算日期
  lv_datum = sy-datum - ls_ztfi_config_log-zdays.
  lr_datum = VALUE #( BASE lr_datum ( sign = 'I' option = 'LE' low = |{ lv_datum  }| ) ).

  "删除条件
  lv_where = |{ ls_ztfi_config_log-filed_cond } IN LR_DATUM AND ITFID EQ '{ ls_ztfi_config_log-itfid }'|.

  DELETE FROM ztfi_intf_log WHERE (lv_where).
  IF sy-subrc = 0.
    COMMIT WORK.
  ENDIF.

  DATA(lv_msg) = |表 { ls_ztfi_config_log-tabname }-{ ls_ztfi_config_log-filed_cond } <={ lv_datum },接口编号{ ls_ztfi_config_log-itfid },数据已删除成功,条目数{ sy-dbcnt }。|.
  WRITE:/ lv_msg.
ENDFORM.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值