반응형
0. 이해를 위한 사전 지식
- Import Queue란 ? 2024.09.02 - [SAP/BC] - # [SAP] Import Queue ( Import Queue 정리 )
1. 스크립트 컨셉
- tp cleanbuffer 명령어를 수행할 경우, Import Buffer의 이력이 아예 삭제되기 때문에 이력을 유지하며 Import Queue 정리가 필요함
- tp showbuffer 명령어를 수행하여 이관 된, Request number ( 성공, 실패, 경고 포함 )을 확인
- /usr/sap/trans/buffer/<SID> 파일을 읽은 뒤, 각 라인 ( Request )을 확인하여 특정 날짜보다 오래 전에 이관된 Request를 주석 처리
2. 스크립트 작성
- tp showbuffer 수행 결과 파일과 스크립트 파일을 넣을 경로 생성
- <Path> 는 해당 쉘을 저장하고자 하는 각자의 경로를 설정하면 됨
sidap01:/<Path>/ > mkdir import_queue_clear
sidap01:/<Path>/ > cd import_queue_clear
sidap01:/<Path>/import_queue_clear > mkdir data script
sidap01:/<Path>/import_queue_clear > ll
- import_queue_clear.sh 작성
- tp show buffer 수행 결과를 /<Path>/import_queue_clear/data 경로에 생성
- 또한, 데이터 파일에 대한 권한, 소유권을 변경 한 뒤, Import Queue Clear를 수행하는 파이썬 파일 실행
sidap01:/<Path>/import_queue_clear > cd script
sidap01:/<Path>/import_queue_clear/script > vi import_queue_clear.sh
#!/bin/bash
# current date for backup file name
# 오늘 날짜를 저장하는 변수
current_date=$(date +%y%m%d)
# hostname check
# 해당 쉘이 실행되는 서버의 호스트네임을 저장하는 변수
hostname=$(hostname)
# sid (Lower case) check
# 제 케이스의 경우 <sid>ap01가 호스트네임이기 때문에 이를 이용해 sid를 구해서 변수에 저장
sid=${hostname:0:3}
# SID (Upper case ) check
# sid를 대문자로 변환하여 변수에 저장
sid_upper=$(echo $sid | tr '[:lower:]' '[:upper:]')
# original Queue file ( /usr/sap/trans/buffer/SID ) backup
# import queue data를 가지고 있는 /usr/sap/trans/buffer/<SID> 파일을 <sid>_<오늘 날짜> 이름으로 백업
cp -rp /usr/sap/trans/buffer/$sid_upper /<Path>/import_queue_clear/data/${sid_upper}_${current_date}
# execute tp showbuffer command and save the result to file /monitoring/import_queue_clear/data/~
# tp showbuffer 명령어를 수행할 경우 import queue 상의 모든 request의 정보를 확인할 수 있고, 이를 파일로 생성
sudo -i -u "${sid}adm" tp showbuffer $sid_upper pf=/usr/sap/trans/bin/TP_DOMAIN_${sid_upper}.PFL > /<Path>/import_queue_clear/data/tp_showbuffer_${sid_upper}.txt
# change file authorization
# 보안을 위해 파일 권한, 소유자, 소유 그룹 변경
chmod 744 /<Path>/import_queue_clear/data/tp_showbuffer_${sid_upper}.txt
sudo chown ${sid}adm:sapsys /<Path>/import_queue_clear/data/tp_showbuffer_${sid_upper}.txt
# execute import queue clear python
# 실질적으로 /usr/sap/trans/buffer/<SID> 파일을 조작하는 파이썬 프로그램 실행
python3 /<Path>/import_queue_clear/script/import_queue_clear.py
- import_queue_clear.py 작성
- /<Path>/import_queue_data/tp_showbuffer_SID.txt 파일과 /usr/sap/trans/buffer/SID 파일을 읽은 뒤, 현재 시점보다 6개월 전에 반영된 request는 주석처리 하는 파이썬 코드
#!/usr/bin/python3
import os
import socket
from datetime import datetime
import calendar
imported_list = []
def getDate():
# 오늘 날짜를 가져오기
today = datetime.today()
year = today.year
month = today.month
# 오늘 날짜 기준으로 6개월 전 날짜 구하기
if month <= 6:
year -= 1
month += 6
else: # month > 6
month -= 6
# 캘린더 상으로 유효한 날짜인지 확인
last_day_of_month = calendar.monthrange(year, month)[1]
day = min(today.day, last_day_of_month)
# yyyymmdd 형식으로 포맷
target_date = datetime(year,month,day).strftime('%Y%m%d')
return target_date
def get_reqeust_info(input_string):
indices = []
line = input_string.replace("\n","")
# tp showbuffer 데이터는 "|" 로 정보들이 분리되기 때문에,
# "|" 위치에 대한 index를 indices list에 저장
for index, char in enumerate(input_string):
if char == '|':
indices.append(index)
# 라인의 0번째 인덱스부터 첫번째로 "|"가 나오는 부분까지가 request number
request_number = line[:indices[0]].replace(" ","")
# 라인의 51 ~ 55번째 자리까지가 RC (Request import status) 값을 나타냄
return_code = line[51:56].replace(" ","")
return [request_number, return_code]
def read_showbuffer_file():
# 프로그램을 실행하는 hosname, sid (대소문자) 확인
hostname = socket.gethostname()
lower_sid = hostname[0:3]
upper_sid = lower_sid.upper()
# 이전에 tp showbuffer 명령어로 생성한 파일 오픈
f = open("/<Path>/import_queue_clear/data/tp_showbuffer_{upper_sid}.txt", "r")
# 파일의 모든 데이터를 읽음
lines = f.readlines()
# 데이터를 라인별로 확인
for line in lines:
# request의 경우 <SID>K<NUMBER> 이기 때문에 읽은 정보의 첫 4글자가 <SID>K 인지 확인
if line[0:4] != "KEDK":
continue
# get_request_info() 함수 수행
request_info = get_reqeust_info(line)
# RC값이 "*4000"인 경우 아직 반영되지 않은 상태이기 떄문에
# 이 외의 값을 가지면서, None 값이 아닌것을 imported_list에 추가
# 결론적으로 imported_list에는 이관이 된 request number가 저장됨
# 이관된 상태는 정상,경고,에러를 모두 포함함 (이관이 안된 것만 제외)
if request_info is not None and request_info[1] != "*4000":
imported_list.append(request_info[0])
def change_SID_file():
# 프로그램을 실행하는 hosname, sid (대소문자) 확인
hostname = socket.gethostname()
lower_sid = hostname[0:3]
upper_sid = lower_sid.upper()
# import queue 상의 request 정보가 있는 /usr/sap/trans/buffer/<SID> 파일 경로 설정
file_path = "/usr/sap/trans/buffer/{upper_sid}"
# getDate() 수행하여 오늘날짜 기준 6개월 전 날짜 가져옴
target_date = datetime.strptime(getDate(),"%Y%m%d")
# /usr/sap/trans/buffer/<SID> 파일 읽기
with open(file_path, 'r') as f:
lines = f.readlines()
# request에 대한 정보는 3번째 줄부터 시작하기 때문에 2번째 부터 반복하여 line 읽기
for i in range(2,len(lines)):
# 각 line 별로 하나의 request 정보를 가지고 있음
line = lines[i]
# request 정보를 공백 기준으로 분리
request_info = line.split()
# 분리된 데이터의 첫번째의 1번째 글자가 이미 주석처리 (#) 되어 있는 경우 다음 request 확인
if request_info[0][0] == '#':
continue
# 분리된 데이터의 첫번째의 4번째 글자부터 마지막까지의 글자가 request number
# ex) request_info[0][3:] = <SID>K<NUMBER>
# 해당 request가 imported_list (이미 이관된 리퀘스트)에 있는 경우
if request_info[0][3:] in imported_list:
# requst_info의 마지막 데이터의 5번째 ~ 11번째까지는 이관된 날짜 데이터
# ex) request_info[-1][4:12] = 20240101
# 이관된 날짜를 yyyymmdd 형식으로 포맷
reference_date = datetime.strptime(request_info[-1][4:12], "%Y%m%d")
# 이관 날짜가 6개월보다 오래된 경우
if reference_date < target_date :
# 해당 라인의 첫번째 글자를 변경하여 주석 처리 (#)
lines[i] = "#" + line[1:]
# 모든 라인을 확인 한 뒤, 변경 내역을 write
with open(file_path, 'w') as f:
f.writelines(lines)
def main():
read_showbuffer_file()
change_SID_file()
# 프로그램 시작
main()
3. 스크립트 실행
sidap01:/ > cd /<Path>/import_queue_clear/script
sidap01:/<Path>/import_queue_clear/script > ./import_queue_clear.sh
🙋♂️ 궁금한 점이나 잘못된 내용을 댓글로 적어주시면 감사하겠습니다 !!
반응형
'SAP BC > SAP' 카테고리의 다른 글
# [SAP] Import Queue ( Import Queue 정리 ) (2) | 2024.09.03 |
---|---|
# [SAP] Transport Request - STMS (0) | 2024.08.08 |
# [SAP] Import options (0) | 2024.08.06 |
# [SAP] Lock Entries - SM12 (0) | 2024.07.25 |
# [SAP] CTS Import history (0) | 2024.06.28 |