由于公司没有上PI,很久之前公司自己开发的中间平台也不太好用,于是想着自己弄个通用的接口日志记录工具,之前在GIT上看到有相关工具GitHub - ABAP-Logger/ABAP-Logger: ABAP Logging as painless as any other language,但是只能导入到S/4中使用,于是参照他的逻辑自己调整了个ECC版本的,主要是两个地方的调整,一个是S/4和ECC语法区别的调整,一个是ECC中没有/UI2/CL_JSON这个工具类,下载了别人封装好的工具类导入,参考文章ABAP 中JSON格式的转换与解析 - 氢氦 - 博客园 (cnblogs.com)
日志主要的逻辑都写在宏里面,代码和表结构如下
*&---------------------------------------------------------------------*
*& 包含文件 ZFM_LOG_MACROS
*&---------------------------------------------------------------------*
DEFINE /afl/log_init.
data: /afl/comp_tab type cl_abap_structdescr=>component_table,
/afl/comp_wa like line of /afl/comp_tab.
data: /afl/struct_type type ref to cl_abap_structdescr, "Structure
/afl/parameter_data type ref to data.
data: /afl/table_structure_type type ref to cl_abap_structdescr,
/afl/table_type type ref to cl_abap_tabledescr.
data: true_fieldname type string.
field-symbols: </afl/parameter_data> type any,
</afl/parameter_data_field> type any,
</afl/parameter> type any.
data: /afl/callstack_tab type abap_callstack.
data: /afl/callstack_wa type abap_callstack_line.
data: /afl/log type zfl_log.
data: /afl/config_wa type zfl_config.
data: /afl/parameters_tab type table of fupararef.
data: /afl/oref type ref to cx_uuid_error.
data: /afl/func_name type abap_callstack_line-blockname.
get time.
call function 'SYSTEM_CALLSTACK'
importing
callstack = /afl/callstack_tab.
read table /afl/callstack_tab into /afl/callstack_wa index 1.
if sy-subrc = 0.
/afl/func_name = /afl/callstack_wa-blockname.
endif.
select single * into /afl/config_wa from zfl_config
where fname = /afl/func_name
and enabled = 'X'.
if sy-subrc = 0.
select *
into table /afl/parameters_tab
from fupararef
where funcname = /afl/func_name.
if sy-subrc = 0.
sort /afl/parameters_tab by paramtype pposition.
field-symbols: </alf/parameters> like line of /afl/parameters_tab,
</alf/comp> like line of /afl/comp_tab.
if /afl/config_wa-import = abap_true.
/afl/log_get_json 'I' /afl/log-import.
endif.
*{ REPLACE PRDK900040 1
*\ if /afl/config_wa-table_out = abap_true.
if /afl/config_wa-table_in = abap_true.
*} REPLACE
/afl/log_get_json 'T' /afl/log-table_in.
endif.
if /afl/config_wa-change = abap_true.
/afl/log_get_json 'C' /afl/log-change_in.
endif.
data: /afl/start_time type tzntstmpl.
try.
/afl/log-guid = cl_system_uuid=>create_uuid_x16_static( ).
catch cx_uuid_error into /afl/oref.
endtry.
/afl/log-fname = /afl/func_name.
/afl/log-uname = sy-uname.
endif.
endif.
END-OF-DEFINITION.
DEFINE /afl/log_get_json.
clear /afl/comp_tab.
loop at /afl/parameters_tab assigning </alf/parameters> where paramtype = &1.
/afl/comp_wa-name = </alf/parameters>-parameter.
/afl/comp_wa-type ?= cl_abap_datadescr=>describe_by_name( </alf/parameters>-structure ).
append /afl/comp_wa to /afl/comp_tab.
endloop.
if /afl/comp_tab is not initial.
/afl/struct_type = cl_abap_structdescr=>create( /afl/comp_tab ).
create data /afl/parameter_data type handle /afl/struct_type.
assign /afl/parameter_data->* to </afl/parameter_data>.
loop at /afl/comp_tab assigning </alf/comp>.
assign (</alf/comp>-name) to </afl/parameter>.
assign component </alf/comp>-name of structure </afl/parameter_data> to </afl/parameter_data_field>.
</afl/parameter_data_field> = </afl/parameter>.
endloop.
&2 = zui2_json=>serialize( data = </afl/parameter_data> ).
endif.
END-OF-DEFINITION.
DEFINE /afl/set_custom_fields.
/afl/log-cust_field1 = &1.
/afl/log-cust_field2 = &2.
/afl/log-cust_field3 = &3.
END-OF-DEFINITION.
DEFINE /afl/save .
if /afl/log-guid is not initial.
data: /afl/end_time type tzntstmpl.
if /afl/config_wa-export = abap_true.
/afl/log_get_json 'E' /afl/log-export.
endif.
if /afl/config_wa-table_out = abap_true.
/afl/log_get_json 'T' /afl/log-table_out.
endif.
if /afl/config_wa-change = abap_true.
/afl/log_get_json 'C' /afl/log-change_out.
endif.
get time.
get time stamp field /afl/end_time.
/afl/log-udate = sy-datum.
/afl/log-utime = sy-uzeit.
modify zfl_log from /afl/log.
endif.
END-OF-DEFINITION.
![](https://i-blog.csdnimg.cn/blog_migrate/8304e8d75df0a1850f47bba833d2dee2.png)
函数组中插入包含程序,然后在function结束处插入宏调用即可
日志清理程序:
REPORT zfm_log_clean.
DATA:gt_log TYPE TABLE OF zfl_log.
DATA:lt_log TYPE TABLE OF zfl_log.
DATA:gt_config TYPE TABLE OF zfl_config.
DATA:ls_log TYPE zfl_log.
DATA:ls_config TYPE zfl_config.
DATA:lv_date TYPE sy-datum.
SELECT * INTO CORRESPONDING FIELDS OF TABLE gt_log FROM zfl_log.
SELECT * INTO CORRESPONDING FIELDS OF TABLE gt_config FROM zfl_config.
SORT gt_config BY fname.
LOOP AT gt_log INTO ls_log.
READ TABLE gt_config INTO ls_config WITH KEY fname = ls_log-fname BINARY SEARCH.
IF sy-subrc = 0.
lv_date = ls_log-udate + ls_config-save_days.
IF lv_date < sy-datum.
APPEND ls_log TO lt_log.
ENDIF.
ENDIF.
ENDLOOP.
DELETE zfl_log FROM TABLE lt_log.