[번역] 이벤트 주도 방식을 위한 측정
— Translate — 5 min read

이 게시물은 원본 아티클인 Instrumentation for Event Driven 를 한글로 번역한 게시글입니다. 게시물 내용의 저작권은 원작자 Sibelius Seraphini 에게 있습니다.
이 아티클에서 언급되었듯이 Woovi(회사)는 관찰 가능성에 많은 투자를 하고 있습니다. 이번 아티클에서는 우리의 이벤드 주도 아키텍처에서 어떻게 우리의 이벤트를 측정하는지에 대해 설명하겠습니다.
관찰 가능성 개념
깊게 알아보기 전에, 기본적인 관찰 가능성 개념 몇 가지를 정의하겠습니다.
트랜잭션(Transaction)은 하나의 완전한 요청, 하나의 작업, 하나의 작업 단위를 의미합니다.
모든 POST /charge
는 동일한 트랜잭션 타입과 이름을 가지고 있습니다.
트랜잭션은 시작과 끝을 가지고 있습니다.
스팬(Span)은 트랜잭션 내부 작업 단위를 의미합니다. 스팬은 시작과 끝을 가지고 있습니다. 스팬의 예는 다음과 같습니다: 데이터베이스 쿼리, http 요청, 레디스 요청 등
라벨(Label)은 트랜잭션이나 스팬에 첨부된 메타데이터 입니다.
이벤트 주도 측정
우리는 우리의 어플리케이션 성능 모니터링으로 Elastic APM을 사용합니다.
elastic-apm-node
는 koa, mongodb, redis 같은 많은 패키지들을 자동으로 추적하여 모니터링하지만,
우리는 Woovi의 요구에 맞춰 수동으로 설정을 해주어야 합니다.
우리는 분산 큐와 이벤트 주도 라이브러리에 bull-js을 사용합니다.
이벤트 처리를 위한 함수를 등록할 때 bull-js를 이렇게 사용합니다.
const queue = new Queue('WEBHOOK', config.REDIS_HOST);
queue.process('CHARGE_PAID', chargePaidJob);
작업이 실행 될 때 하나의 트랜잭션이 생성하고자 합니다. APM 서버와 Kibana는 동일한 트랜잭션 타입과 이름을 그룹으로 만듭니다.
이를 가능하게 하기 위해, 우리는 트랜잭션을 시작하는 고차 함수를 생성하고, 일부 작업 데이터를 라벨/메타데이터로 설정하며, 작업이 완료된 후 트랜잭션을 성공 또는 실패로 표시하고 종료합니다. 아래는 측정 함수 입니다.
export const jobMiddleware = (fn: (job: Job) => Promise<any>) => { const type = 'job';
const middleware = async (...args: any[]) => { const [job] = args;
const name = job.name; const trans = apm.startTransaction(name, type);
if (job.data) { apm.setLabel('jobData', JSON.stringify(job.data)); }
let result;
try { result = await fn(...args);
if (trans) { trans.setOutcome('success'); } } catch (err) { apm.captureError(err); if (trans) { trans.setOutcome('failure'); } }
if (trans) { trans.end(); }
return result; };
return middleware;};
kibana에서는 이렇게 결과가 보여집니다.

각각의 이벤트와 작업은 독립된 트랜잭션을 가지고 있으며, 이는 어떤일이 일어나는지 깊게 이해할 수 있도록 해줍니다.
이는 마치 코드가 실제로 실행되는 것을 보는 것 처럼 보이지만, 추가적인 console.log
없이도 가능합니다.
결론
적절한 측정은 운영 환경에서의 관찰 가능성을 가능케 합니다.
이는 운영환경에서 console.log
없이도 코드에 어떤 일이 발생했는지 이해할 수 있게 해줍니다.
여러분은 느린 쿼리와 코드, 잘못된 접근, 많은 데이터 베이스 호출 등을 식별할 수 있습니다.
이 아티클이 여러분이 운영 환경에서 버그를 고칠 때 필요한 올바른 관측 가능성을 보장하는 측정을 만들 수 있도록 도움이 되었으면 좋겠습니다.