I am looking into replacing a homegrown log processing library which looks awfully close to ReactiveStreams with io.projectreactor
. The objective is to reduce the code we maintain, and take advantage of any new features added by the community (eyeing operator fusion).
As a start, I need to consume the stdio and merge the multiline log-entries into text blobs that would flow down the pipeline. The use case is explained in detail on multiline log entries chapter of the Filebeat docs (except we want it inprocess).
So far the code I have is:
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
Flux<String> lines = Flux.generate(sink -> rethrow(() -> { while (true) sink.next(input.readLine()); }));
Flux<String> logRecordsStr = lines.concatMap(new LogRecordJoiner());
Flux<LogRecord> logRecords = logRecordsStr.map(new LogRecordMapper());
logRecords.doOnEach(r -> System.out.printf("%s payload: %d chars\n", r.timestamp, r.payload.length()))
.subscribe();
This takes care about the multi-line merging when a new log header is detected, but in the existing library we also flush the accumulated lines after a timeout (i.e. if no text is received within 5 seconds, flush the record).
What would be the right way to model this in Reactor? Do I need to write my own operator, or can I customize any of the existing?
Any pointers to relevant examples and docs for achieving this use-case in Project Reactor or RxJava would be very much appreciated.