SAP 小技巧记录报表程序的执行日志

作者:ABAP技巧与实战 约 9 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, 开发
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

原创 无峰 [ ABAP 技巧与实战 ](javascript:void\(0\);)

前言

有时候项目上基于如下原因会追查特定事务代码的执行情况.

• 性能分析

• 安全性分析

• ……

有些标准的功能可以查询事务代码的执行情况. 但似乎只有调用记录, 没有需要的细节信息,比如:选择条件,查询记录数等.因此考虑自行记录程序(/报表)的执行日志

**本文主要介绍报表执行日志的记录**

思维导图

把程序调用日志相关的内容整理了一下.

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

标准的程序调用分析

标准分析有两个事务代码 STATS 和 SM20

用ST12粗略分析了一下这两个事务代码查询数据的存储

STATS 似乎是存在文件系统中的. 没有记录到表里, 因此内容保留周期有限,查询性能较差.

SM20 数据存储在 PRSAULOG, P_RSAU_LOG 中. 可以长期保留,除非有后台作业清除表内容.

执行一个标准报表MB51后.

查看标准的程序调用分析功能

STATS

这个事务偏性能分析, 可以查询到特定用户,特定事务代码执行的系统性能开销信息

STATS限制日期范围受 length影响, 最多99小时. end date 按 start date + length 计算而来.

这个设计应该是考虑性能问题. 实际测试发现 STATS只能查询最近3天的内容

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

SM20 安全审计日志

安全审计日志需要先开启安全审计功能

关于安全审计功能的相关减少, 详见如下链接

https://blog.csdn.net/lostworld_gy/article/details/86090644

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

自定义类记录

基于标准分析没有想要的内容,主要是选择屏幕内容.

因此考虑通过自定义类方法来记录 zcl_report=>save_rep_log_pub

如下图,在自定义程序的如下三个位置分别调用类方法即可.

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

控制表

ZTREPORT_C1

报表日志配置(如未配置,视同为都记录)

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

记录表

ZTREPORT_LOG

报表执行日志

选择屏幕内容部分记录到 INDX(ZP)

> INDX应用详见链接 无峰,公众号:ABAP 技巧与实战 [ SAP小技巧 使用EXPORT/IMPORT保存特殊数据

> ](https://mp.weixin.qq.com/s?__biz=Mzg4MjA1MjE4NQ==&mid=2247486037&idx=1&sn=40786ce2465ba450a93ba6f4ffca7635&chksm=cf5dd763f82a5e7544af109794dadf873036bd3949f8fb07553176b814bbaf4bf8f707349caa&token=2032717129&lang=zh_CN#rd)

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

记录结果的查询

可以指定统计的日期维度,按限制的条件查询统计结果或明细结果

在统计结果中,点击条目数可以显示明细调用

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

执行结果按统计/明细两个窗口呈现.

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

明细中可以通过点击显示变式查看当时的查询条件

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

可以通过带变式执行功能重新执行程序并带入当时的选择条件(跳过选择屏幕)

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

对动态报表的支持

动态报表的执行按动态报表的查询ID代替程序名来记录执行情况. ZDQ中开放了一个日志按钮查询历史执行情况. 点击后, 可以查看当前查询ID的执行情况,

动态报表因为使用了动态选择屏幕, 不支持显示变式功能. 但支持带变式执行功能.

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

对标准程序的支持

自定义程序可以在代码中添加相应的语句取记录执行日志. 但是不可能修改标准程序去添加记录日志的代码. 因此考虑把相关的日志记录放到底层报表执行框架中 .

反复跟踪测试发现如下位置可以完成

报表执行时记录一次. 获取初始时间戳

程序 RSDBRUNT FORM POP_SCREEN. 报表程序执行时,都会进入这个节点 ,可以作为报表执行的开始节点

其它程序通过SUBMIT调用程序, 也会进入这个节点. 但是此时MEMKEY-REPORT = '' 无法记录.

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
IF -ucomm = 'ONLI' AND memkey-report IS NOT INITIAL.
DATA(lv_active) = zcl_enh_control=>check_enh_actvt( 'ZENH_10068' ).
IF lv_active = 'X'.
INCLUDE zenh_10068.
ENDIF.
ENDIF.

ALV显示前,记录一次, 获取读取得记录数, SQL执行后得时间戳信息(大部分报表都通过ALV显示结果,因此在ALV显示之前增强记录即可. 增强在

SET_TABLE_FOR_FIRST_DISPLAY 中

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
DATA(lv_active_2) = zcl_enh_control=>check_enh_actvt( 'ZENH_10068' ).
IF LV_ACTIVE_2 = 'X'.

DATA(LV_REPID) = SY-CPROG.

zcl_report=> save_rep_log_pub( iv_point = '01' iv_lines = lines( IT_OUTTAB )

IV_REPID = LV_REPID ).

ENDIF.

程序 RSDBRUNT FORM %_RETURN_TO_SELSCREEN. 报表程序退出时,会返回选择屏幕,

通过这个节点返回,可以作为一次报表执行的结束节点

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

if MEMKEY-REPORT <> ''.

DATA(lv_active_3) = zcl_enh_control=>check_enh_actvt( 'ZENH_10068' ).
IF LV_ACTIVE_3 = 'X'.

zcl_report=>save_rep_log_pub( iv_point = '99' ).

ENDIF.

endif.

上述增强实现后, 自定义程序也无需附加代码记录日志了.

重点强调

RSDBRUNT是底层框架程序, 当框架程序中调用的类修改出现问题,(比如可选参数调整为必输参数)修改RSDBRUNT 中的部分代码,导致异常. 此时

SE38,SE24 等代码编辑器都无法执行了. 无法修复导致异常的程序.

**但是ECLIPSE 代码编辑器不受影响, 可以修复引起错误的代码.**

以后要多尝试用eclipse 编辑代码咯.

SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图
SAP 小技巧记录报表程序的执行日志 - 封面图

日志记录的代码部分

METHOD save_rep_log_pub. "保存日志 DATA: lv_runtime TYPE i, lv_timestamp TYPE c LENGTH 14. DATA: lv_repid TYPE sy-repid. IF iv_frame = 'X'. gv_frame = 'X'. ENDIF. IF iv_frame = '' AND gv_frame = 'X'. "如果框架中调用了. 则程序的的调用直接退出 RETURN. ENDIF. IF iv_repid IS NOT INITIAL. lv_repid = iv_repid. "程序名/CHAR/40.0/ ELSE. lv_repid = sy-cprog. "程序名/CHAR/40.0/ ENDIF. GET TIME. lv_timestamp = sy-datum && sy-uzeit. GET RUN TIME FIELD lv_runtime. IF gs_c1_sta IS INITIAL. SELECT SINGLE * FROM ztreport_c1 INTO gs_c1_sta WHERE repid = lv_repid. IF sy-subrc <> 0. gs_c1_sta = VALUE #( repid = lv_repid exelog = 'X' varlog = 'X' ). ENDIF. ENDIF. CHECK gs_c1_sta-exelog = 'X'. CASE iv_point. WHEN '00'. "开始 CLEAR gs_log_sta. CALL FUNCTION 'NUMBER_GET_NEXT' EXPORTING nr_range_nr = '02' object = 'ZLOGID' IMPORTING number = gs_log_sta-logid. "报表执行日志ID/CHAR/16.0/主键 gs_log_sta-repid = lv_repid. "程序名/CHAR/40.0/ gs_log_sta-tcode = sy-tcode.* SELECT SINGLE tcode FROM tstc INTO gs_log_sta-tcode WHERE tcode = sy-tcode. "如果当前TCODE 就是程序的TCODE. 记录一下.* IF sy-subrc <> 0.* SELECT SINGLE tcode FROM tstc INTO gs_log_sta-tcode WHERE pgmna = lv_repid.* ENDIF. gs_log_sta-tmbeg = lv_timestamp. "开始的时间戳/CHAR/14.0/ gs_log_sta-runtime00 = lv_runtime. CALL METHOD zcl_comm_bsd=>get_zsbc001( EXPORTING iv_updkz = 'I' CHANGING cs_data = gs_log_sta ). gs_log_sta-spyea = sy-datum(4). gs_log_sta-spmon = sy-datum(6). MODIFY ztreport_log FROM gs_log_sta. "保存变式 IF gs_c1_sta-varlog = 'X'. DATA: lt_sel TYPE TABLE OF rsparams. CALL FUNCTION 'RS_REFRESH_FROM_SELECTOPTIONS' EXPORTING curr_report = lv_repid* IMPORTING* SP = TABLES selection_table = lt_sel selection_table_255 = gt_sel255_sta* EXCEPTIONS* NOT_FOUND = 1* NO_REPORT = 2* OTHERS = 3 . DATA: ls_indx TYPE indx. ls_indx-aedat = sy-datum. ls_indx-enddt = sy-datum. ls_indx-usera = sy-uname. ls_indx-pgmid = lv_repid. EXPORT gt_sel255 = gt_sel255_sta TO DATABASE indx(zp) FROM ls_indx ID gs_log_sta-logid. ENDIF. WHEN '01'. "主体查询结束 IF gs_log_sta-logid <> ''. gs_log_sta-runtime01 = lv_runtime. gs_log_sta-sec00_01 = ( gs_log_sta-runtime01 - gs_log_sta-runtime00 ) / 1000 / 1000. gs_log_sta-lines = iv_lines. IF gs_log_sta-lines <> 0. gs_log_sta-line_cost = ( gs_log_sta-runtime01 - gs_log_sta-runtime00 ) / 1000 / gs_log_sta-lines. ENDIF. MODIFY ztreport_log FROM gs_log_sta. ENDIF. WHEN '99'. "主体查询结束 IF gs_log_sta-logid <> ''. gs_log_sta-runtime99 = lv_runtime.

...

ABAP技巧与实战

关于作者:ABAP技巧与实战

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「SAP小技巧记录报表程序的执行日志.md」整理生成,仅用于内部技术分享与学习交流。