요구사항
- Aws, Ncp 프로바이더에 대한 로그 수집을 우선적으로 지원해야 하고, 고객사 납품 일정에 따라 향후 Azure, Gcp, Nhn, Vsphere 등의 프로바이더로 확장이 가능해야한다.
- 고객사 내부망 구성 요구사항에 따라 수집한 로그를 Pulsar, 로그 처리 서버 등으로 전달할 수 있어야 한다.
- Org 개념이 존재하는 프로바이더에 대해서는 수집 로그 내 추가적인 후처리가 필요하다.
설계
요구사항에 따라 파이프라인 객체의 확장 포인트는 크게 3가지의 객체(Input, Filter, Output)로 개념화할 수 있다고 생각하여 이들에 각각 책임을 부여하고 협력에 있어 일종의 약속이 될 인터페이스들을 선언해주었습니다.
그리고 Input, Output의 경우엔 확장 포인트가 서로 배타적이기 때문에 완전히 갈아끼우는 형태의 전략 패턴을, Filter의 경우 다양한 경우의 수를 혼합해서 사용할 수 있겠다는 생각에 데코레이터 패턴을 활용하고자 했습니다.
아래는 UML 설계도입니다.

- Pipeline
- Input, Filter, Output 인스턴스들을 멤버 변수로 갖는 객체
- 파이프라인 내 객체들의 협력 방식만 기술
- 합성을 통한 자유로운 확장 가능
- Input
- 로그 수집을 시작하고, 종료하는 역할을 수행하는 객체
- 역할에 따른 추상화된 인터페이스만을 외부에 제공하고, 각 프로바이더 별로 상이한 수집 로직은 이를 구현하는 구체 클래스에서 구현 (전략 패턴)
- 이를 통해 파이프라인 객체 내 다른 코드를 건들지 않고 손쉽게 확장 가능
- Filter
- 파이프라인 내에서 Input - Output 사이의 가교 역할을 하며, 파이프라인 생성 단계에서 지정된 컨텍스트에 따라 알맞은 전처리 로직을 수행하는 객체
- 다양한 역할을 수행해야하기 때문에 처음에는 파이프라인 객체 내에서 배열로 관리하려고 했으나, 더 깔끔한 의존 관계를 위해 데코레이터 패턴을 활용
- 이를 통해 특정 프로바이더에 대한 추가적인 전처리(OrgFilter)는 물론, 향후 추가될 요구사항에 대해서도 기존 코드를 건들지 않는 방향으로 우아하게 수정 가능
- Output
- Filter 객체에 의해 전처리된 로그를 목적지로 전송하는 역할을 수행하는 객체
- 이 또한 전략 패턴을 통해 MQ 혹은 Http Server로의 확장이 가능하도록 설계
- PipelineFactory (설계도 상 미포함)
- 위에서 이야기한 확장성은 결국 DI를 통해서 보장이 되는데, 이를 위해 파이프라인 객체 생성 컨텍스트에 따라 알맞은 멤버 객체들을 생성해줄 책임을 수행하는 팩토리 객체 필요
- 어떤 프로바이더인지, 로그가 어떤 목적지를 갖는지에 따라 적절한 파이프라인 객체를 생성
결과
- 초기 상정한 3개의 확장 포인트(Input, Filter, Output)에 대해 확장이 필요한 경우, 기존 코드는 PipelineFactory 만을 수정하면 되게끔 설계가 이루어졌습니다.
- 초기 Aws, Ncp에 대한 로직만 작성해둔 상태에서, Azure, Gcp, Nhn 프로바이더로 확장하는데 무리가 없었을 뿐더러 초기 예상보다 기간을 훨씬 단축하는 결과를 거뒀습니다. (2주 → 1주)