데이터베이스 기술/POSTGRESQL

PostgreSQL - LogCollector

(주)비트나인 2023. 8. 29. 13:09

1. 개요

PG log 기록은 DB에 직접 저장하도록 설정할 수도 있다, 하지만 그렇게 되면 DB에 직접 트랜잭션이 발생하므로 DB성능을 저하시킬 우려가 있다. 그래서 log를 파일로 저장하고 해당파일을 읽어서 다른 DB에 저장 시키서 원천 DB는 사용하지 않도록 할 필요가 있다.

 

2. 목표1 - 파일 생성 event를 감지 

PG의 로그는 아래와 같이 날짜별로 데이터가 쌓이는데

날짜가 바뀌어서 새로운 파일 생성된다면 그 event를 감지할 수 있어야 한다.

 

3. 목표2 - 파일 내용 변경 event를 감지

log 파일내용이다, 아래와 같이 어떠한 log 발생하면 해당 시간과 함께 row별로 쌓이는데 새로운 한 줄이 추가 됐을때 변경 이벤트를 감지할 수 있어야 한다.

4. 구현기술 

해당 관련 기술에는 Apache Commons IO와 WatchService가 있다. 

WatchService는 운영체제의 파일 변경 이벤트를 수신하기 때문에 반복적으로 이벤트를 수집하지 않고 해당 이벤트가 발생됐을때 바로 수식할 수 있다.

Apache Commons IO는 Java File 클래스의 listFiles()를 주기적으로 호출하여 변화를 감지하므로 event의 발생빈도가 적다면 CPU를 낭비할 수 있습니다.

이번에는 WatchService를 사용하기로 합니다.

 

5. 구현

WatchService watchService = FileSystems.getDefault().newWatchService();

WatchService를 생성한다.

private final String targetDirectory

 "C:\\work\\AgensGraph-2.12.0\\data\\agdata\\log\\";

WatchService가 감시할 디렉터리 경로를 설정한다.

Path path = Paths.get(targetDirectory);

path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE

, StandardWatchEventKinds.ENTRY_DELETE

, StandardWatchEventKinds.ENTRY_MODIFY

, StandardWatchEventKinds.OVERFLOW);

해당 경로에서 감시할 event들을 등록한다.

위의 경우에는 CREATE, DELETE, MODIFY, OVERFLOW 4가지를 등록했다. 

 

6. 테스트 - file 생성 event

CREATE를 테스트 하기 위해 해당 경로에 postgresql-2023-07-25.log라는  임의 파일을 생성한다. 생성하는 순간

List<WatchEvent<?>> events = watchKey.pollEvents();

watchKey에서 해당 watchKey의 모든 event를 List로 수집해서 반환한다.

WatchEvent.Kind<?> kind = event.kind();

events에서 kind 메소드를 이용하여 event의 종류를 구분하고

Path paths = (Path) event.context();

event에서 해당 event가 발생한 Path(경로)를 구할 수 있다.

if(kind.equals(StandardWatchEventKinds.ENTRY_CREATE)){

위에서 구한 kind를 이용하여 event를 종류별로 감지할 수 있다. 위의 경우에는 CREATE event이다.

파일 새로 생성됐다는 event가 감지 됐고 해당 파일명을 구할 수 있다.

 

7. 테스트 - file 수정 event

log가 발생할때마다 log파일이 변경될 것이고 이 event를 감지해내야 하는게 목표였다. postgresql-2023-07-25.log 파일을 

2023-07-26 15:37:34.146 KST [15800] LOG:  이 로그는 영국에서 시작되어...1

2023-07-26 15:37:34.146 KST [15800] LOG:  이 로그는 영국에서 시작되어...2

위의 내용으로 2번 변경해보았다.

변경된 2번의 event를 감지할 수 있었고 해당 line의 내용도 얻을 수 있었다.

 

source : github




 

 

글 : 강민욱 수석보 ( 비트나인 HyperDB R&D Lead팀 )