diff --git a/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LengthSplittingAppender.java b/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LengthSplittingAppender.java index 18e313b..48c196e 100644 --- a/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LengthSplittingAppender.java +++ b/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LengthSplittingAppender.java @@ -34,6 +34,13 @@ * SOFTWARE. */ public class LengthSplittingAppender extends SplittingAppenderBase { + private final LoggingEventCloner loggingEventCloner; + + public LengthSplittingAppender() { + super(); + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + this.loggingEventCloner = new LoggingEventCloner(loggerContext); + } private int maxLength; private String sequenceKey; @@ -61,19 +68,17 @@ public boolean shouldSplit(ILoggingEvent event) { @Override public List split(ILoggingEvent event) { - LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); List logMessages = splitString(event.getFormattedMessage(), getMaxLength()); List splitLogEvents = new ArrayList<>(logMessages.size()); for (int i = 0; i < logMessages.size(); i++) { - - LoggingEvent partition = LoggingEventCloner.clone(event, loggerContext); + String message = logMessages.get(i); Map seqMDCPropertyMap = new HashMap<>(event.getMDCPropertyMap()); seqMDCPropertyMap.put(getSequenceKey(), Integer.toString(i)); - partition.setMDCPropertyMap(seqMDCPropertyMap); - partition.setMessage(logMessages.get(i)); - splitLogEvents.add(partition); + LoggingEvent clonedEvent = loggingEventCloner.clone(event, message, seqMDCPropertyMap); + + splitLogEvents.add(clonedEvent); } return splitLogEvents; @@ -85,7 +90,7 @@ private List splitString(String str, int chunkSize) { List results = new ArrayList<>(remainder == 0 ? fullChunks : fullChunks + 1); for (int i = 0; i < fullChunks; i++) { - results.add(str.substring(i*chunkSize, i*chunkSize + chunkSize)); + results.add(str.substring(i * chunkSize, i * chunkSize + chunkSize)); } if (remainder != 0) { results.add(str.substring(str.length() - remainder)); diff --git a/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LoggingEventCloner.java b/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LoggingEventCloner.java index 837fa58..670bb5e 100644 --- a/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LoggingEventCloner.java +++ b/platform-spring-bom/platform-spring-logging-server-config/src/main/java/com/latch/LoggingEventCloner.java @@ -6,6 +6,7 @@ import org.slf4j.Marker; import java.util.List; +import java.util.Map; /* * MIT License @@ -31,26 +32,33 @@ * SOFTWARE. */ class LoggingEventCloner { + private final LoggerContext loggerContext; - static LoggingEvent clone(ILoggingEvent event, LoggerContext loggerContext) { - LoggingEvent logEventPartition = new LoggingEvent(); + public LoggingEventCloner(LoggerContext loggerContext) { + this.loggerContext = loggerContext; + } + + public LoggingEvent clone(ILoggingEvent event, String message, Map mdcValueMap) { + LoggingEvent newEvent = new LoggingEvent(); - logEventPartition.setLevel(event.getLevel()); - logEventPartition.setLoggerName(event.getLoggerName()); - logEventPartition.setTimeStamp(event.getTimeStamp()); - logEventPartition.setLoggerContextRemoteView(event.getLoggerContextVO()); - logEventPartition.setLoggerContext(loggerContext); - logEventPartition.setThreadName(event.getThreadName()); + newEvent.setLevel(event.getLevel()); + newEvent.setLoggerName(event.getLoggerName()); + newEvent.setTimeStamp(event.getTimeStamp()); + newEvent.setLoggerContextRemoteView(event.getLoggerContextVO()); + newEvent.setLoggerContext(this.loggerContext); + newEvent.setThreadName(event.getThreadName()); + newEvent.setMessage(message); + newEvent.setMDCPropertyMap(mdcValueMap); List eventMarkers = event.getMarkerList(); if (eventMarkers != null && !eventMarkers.isEmpty()) { - logEventPartition.getMarkerList().addAll(eventMarkers); + eventMarkers.forEach(newEvent::addMarker); } if (event.hasCallerData()) { - logEventPartition.setCallerData(event.getCallerData()); + newEvent.setCallerData(event.getCallerData()); } - return logEventPartition; + return newEvent; } } diff --git a/platform-spring-bom/platform-spring-logging-server-config/src/test/java/com/latch/LoggingEventClonerTest.java b/platform-spring-bom/platform-spring-logging-server-config/src/test/java/com/latch/LoggingEventClonerTest.java new file mode 100644 index 0000000..3277102 --- /dev/null +++ b/platform-spring-bom/platform-spring-logging-server-config/src/test/java/com/latch/LoggingEventClonerTest.java @@ -0,0 +1,99 @@ +package com.latch; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.LoggingEvent; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.helpers.BasicMarkerFactory; + +import java.util.Collections; +import java.util.Map; + +public class LoggingEventClonerTest { + private final LoggerContext loggerContext; + private final LoggingEventCloner loggingEventCloner; + + public LoggingEventClonerTest() { + this.loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + this.loggingEventCloner = new LoggingEventCloner(loggerContext); + } + + @Test + public void correctlyClonesBasicEventProperties() { + LoggingEvent event = createLoggingEventWithContext(); + event.setLevel(Level.DEBUG); + event.setLoggerName("loggerName"); + event.setThreadName("testThread"); + event.setTimeStamp(System.currentTimeMillis()); + + LoggingEvent clonedEvent = loggingEventCloner.clone(event, "", Collections.emptyMap()); + + Assertions.assertNotNull(clonedEvent); + Assertions.assertEquals(event.getLevel(), clonedEvent.getLevel()); + Assertions.assertEquals(event.getLoggerName(), clonedEvent.getLoggerName()); + Assertions.assertEquals(event.getThreadName(), clonedEvent.getThreadName()); + Assertions.assertEquals(event.getTimeStamp(), clonedEvent.getTimeStamp()); + } + + @Test + public void correctlyClonesMessage() { + LoggingEvent event = createLoggingEventWithContext(); + String message = "Test message"; + + LoggingEvent clonedEvent = loggingEventCloner.clone(event, message, Collections.emptyMap()); + + Assertions.assertNotNull(clonedEvent); + Assertions.assertEquals(message, clonedEvent.getMessage()); + } + + @Test + public void correctlyClonesMDCProperties() { + LoggingEvent event = createLoggingEventWithContext(); + Map mdcProperties = Map.of("key1", "value1", "key2", "value2"); + + LoggingEvent clonedEvent = loggingEventCloner.clone(event, "", mdcProperties); + + Assertions.assertNotNull(clonedEvent); + Map clonedMDCProperties = clonedEvent.getMDCPropertyMap(); + Assertions.assertEquals(2, clonedMDCProperties.size()); + Assertions.assertEquals("value1", clonedMDCProperties.get("key1")); + Assertions.assertEquals("value2", clonedMDCProperties.get("key2")); + } + + @Test + public void correctlyClonesMarker() { + LoggingEvent event = createLoggingEventWithContext(); + Marker marker = new BasicMarkerFactory().getMarker("TestMarker"); + event.addMarker(marker); + + LoggingEvent clonedEvent = loggingEventCloner.clone(event, "", Collections.emptyMap()); + + Assertions.assertNotNull(clonedEvent); + Assertions.assertEquals(marker.getName(), clonedEvent.getMarkerList().get(0).getName()); + } + + @Test + public void correctlyClonesCallerData() { + LoggingEvent event = createLoggingEventWithContext(); + StackTraceElement[] callerData = new StackTraceElement[] { + new StackTraceElement("com.example.Class", "method", "Class.java", 42) + }; + event.setCallerData(callerData); + + LoggingEvent clonedEvent = loggingEventCloner.clone(event, "", Collections.emptyMap()); + + Assertions.assertTrue(clonedEvent.hasCallerData()); + StackTraceElement[] clonedCallerData = clonedEvent.getCallerData(); + Assertions.assertEquals(1, clonedCallerData.length); + Assertions.assertEquals(callerData[0].getClassLoaderName(), clonedCallerData[0].getClassLoaderName()); + } + + private LoggingEvent createLoggingEventWithContext() { + LoggingEvent event = new LoggingEvent(); + event.setLoggerContext(loggerContext); + return event; + } +}