요즘 로그를 남기기 위해서는 CBO 테이블을 만들어서 기록을 합니다.
저만 그러는것은 아니겠죠?, 하지만 1회성 오류 확인을 하기 위해서 CBO 테이블을 만드는 것은 좀 비효율적일 때가 있습니다.
그때 SAP에서 제공하는 BAL 로그 남기는 것을 고려할 수 있습니다.
최근에 15년 전부터 사용되는 오래된 프로그램이 있는데 프로그램-펑션-펑션-펑션-펑션.. 등으로
아주 복잡하게 되어 있어 어디서 오류가 발생하는지 도저히 못 찾는 경우가 있었습니다.
로그는 남겨서 확인 경우가 있어 BAL 로그 방식을 이야기 해볼까 합니다.
서론: 로그의 중요성
SAP ABAP 개발자라면 프로그램 실행 중 발생하는 다양한 상황을 추적하고, 오류를 진단하며, 비즈니스 프로세스의 흐름을 파악하는 데 로그가 얼마나 중요한지 잘 아실 겁니다. 특히 백그라운드 배치 작업이나 인터페이스 프로그램처럼 사용자 인터페이스가 없는 환경에서는 로그가 유일한 통신 수단이 되기도 합니다.
이번 포스팅에서는 SAP ABAP 환경에서 로그를 기록하는 두 가지 핵심 방법을 깊이 있게 다룹니다.
바로 SAP 표준 프레임워크인 BAL(Business Application Log) 과 개발자가 직접 설계하는 CBO(Custom Business Object) 테이블 로깅입니다.
1. SAP 표준 로깅의 정석: Business Application Log (BAL)
BAL은 SAP가 제공하는 표준 애플리케이션 로그 프레임워크입니다.
이를 활용하면 프로그램에서 발생하는 정보, 경고, 오류 메시지를 체계적으로 기록하고, 표준 트랜잭션(SLG1)을 통해 편리하게 조회할 수 있습니다. 이는 특히 시스템 운영 및 모니터링 관점에서 매우 강력한 도구입니다.
1.1. BAL 개요 및 주요 트랜잭션
- SLG0: BAL 오브젝트(Object) 및 서브오브젝트(Subobject)를 정의하는 트랜잭션입니다.
로그를 기록하기 전에 반드시 로깅 대상에 대한 분류 체계를 이곳에서 정의해야 합니다.
예를 들어, 'ZMM' (자재 관리) 오브젝트 아래에 'POINFO' (구매 오더 정보)와 같은 서브오브젝트를 만들 수 있습니다. - SLG1: 기록된 BAL 로그를 조회하는 핵심 트랜잭션입니다.
오브젝트, 서브오브젝트, 외부 번호(EXTNUMBER), 사용자, 날짜 등 다양한 조건으로 필터링하여 원하는 로그를 빠르게 찾을 수 있습니다. - SLG2: 오래된 BAL 로그를 삭제하여 시스템 성능을 최적화하고 데이터베이스 공간을 관리하는 트랜잭션입니다.
1.2. BAL 기록 단계별 예시: 범용 write_free_log 서브루틴
BAL을 사용하기 위한 첫 단계는 SLG0 트랜잭션에서 로그를 저장할 오브젝트(Object) 와 서브오브젝트(Subobject) 를 정의하는 것입니다. 이 설정이 되어 있지 않으면 로그가 제대로 기록되지 않습니다.
단계별 등록 방법:
- SLG0 트랜잭션 실행: SAP GUI에서 SLG0을 입력하고 실행합니다.
- 오브젝트 생성:
- '애플리케이션 로그: 오브젝트' 화면에서 '신규 엔트리(F5)' 버튼을 클릭합니다.
- 오브젝트(Object) 필드에 원하는 오브젝트 코드(예: ZMM – Z로 시작하는 커스텀 오브젝트)를 입력합니다.
- 오브젝트 텍스트(Object Text)에 오브젝트에 대한 설명(예: '자재 관리 애플리케이션 로그')을 입력합니다.
- 저장 버튼을 클릭하고 Transport Request(TR)에 포함시킵니다.
- 서브오브젝트 생성:
- 방금 생성한 오브젝트를 선택하고 왼쪽 탐색 영역에서 '서브오브젝트 정의'를 더블클릭합니다.
- '신규 엔트리(F5)' 버튼을 클릭합니다.
- 서브오브젝트(Subobject) 필드에 원하는 서브오브젝트 코드(예: POINFO – 구매 오더 정보)를 입력합니다.
- **서브오브젝트 텍스트(Subobject Text)**에 설명을 입력합니다(예: '구매 오더 정보 처리').
- 저장 버튼을 클릭하고 TR에 포함시킵니다.
이렇게 SLG0에 오브젝트(ZMM)와 서브오브젝트(POINFO)가 등록되면, ABAP 코드에서 이들을 사용하여 BAL 로그를 생성할 수 있습니다.
1.3. BAL 기록 단계별 예시: 범용 write_free_log 서브루틴
다음 write_free_log 서브루틴은 BAL을 사용하여 메시지를 기록하는 범용적인 코드 예시입니다.
메시지 유형, 메시지 텍스트, 그리고 로그를 식별할 수 있는 외부 번호(External Number)를 파라미터로 받아 효율적인 ABAP 로깅을 가능하게 합니다.
*&---------------------------------------------------------------------*
* 애플리케이션 로그에 메시지를 기록하는 공통 서브루틴
*----------------------------------------------------------------------*
FORM write_free_log USING pv_msgty TYPE balmi-msgty " 메시지 유형 (S, I, W, E, A)
pv_message TYPE bapiret2-message " 기록할 메시지 텍스트
pv_ext_number TYPE balnrext. " 외부 식별자 (예: 문서 번호, 프로세스 ID)
DATA: lv_handle TYPE balloghndl. " 생성된 로그의 고유 핸들
DATA: ls_s_log TYPE bal_s_log. " 로그 헤더 정보 구조체
DATA: lt_log_handles TYPE bal_t_logh. " 로그 핸들을 저장하는 내부 테이블
" 1. 로그 헤더 설정: 로그의 기본 속성을 정의합니다.
" object와 subobject는 SLG0에서 미리 정의해야 합니다.
ls_s_log-object = 'ZMM'. " 예: 자재 관리 관련 커스텀 오브젝트
ls_s_log-subobject = 'POINFO'. " 예: 구매 오더 정보 서브오브젝트
ls_s_log-extnumber = pv_ext_number. " SLG1에서 검색할 핵심 식별자
ls_s_log-aldate = sy-datum. " 현재 시스템 날짜
ls_s_log-altime = sy-uzeit. " 현재 시스템 시간
ls_s_log-aluser = sy-uname. " 현재 사용자명
ls_s_log-altcode = sy-tcode. " 현재 트랜잭션 코드
ls_s_log-alprog = sy-repid. " 현재 프로그램명
" 2. 로그 생성: 설정된 헤더 정보로 새로운 로그를 생성하고 핸들을 반환합니다.
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = ls_s_log
IMPORTING
e_log_handle = lv_handle
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
EXIT. " 로그 생성 실패 시 종료
ENDIF.
" 3. 로그 핸들 테이블에 추가: 여러 로그를 한 번에 저장하기 위해 핸들을 모읍니다.
APPEND lv_handle TO lt_log_handles.
" 4. 메시지 추가: 생성된 로그에 실제 메시지 텍스트와 유형을 기록합니다.
CALL FUNCTION 'BAL_LOG_MSG_ADD_FREE_TEXT'
EXPORTING
i_log_handle = lv_handle
i_msgty = pv_msgty
i_text = pv_message
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
" 메시지 추가 실패 시 오류 처리 (선택 사항)
ENDIF.
" 5. DB 저장: 메모리에 있는 로그를 데이터베이스에 영구적으로 저장합니다. 이 단계가 있어야 SLG1에서 조회 가능합니다.
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_t_log_handle = lt_log_handles
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
" DB 저장 실패 시 오류 처리 (선택 사항)
ENDIF.
ENDFORM.
SLG1 트랜잭션으로 이동하여 Object: ZMM, Subobject: POINFO를 입력하면 기록된 ABAP 애플리케이션 로그를 확인할 수 있습니다. EXTNUMBER 필드를 활용하면 특정 문서나 프로세스에 대한 로그를 쉽게 필터링할 수 있습니다.
REPORT Z_TEST_APP_LOG_BLOG.
* 위에서 정의된 FORM write_free_log ... 코드가 여기에 포함됩니다.
START-OF-SELECTION.
" 성공 메시지 기록: 구매 오더 'PO_123456' 생성 성공 로그
PERFORM write_free_log USING 'S' " Success 유형
'구매 오더 123456이 성공적으로 생성되었습니다.'
'PO_123456'. " 외부 번호로 PO 번호 지정
" 경고 메시지 기록: 재고 관련 경고 로그
PERFORM write_free_log USING 'W' " Warning 유형
'재고 부족: 품목 ABC에 대해 재고 확인이 필요합니다.'
'ITEM_ABC'. " 외부 번호로 품목 ID 지정
" 오류 메시지 기록: 데이터 유효성 검사 실패 오류 로그
PERFORM write_free_log USING 'E' " Error 유형
'데이터 유효성 검사 실패: 필수 필드가 누락되었습니다.'
'VALIDATION_ERROR'. " 외부 번호로 오류 유형 지정
" 정보 메시지 기록: 백그라운드 작업 완료 정보 로그
PERFORM write_free_log USING 'I' " Information 유형
'백그라운드 작업 완료: 일괄 처리 프로세스 성공.'
'BATCH_JOB_001'. " 외부 번호로 배치 작업 ID 지정
MESSAGE '로그 기록이 완료되었습니다! SLG1 트랜잭션에서 확인하세요.' TYPE 'I'.
여기까지입니다.
아래부턴 CBO 남기는 것과 비교하여 일을 추가하였습니다. 참고 정도로 보시면 좋을 것 같습니다.
<< 참고사항 >>
* 커스텀 로깅의 힘: CBO 테이블에 직접 로그 기록하기
CBO(Custom Business Object) 테이블에 직접 로그를 기록하는 방식은 SAP 시스템 내에 개발자가 직접 생성한 투명 테이블(Transparent Table)에 프로그램의 특정 이벤트나 데이터 변경 이력을 저장하는 방법입니다.
이 방식은 SAP 표준 프레임워크의 제약에서 벗어나 완벽한 커스터마이징이 가능하다는 것이 가장 큰 특징입니다.
1. 작동 방식 및 주요 특징
- 커스텀 테이블 설계 및 생성: SE11 트랜잭션에서 로그를 저장할 필드(예: 변경 일시, 변경 사용자, 이전 값, 새 값, 관련 문서 번호, 상세 메시지, 특정 플래그 등)를 포함하는 투명 테이블을 직접 설계하고 생성합니다.
- ABAP 코드 작성: 프로그램 내에서 특정 이벤트(예: 마스터 데이터 생성/변경/삭제, 트랜잭션 상태 변화)가 발생할 때마다 해당 CBO 테이블에 데이터를 INSERT하거나 MODIFY하는 ABAP 코드를 직접 작성합니다.
- 조회 프로그램 개발: SE16N으로 테이블 내용을 직접 조회하거나, ALV 리포트 등 별도의 ABAP 프로그램을 개발하여 로그를 상세하게 조회하고 분석할 수 있습니다.
CBO 테이블 로깅의 주요 특징:
- 극강의 커스터마이징: 필요한 모든 정보를 원하는 구조와 형태로 자유롭게 저장할 수 있습니다.
- 데이터 접근 용이성: 표준 테이블처럼 SELECT 문을 통해 직접 데이터에 접근하여 복잡한 통계 분석이나 사용자 맞춤형 리포팅이 매우 용이합니다.
- 비즈니스 데이터와의 긴밀한 연관성: 특정 비즈니스 데이터의 변경 이력이나 상태 변화를 매우 상세하게 추적하고 감사(Audit) 목적으로 활용하는 데 탁월합니다.
2. BAL vs. CBO 테이블 로그: 핵심 비교 분석
두 가지 SAP 로깅 방법은 "로그를 남긴다"는 공통점을 가지지만, 목적과 활용 방식에서 큰 차이를 보입니다.
프로젝트의 요구사항에 따라 적절한 방식을 선택하는 것이 중요합니다.
구분 | Business Application Log (BAL) | CBO 테이블 로그 |
주요 목적 | 프로그램 실행 결과, 오류, 정보 메시지 기록 및 모니터링, 오류 진단 | 특정 비즈니스 데이터의 상세 변경 이력, 작업 흐름의 감사 추적 |
표준/커스텀 | SAP 표준 프레임워크 (BAL 함수 모듈) 활용 | 개발자가 직접 설계하고 구현하는 커스텀 방식 |
데이터 구조 | SAP 표준 테이블(BALHDR, BALDAT, BAL_INDX 등) 사용. 메시지, 헤더 위주. | 개발자가 정의한 자유로운 커스텀 테이블 구조. 모든 비즈니스 데이터 필드 포함 가능. |
조회 방식 | SLG1 트랜잭션 (표준 조회 화면) | SE16N 또는 개발자가 만든 맞춤형 리포트/트랜잭션 |
유연성 | 정해진 BAL 프레임워크 내에서 유연성 제공. (EXTNUMBER 활용) | 데이터 구조, 저장 로직, 조회 방식 모두 완벽한 커스터마이징 가능. |
성능 | BAL 프레임워크에 최적화되어 있어 대량의 메시지 처리에 유리. | 개발자가 구현하는 방식에 따라 성능이 달라질 수 있음. 대량 로깅 시 성능 최적화 필요. |
데이터 보존 | SLG2 트랜잭션을 통해 표준 삭제 기능 제공. | 개발자가 직접 삭제 로직(예: 배치 프로그램)을 구현해야 함. |
개발 공수 | BAL 함수 모듈 사용법 숙지 시 비교적 낮음. (SLG0 설정 필요) | 테이블 설계, 로깅 로직, 조회 리포트까지 모두 개발해야 하므로 초기 공수 높음. |
주요 활용 예시 | 배치 작업 성공/실패 결과, 인터페이스 처리 오류, 예외 상황 알림 | 마스터 데이터 변경 이력, 트랜잭션 데이터 상태 변화(예: 주문 승인 이력), 사용자 행위 기록 |
3 내 프로젝트에 맞는 로깅 방식 선택 가이드
프로젝트의 성격과 로그 데이터의 활용 목적을 명확히 이해하는 것이 가장 중요합니다.
3.1. BAL(Business Application Log)을 사용해야 하는 경우:
- 프로그램 실행의 전반적인 흐름 및 결과 기록이 주 목적일 때
(예: 백그라운드 작업의 성공/실패 여부, 인터페이스 프로그램의 처리 건수 및 오류). - SAP 표준화된 오류 및 정보 메시지 관리가 필요하며, SLG1과 같은 표준 조회 화면으로 충분할 때.
- 운영 담당자나 시스템 관리자가 프로그램의 상태를 빠르게 파악하고 문제 발생 시 초기 진단을 할 필요가 있을 때.
- 복잡한 비즈니스 데이터와의 상세한 연관성보다는 메시지 텍스트와 몇 가지 식별자(EXTNUMBER)만으로 충분할 때.
- 다양한 프로그램에서 공통적으로 메시지를 기록해야 하는 범용 로깅 서브루틴을 구현할 때 매우 효과적입니다.
3.2. CBO 테이블에 직접 로그를 기록해야 하는 경우:
- 특정 비즈니스 데이터의 상세하고 엄격한 변경 이력 추적이 필수적일 때 (예: 구매 오더의 상태 변경 이력, 자재 마스터의 특정 필드 변경 기록, 사용자 권한 변경 이력).
- 감사(Audit) 목적으로 데이터 변경 이력을 법적 요구사항에 따라 상세하게 보존하고, 데이터의 무결성이 매우 중요할 때.
- 로그 데이터를 기반으로 복잡한 통계 분석이나 사용자 맞춤형 리포팅이 필요하여, SELECT 문으로 직접 접근 가능한 테이블 구조가 유리할 때.
- BAL의 표준 필드만으로는 부족하고, 더 많은 비즈니스 관련 필드(예: 플랜트, 회사 코드, 특정 금액, 변경 전 값, 변경 후 값 등)를 함께 저장하고 싶을 때.
- 특정 비즈니스 프로세스의 단계별 진행 상황이나 결과를 맞춤형으로 기록하고, 이를 다른 비즈니스 로직에 활용해야 할 때.
'ABAP' 카테고리의 다른 글
SAP S/4HANA 개발 필수! CDS View 개념부터 MM 모듈 예제 (0) | 2025.07.19 |
---|---|
[ABAP] 출력 제어(Output Control) - Inbound Delivery 및 Invoice 생성하기 (0) | 2025.07.10 |
[ABAP] Part 2 - 시점별 재고 ( 전통적인ABAP + ALV 리포트) (0) | 2025.07.05 |
[ABAP] Part 1 - 시점별 재고 (CDS View + ALV 리포트) (0) | 2025.07.05 |
[ABAP] 표준 자재 검색(F4)에 나만의 탭 추가하기 (Append Search Help) (0) | 2025.07.02 |