Integration Suite 운영의 숨겨진 위험
SAP BTP Integration Suite(Cloud Integration 캐퍼빌리티)로 iFlow를 배포하고 나면 "연결됐으니 끝"이라고 생각하기 쉽습니다. 하지만 실제 운영 환경에서는 수신 시스템의 일시적 다운, 인증서 만료, 페이로드 스키마 변경 같은 이유로 메시지가 조용히 실패합니다. 문제는 실패 사실을 아무도 모른 채 수 시간, 수일이 흐른다는 것입니다. 주문 데이터 300건이 ERP에 도착하지 않았다는 사실을 현업 전화로 알게 되는 순간, 이미 사고입니다.
이 글에서는 Integration Suite 모니터링 화면과 OData API를 활용해 메시지 처리 실패를 빠르게 파악하는 5가지 체크포인트를 초급자 눈높이에서 정리합니다. 읽고 나면 다음을 할 수 있습니다.
- Monitor 화면에서 상태 필터로 실패 메시지를 즉시 좁혀 보기
- RETRY / FAILED / ESCALATED 상태의 차이를 이해하고 대응 우선순위 정하기
- OData API로 실패 로그와 오류 상세를 프로그램적으로 조회하기
- Alert 알림 자동화와 KPI 대시보드의 기본 틀 잡기
사전에 알아두면 좋은 것은 많지 않습니다. BTP 서브어카운트와 Integration Suite 인스턴스(테넌트)에 접근할 수 있고, iFlow를 한 번이라도 배포해 본 경험이면 충분합니다. OData 문법은 예제를 따라 하며 익혀도 됩니다.
환경 준비 — 어떤 테넌트에서 무엇이 필요한가
이 글의 예제는 다음 환경을 기준으로 합니다.
- SAP Integration Suite (BTP Cloud Foundry 환경, Standard/Premium 에디션 공통 — 모니터링 기능은 에디션과 무관하게 제공됩니다)
- Cloud Integration 캐퍼빌리티 활성화 상태
- API 호출용 Process Integration Runtime 서비스 인스턴스 (plan:
api) — OData API 인증에 사용할 OAuth Client Credentials를 여기서 발급받습니다 - 역할: 화면 모니터링은
MonitoringDataRead, API 조회도 동일 계열 역할이 부여된 서비스 키가 필요합니다
서비스 키를 생성하면 clientid, clientsecret, tokenurl, url(API 엔드포인트)이 발급됩니다. 이후 예제의 {tenant}는 이 url 값(예: https://mycompany.it-cpi018.cfapps.eu10-002.hana.ondemand.com)으로 치환하면 됩니다. Neo 환경은 경로 구조가 다르므로 이 글에서는 다루지 않습니다.
모니터링 아키텍처 이해 — MPL이라는 블랙박스 기록장치
Integration Suite의 모니터링 중심에는 Message Processing Log(MPL)가 있습니다. 비행기의 블랙박스에 비유하면 이해가 쉽습니다. iFlow를 통과하는 모든 메시지는 자동으로 MPL 한 건을 남기고, 여기에 시작/종료 시각, 최종 상태, 통과한 스텝, 오류 정보가 기록됩니다. 사고(실패)가 나면 이 블랙박스를 열어 어느 스텝에서 무엇 때문에 추락했는지 역추적하는 것이 운영의 기본입니다.
구조를 계층으로 보면 다음과 같습니다.
- MPL 헤더 — MessageGuid, 상태(Status), iFlow 이름, 처리 시각
- Error Information — 실패 시 예외 메시지와 마지막 오류 스텝
- Attachments / Custom Header — 개발자가 Groovy로 남긴 커스텀 로그와 검색용 비즈니스 키(예: 주문번호)
중요한 원칙 하나. MPL은 기본적으로 페이로드(본문)를 저장하지 않습니다. 로그 레벨이 Info일 때 저장되는 것은 메타데이터이며, 페이로드 추적이 필요하면 Trace 레벨(약 10분간만 유지)이나 커스텀 로깅을 써야 합니다. 이 특성을 모르면 "실패했는데 데이터가 안 보인다"며 당황하게 됩니다. 또한 MPL 보관 기간은 일반적으로 30일이므로, 장기 감사 목적이라면 외부로 로그를 내보내는 설계가 권장됩니다.
체크포인트 1 — Message Processing Log 상태 필터부터 연다
아침 운영 점검의 시작은 Monitor 화면입니다. 단계는 이렇습니다.
- Integration Suite 홈에서 Monitor > Integrations and APIs 진입
- Monitor Message Processing 타일에서 시간 범위를 Past Hour 또는 Past 24 Hours로 설정
- Status 필터를 Failed로 좁히고, 반복 점검할 조합(특정 iFlow + Failed)은 타일로 저장
여기서 초급자가 자주 놓치는 포인트는 Completed만 보고 안심하는 것입니다. 상태가 Completed여도 iFlow 내부에서 예외를 삼키는(catch 후 무시) 설계라면 비즈니스적으로는 실패일 수 있습니다. 그래서 상태 필터는 시작점일 뿐이고, 뒤에 나올 커스텀 헤더·KPI와 함께 봐야 완성됩니다.
체크포인트 2 — RETRY vs FAILED vs ESCALATED, 대응이 다르다
상태값의 의미를 정확히 알아야 우선순위를 정할 수 있습니다.
| 상태 | 의미 | 대응 |
|---|---|---|
| RETRY | 일시 오류로 재시도 대기 중 (주로 JMS/XI 어댑터 큐 기반) | 일단 관망. 재시도 횟수가 계속 늘면 수신 시스템 점검 |
| FAILED | 처리 확정 실패. 자동 복구 없음 | 즉시 분석 대상. 재처리 또는 소스 재전송 필요 |
| ESCALATED | Exception Subprocess의 Escalation End로 종료. 오류를 인지하고 의도적으로 종료 처리한 상태 | 설계된 예외 흐름이 실행된 것. 후속 프로세스(알림·보상 트랜잭션) 동작 여부 확인 |
비유하자면 RETRY는 "다시 전화 걸어보는 중", FAILED는 "통화 포기", ESCALATED는 "통화 실패를 상사에게 보고 완료"입니다. FAILED가 쌓이는데 아무도 재처리하지 않는 상황이 가장 위험하며, RETRY가 수 시간 지속되는 것도 큐 적체로 이어지므로 방치하면 안 됩니다.
체크포인트 3 — OData API로 실패 상세를 프로그램적으로 조회
화면 클릭만으로는 자동화가 안 됩니다. Integration Suite는 /api/v1 경로에 OData API를 제공하므로, 실패 로그를 스크립트로 긁어와 Slack/Teams 알림이나 리포트에 연결할 수 있습니다. 실무 시나리오로 주문처리 iFlow(OrderDispatch_ECC_to_S4)의 최근 실패를 조회해 보겠습니다.
1단계 — 기본 조회. 특정 iFlow의 FAILED 로그를 최신순으로 가져옵니다.
GET {tenant}/api/v1/MessageProcessingLogs?
$filter=Status eq 'FAILED'
and IntegrationFlowName eq 'OrderDispatch_ECC_to_S4'
and LogEnd gt datetime'2026-07-25T00:00:00'
&$orderby=LogEnd desc
&$top=50
&$format=json
2단계 — 오류 상세까지 확인하는 실무 스크립트. MessageGuid로 Error Information API를 이어 호출하고, 실패·인증 오류를 로깅합니다.
// Node.js 예제: 실패 주문 메시지 수집 + 오류 원문 조회
const BASE = process.env.CPI_URL; // 서비스 키의 url
const TOKEN = await fetchOAuthToken(); // client_credentials 방식
async function collectFailedOrders() {
const filter = encodeURIComponent(
"Status eq 'FAILED' and IntegrationFlowName eq 'OrderDispatch_ECC_to_S4'"
);
const res = await fetch(
`${BASE}/api/v1/MessageProcessingLogs?$filter=${filter}&$top=50&$format=json`,
{ headers: { Authorization: `Bearer ${TOKEN}` } }
);
if (res.status === 401) throw new Error('토큰 만료 또는 역할 부족(MonitoringDataRead 확인)');
const { d } = await res.json();
for (const log of d.results) {
// 오류 상세: ErrorInformation의 $value가 예외 원문을 반환
const err = await fetch(
`${BASE}/api/v1/MessageProcessingLogs('${log.MessageGuid}')/ErrorInformation/$value`,
{ headers: { Authorization: `Bearer ${TOKEN}` } }
);
console.error(`[실패] Guid=${log.MessageGuid} 종료=${log.LogEnd}`);
console.error(` 원인: ${(await err.text()).slice(0, 300)}`);
}
}
3단계 — 프로덕션 관점 보강. (1) $top+$skip 페이징으로 대량 조회 시 부하를 제어하고, (2) 토큰은 매 호출이 아니라 만료 시각까지 캐싱하며, (3) clientsecret은 코드가 아닌 BTP Destination이나 환경 변수 금고에 보관합니다. 주문번호로 역추적하려면 iFlow에서 Custom Header를 심는 것이 결정적입니다.
// Groovy Script 스텝: MPL에 주문번호를 검색 키로 기록
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def orderId = message.getHeaders().get("SalesOrderNumber") ?: "UNKNOWN"
def mpl = messageLogFactory.getMessageLog(message)
if (mpl != null) {
mpl.addCustomHeaderProperty("OrderID", orderId) // 화면·API 검색 가능
mpl.setStringProperty("Step_Validation", "PASSED") // 스텝 진행 표식
}
return message
}
이후 MessageProcessingLogCustomHeaderProperties?$filter=Name eq 'OrderID' and Value eq '4500012345'처럼 비즈니스 키로 MPL을 역조회할 수 있어, "주문 4500012345가 어디서 멈췄나"라는 현업 질문에 1분 안에 답하게 됩니다.
체크포인트 4 — Alert 자동화, 사람이 화면을 보기 전에 알린다
모니터링 화면을 하루 종일 쳐다볼 수는 없습니다. 일반적으로 두 가지 방식이 쓰입니다. 첫째, SAP Alert Notification service(ANS)와 연동해 iFlow 실패 이벤트를 이메일·Slack·웹훅으로 발송하는 방식. 둘째, 체크포인트 3의 OData 조회를 스케줄러(iFlow의 Timer 또는 외부 잡)로 돌려 자체 알림을 만드는 방식입니다. ANS 구독 조건 예시는 다음과 같습니다.
{
"name": "cpi-order-iflow-failure",
"conditions": [
{ "propertyKey": "eventType", "predicate": "CONTAINS", "propertyValue": "MessageProcessingFailure" },
{ "propertyKey": "tags.iflowName", "predicate": "CONTAINS", "propertyValue": "OrderDispatch" }
],
"actions": [ { "type": "EMAIL", "name": "notify-ops-team" } ],
"state": "ENABLED"
}
초급 단계라면 "FAILED 1건이라도 발생하면 알림"으로 시작하고, 노이즈가 커지면 iFlow별·건수 임계치별로 세분화하는 접근이 권장됩니다.
체크포인트 5 — 대시보드 KPI, 숫자 4개면 충분하다
운영 초기의 KPI는 단순할수록 좋습니다. 매일 같은 4개 숫자를 추적하세요.
- 실패율 = FAILED ÷ 전체 처리 건수 (목표: 1% 미만)
- RETRY 체류 건수 — 큐 적체의 조기 신호
- 평균 처리 시간 —
LogEnd - LogStart, 급증 시 수신 시스템 성능 저하 의심 - 최다 실패 iFlow TOP 3 — 구조적 문제를 가진 인터페이스 식별
집계도 OData 한 줄로 시작할 수 있습니다. $count를 쓰면 데이터 본문 없이 건수만 가볍게 얻습니다.
GET {tenant}/api/v1/MessageProcessingLogs/$count?
$filter=Status eq 'FAILED' and LogEnd gt datetime'2026-07-26T00:00:00'
흔한 실수와 트러블슈팅 FAQ
Q1. FAILED 메시지의 페이로드가 안 보입니다. — 정상 동작입니다. Info 레벨 MPL은 페이로드를 저장하지 않습니다. 재현 가능한 건이면 로그 레벨을 Trace로 올려 재전송하고(Trace는 짧게만 유지됨), 상시 필요하면 Groovy로 필요한 필드만 Attachment/Custom Header에 기록하세요. 단, 개인정보·전체 페이로드 상시 저장은 보안과 저장소 부담 때문에 지양하는 것이 일반적입니다.
Q2. OData API 호출이 401/403으로 실패합니다. — Process Integration Runtime 인스턴스의 plan이 api인지, 서비스 키 역할에 모니터링 읽기 권한이 포함됐는지 확인하세요. iFlow 실행용(plan: integration-flow) 키로는 모니터링 API에 접근할 수 없습니다.
Q3. 어제 실패 건이 화면에서 사라졌습니다. — 시간 필터가 Past Hour로 좁혀져 있거나, 보관 기간(일반적으로 30일)이 지난 경우입니다. 장기 보관이 필요하면 OData로 주기 추출해 외부 저장소에 적재하세요.
Q4. RETRY가 며칠째 반복됩니다. — JMS 큐 기반 재시도는 수신 시스템이 복구될 때까지 계속됩니다. 큐 리소스를 잠식하므로, 복구 불가 판정이 나면 큐에서 메시지를 확인 후 수동 정리하고 소스에서 재전송하는 편이 안전합니다.
실전 운영 체크리스트와 더 깊이 가는 길
마지막으로 매일 아침 5분 루틴을 체크리스트로 정리합니다.
- Monitor 화면 Failed 필터 확인 (Past 24 Hours)
- RETRY 체류 건수와 JMS 큐 상태 점검
- ESCALATED 건의 후속 프로세스 실행 여부 확인
- Alert 채널(메일/웹훅) 정상 수신 테스트 — 주 1회
- 실패율·처리 시간 KPI 기록 후 추세 비교
이 다음 주제로는 JMS 기반 재시도 설계, Exception Subprocess 패턴, Cloud ALM 연계 중앙 모니터링, Trace 레벨을 활용한 스텝 단위 디버깅을 이어서 살펴보면 좋습니다. 아래 문서들이 출발점으로 유용합니다.
댓글 0
아직 댓글이 없습니다.