如何优雅的使用 SAP 日志功能:应用程序日志

1,360 阅读10分钟

在本文中,我们将介绍一些常见的技巧,以及是否有针对它们的标准文档(请参阅 Auding and Logging )帮助文档。

在本文中,我们将主要考虑标准工具。所有代码清单都可以在 ZABAPFILEOS_07 年的 github 上找到。

SAP NetWeaver 中的日志记录类型

日志记录有 3 种类型:

  1. 系统日志:收集系统内事件的消息,比如:调试下编辑、更改设置、调用 HTTP 等。

  2. 应用程序日志:这是应用程序中内置的日志,其中信息由一些 id 业务实体(订单、交付、FI 文档等)写入和读取。

  3. 应用程序跟踪(按需详细系统日志):可以按用户、进程、作业激活和停用的详细日志。它用于跟踪 ABAP 代码、SQL 查询、RFC/HTTP 连接和权限检查的工具中。

在本文的第一部分,我们将查看应用程序日志,在本文的第二部分,我们将查看系统日志。

使用应用程序日志

请考虑业务线应用程序中使用的以下日志:

  1. 业务应用程序日志,(事务 SLG1 / SLG0 / SLG2)
  2. 更改凭证日志(事务码 SCDO )
  3. 表更改历史日志:(事务码 SCU3
  4. 通过 SE16N 编辑表格时显示更改

让我们稍微了解一下以下日志:

  1. IDOC 日志
  2. 以 SD/MM 输出日志(基于 NAST)
  3. ODATA-segw 网关日志
  4. SXI_MONITOR XI: 消息监控
  5. 工作流执行(事务码 SWI5

应用程序日志侧重于收集有关特定业务对象(采购订单、财务会计凭证文档或与业务数据处理相关的其他用户操作)的操作的信息。

业务应用程序日志 (BAL) – SLG1 / SLG0 / SLG2

业务应用程序日志是应用程序中最通用和最常用的日志,但它并不是唯一的日志。它有许多 API 和内置的交互式功能。有关此功能的文档,请参阅此处。此外,许多文章专门介绍了此功能以及 SAP 系统内带有演示程序的单独包 (SZAL)(它们的代码是 SBAL_DEMO_* )。如您所见,这是一个有据可查的功能,这增加了它的吸引力。

在系统和爱好者的开发中,此日志有许多日志封装包。我的建议:不要在上面制作另一个包装器(这是浪费时间)——最好使用现有的包装器(它们的数量足够多,而且非常不错)。一个示例IF_RECA_MESSAGE_LIST(基于类 CF_RECA_MESSAGE_LIST);此处描述了一个示例,以及系统中的许多示例。让我们看一下 BAL 功能的一些重要优势。在示例中,我将引用标准的 DEMO 程序,因此您始终可以查看这个或那个选项的实现,并在您的解决方案中实现它。

按层次树和显示消息的能力。 日志可以按层次树累计和显示数据,而不是在一个堆中,而是堆积和显示到某个属性(实体),而这些属性(实体)又可能具有子实体,而子实体又具有子实体。这样,您就不会对消息感到困惑;此外,我们可以按照严重性对消息进行过滤,这也提高了对日志的理解。为了显示此功能,让我们在 ALV 模式下运行 SBAL_DEMO_04_DETLEVEL 程序。

我们可以以树的形式显示日志,并仅显示(过滤)属于所需分支实体的消息。我们还可以根据消息的严重性显示日志。

image.png

日志的不同方式显示

应用程序日志可以显示为独立的窗口,比如弹出窗口 POPUP,或者自定义窗口(锁定父窗口的模式)和非 MODAL 窗口(不锁定父窗口)。要查看这些功能,可以运行 SBAL_DEMO_04 程序。

这个程序支持选择不同的方式用于显示日志:

image.png

  • 选择 Display logs,可以通过日志树方式显示,如图:

image.png

  • 选择 In subsreen,可以通过子屏幕显示内置日志,如图:

image.png

  • 选择 Display as popup,可以以带父窗口锁定的弹出日志显示,如图:

image.png

其他的显示方式,可以你自己探索一下哈。

日志数据保存到数据库

这些日志除了作为前台的展示,也能够保存到数据库,包括任何结构的附加数据。

使用方式可以通过 Demo 程序:SBAL_DEMO_05 和 SBAL_DEMO_06

image.png

SBAL_DEMO_05 和 SBAL_DEMO_06 演示了如何将日志保存到数据库,然后在事务码 SLG1 中显示它。

我们来看一下,程序SBAL_DEMO_06显示了如何将其他数据保存到日志中。

image.png

我们进入这个程序,点击 Create Log,就可以将附加数据保存到日志中,然后选择 Display Log(s) 并在数据库中显示:

image.png

当我们选择 Delete logs 就可以将日志数据从数据库中清除掉。

当我们为某条消息保存了数据后,会出现一个特殊图标,当您单击它时,会出现一个额外的屏幕。其他数据通过类似 INDX 的 table BAL_INDX 进行存储,其中主键是日志中的日志编号和消息编号。

image.png

回调功能:自定义按钮添加功能

日志具有添加用户自己的回调的内置功能,因此我们可以:添加自定义按钮来显示日志,将我们自己的处理程序添加到打开消息和其他回调的函数中。可能的回调在 SBAL_CALLBACK 程序中列出(您也可以在这些示例程序中找到软件实现)。

image.png

具有自定义事件处理程序:

image.png

现在,当我单击分支、消息和按钮时,我能够导航到其他事务,以更复杂的结构显示相邻数据,并导航到其他日志甚至系统😊。

在这篇文章中,我概述了那些在我看来最适用的可能性。如果您想查看其他功能,请通过事务 SE80 打开 SZAL 包(不是 SBAL, 而是 SZAL),然后查看 SBAL_DEMO*  程序。

系统里有 10 个内置的应用程序日志的 Demo 程序:

image.png

删除日志

使用 SBAL 日志时,请记住,应定期清除它们。也可以根据不同的参数配置清洁。这是通过 SLG2 事务完成的。使用登录应用程序时,我们能够指定特定条目的过期时间。该作业可以在后台运行。

用于删除过期日志的标准程序屏幕(SLG2 事务):

image.png

自定义日志对象

BAL 中的自定义对象示例。

让我们看一个逐步设置和使用日志的简单示例。

假设我们有一个程序,通过 HTTP 协议请求 ABFOS 系统中的数据(Advanced Business Flexible Operational Server 是一个基于 nginx 的训练服务器,专门用于演示、原型设计和测试 ERP 任务)。SAP ERP 系统通过 HTTP 协议发送带有参数(当前示例:RAM/product 和 date)的请求,并接受此物料的销售预测。 我们的任务是使用 应用程序日志制作 post-request 对象并以清晰的形式记录,并将其展示给用户。

让我们创建一个主对象:在我们的例子中,我们称它为 ZABFOS – Advanced Business Flex Operational System,以及一个子对象:ZFORECASTAI 辅助预测计算)。为此,请启动事务 SLG0 并单击 新条目

image.png

SLG0 中创建日志记录对象:

image.png

然后,在选择带有 ZABFOS 的行两次后,单击 Sub-Objects 子文件夹。

image.png

使用 *New Entry * 按钮。作为子对象,指定 ZFORECAST 和文本:使用 AI / AI 进行预测计算,如下面的屏幕截图所示。

image.png

对于日志记录,我们将使用基于 IF_RECA_MESSAGE_LIST 接口的类(此处有一篇关于此的精彩文章),对于存储复杂数据,我们将使用表 BAL_INDX。 存储复杂数据的方法将如下面的代码清单所示,该程序的完整代码可在此处获得。

  METHOD save_complex.
    DATA lv_json_http_info TYPE string.
    DATA lv_lognumb_ext TYPE balognr.

    lv_lognumb_ext = mo_msg_list->md_extnumber && mv_complex_counter.
    mv_complex_counter = mv_complex_counter + 1.

    lv_json_http_info =
    /ui2/cl_json=>serialize(
      EXPORTING
        data             = iv
    ).

    EXPORT http_call_json = lv_json_http_info
       TO DATABASE bal_indx(al)
     "  ID g_lognumber. "
       ID lv_lognumb_ext.

    MESSAGE s004(zabfos_msg) WITH lv_lognumb_ext INTO sy-msgli.
    me->add_prev_msg( ).
  ENDMETHOD.

http 调用存储请求、响应代码和完整的响应消息。显示在列表代码中(包含对 ABFOS 的调用)。

  METHOD _log_httpcall.

    MESSAGE s002(zabfos_msg) 
WITH ms_http_call-req_method ms_http_call-req_path
      INTO sy-msgli.
    mo_log->add_prev_msg( ).

    MESSAGE s003(zabfos_msg) WITH 
ms_http_call-resp_code ms_http_call-resp_reason
       INTO sy-msgli.
    mo_log->add_prev_msg( ).

    mo_log->save_complex( ms_http_call ).

  ENDMETHOD.

为了显示复合数据类型,我们将在查看消息时 “调用” 回调。为此,请在查看配置文件中将功能模块指定为回调。这将允许我们在双击消息时 “拦截” 处理。该程序的全部内容可在此处获取日志。

    ls_display_profile-clbk_ucbf-userexitp = ''.
    ls_display_profile-clbk_ucbf-userexitf = 'Z_AF07_SBAL_CALLBACK_BEFORE'.
    ls_display_profile-clbk_ucbf-userexitt = const_callback_function.

    ls_display_profile-clbk_ucaf-userexitp = ''.
    ls_display_profile-clbk_ucaf-userexitf = 'Z_AF07_SBAL_CALLBACK_AFTER'.
    ls_display_profile-clbk_ucaf-userexitt = const_callback_function.

功能模块本身可以包含任何处理(取决于需要和情况)。在我们的例子中,我们只是从 INDX 表中读取 http-request-response 并将其显示在 HTML 浏览器中。

FUNCTION z_af07_sbal_callback_before.
*"----------------------------------------------------------------------
*"*"Local Interface:
" CHANGING "
"     REFERENCE(C_S_USER_COMMAND_DATA) TYPE  BAL_S_CBUC"
*"----------------------------------------------------------------------
  DATA lc_complex_data_mark TYPE string VALUE 'Complex save id:'.
  DATA lv_trg_id TYPE string.
  DATA lv_log_id_indx TYPE balognr.
  DATA lv_http_info_json TYPE string.
  DATA html_xstring TYPE xstring.

  IF c_s_user_command_data-ucomm EQ '&IC1'.
    IF c_s_user_command_data-list_msgh-log_handle IS NOT INITIAL
        AND c_s_user_command_data-list_msgh-msgnumber IS NOT INITIAL.

      IF c_s_user_command_data-list_value CS lc_complex_data_mark.
        lv_trg_id = c_s_user_command_data-list_value.
        REPLACE ALL  OCCURRENCES OF lc_complex_data_mark IN lv_trg_id WITH ''.
        CONDENSE lv_trg_id NO-GAPS.
        lv_log_id_indx = lv_trg_id.

        IMPORT http_call_json = lv_http_info_json
          FROM DATABASE bal_indx(al)
            ID   lv_log_id_indx
            IGNORING STRUCTURE BOUNDARIES
            .

        TRY .
            CALL TRANSFORMATION sjson2html SOURCE XML lv_http_info_json
                                   RESULT XML html_xstring.

            cl_abap_browser=>show_html(
              html_string = cl_abap_codepage=>convert_from( html_xstring )
               ).

            c_s_user_command_data-ucomm_exec = abap_true.
          CATCH cx_root.

        ENDTRY.
      ENDIF.
    ENDIF.
  ENDIF.

ENDFUNCTION.

请注意,对于日志记录和显示,我们完整地使用 SLG1 概念和存储。

现在,当我们双击消息时,我们将打开一个 HTML 浏览器,其中包含详细的日志(我们想要的数据量)。带有演示数据(包括 nginx 配置、ABFOS rust 实现)的包发布在 github 上的仓库中。

应用程序日志可以使用自己的视图屏幕和回调进行扩展功能:

image.png

在处理日志(尤其是详细日志)时,您需要记住它们的清理和存储时间。这是通过事务 SLG2 完成的。还可以通过 SMICM 跟踪查看 HTTP 调用,但更多内容请参阅系统日志。

总结

本文总结了如何优雅的使用 SAP 系统标准日志功能,通过几个示例程序讲解了应用程序日志的展示方式,数据保存和日志删除功能。最后介绍了自定义日志对象,并将这个日志对象用于自定义程序当中,通过合理运用标准日志功能,可以在开发过程中大大提升效率,欢迎读者一起研究探索,并在系统中进行运用。

参考链接:OlegBash599/ZABAPFILEOS_07: Logging Samples (ANNA K*)