diff --git a/appender/src/main/java/no/entur/logging/cloud/appender/scope/DefaultLoggingScope.java b/appender/src/main/java/no/entur/logging/cloud/appender/scope/DefaultLoggingScope.java index 21abefe6..d814c6ee 100644 --- a/appender/src/main/java/no/entur/logging/cloud/appender/scope/DefaultLoggingScope.java +++ b/appender/src/main/java/no/entur/logging/cloud/appender/scope/DefaultLoggingScope.java @@ -2,6 +2,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; +import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; @@ -11,22 +12,32 @@ */ public class DefaultLoggingScope implements LoggingScope { + // note: not ignored and not queued means it should be printed protected final Predicate queuePredicate; protected final Predicate ignorePredicate; + protected final long timestamp = System.currentTimeMillis(); protected boolean failure = false; - protected ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); + protected final LoggingScopeFlushMode flushMode; + + protected ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); - public DefaultLoggingScope(Predicate queuePredicate, Predicate ignorePredicate) { + public DefaultLoggingScope(Predicate queuePredicate, Predicate ignorePredicate, LoggingScopeFlushMode flushMode) { this.queuePredicate = queuePredicate; this.ignorePredicate = ignorePredicate; + this.flushMode = flushMode; } @Override - public ConcurrentLinkedQueue getEvents() { - return queue; + public Queue getEvents() { + if(flushMode == LoggingScopeFlushMode.LAZY && !failure) { + // filter unwanted events + events.removeIf(queuePredicate); + } + + return events; } @Override @@ -35,10 +46,16 @@ public boolean append(ILoggingEvent eventObject) { return true; } + if(flushMode == LoggingScopeFlushMode.LAZY) { + // queue for later processing + events.add(eventObject); + return true; + } + if(!failure) { if(queuePredicate.test(eventObject)) { // log this event later or not at all - queue.add(eventObject); + events.add(eventObject); return true; } } @@ -53,11 +70,11 @@ public boolean isFailure() { @Override public void failure() { - // TODO flush buffer here? this.failure = true; } public long getTimestamp() { return timestamp; } + } diff --git a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LogLevelLoggingScope.java b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LogLevelLoggingScope.java index 58165c4d..aadfa918 100644 --- a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LogLevelLoggingScope.java +++ b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LogLevelLoggingScope.java @@ -2,7 +2,6 @@ import ch.qos.logback.classic.spi.ILoggingEvent; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; /** @@ -13,8 +12,8 @@ public class LogLevelLoggingScope extends DefaultLoggingScope { private final Predicate logLevelFailurePredicate; - public LogLevelLoggingScope(Predicate queuePredicate, Predicate ignorePredicate, Predicate logLevelFailurePredicate) { - super(queuePredicate, ignorePredicate); + public LogLevelLoggingScope(Predicate queuePredicate, Predicate ignorePredicate, Predicate logLevelFailurePredicate, LoggingScopeFlushMode flushMode) { + super(queuePredicate, ignorePredicate, flushMode); this.logLevelFailurePredicate = logLevelFailurePredicate; } @@ -23,6 +22,16 @@ public boolean append(ILoggingEvent eventObject) { return true; } + if(flushMode == LoggingScopeFlushMode.LAZY) { + if(!failure && logLevelFailurePredicate.test(eventObject)) { + failure(); + } + + // queue for later processing + events.add(eventObject); + return true; + } + if(!failure) { if(logLevelFailurePredicate.test(eventObject)) { failure(); @@ -32,7 +41,7 @@ public boolean append(ILoggingEvent eventObject) { } if(queuePredicate.test(eventObject)) { // log this event later or not at all - queue.add(eventObject); + events.add(eventObject); return true; } } diff --git a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScope.java b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScope.java index 117b1c40..b8ecf426 100644 --- a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScope.java +++ b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScope.java @@ -2,6 +2,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; +import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; /** @@ -11,7 +12,7 @@ */ public interface LoggingScope { - ConcurrentLinkedQueue getEvents(); + Queue getEvents(); boolean append(ILoggingEvent eventObject); diff --git a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeAsyncAppender.java b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeAsyncAppender.java index 5718417c..3fc050a6 100644 --- a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeAsyncAppender.java +++ b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeAsyncAppender.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class LoggingScopeAsyncAppender extends MdcAsyncAppender implements LoggingScopeSink { @@ -41,7 +42,7 @@ public LoggingScope getCurrentScope() { } public void write(LoggingScope scope) { - ConcurrentLinkedQueue events = scope.getEvents(); + Queue events = scope.getEvents(); for (ILoggingEvent eventObject : events) { postProcess(eventObject); put(eventObject); diff --git a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeFlushMode.java b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeFlushMode.java new file mode 100644 index 00000000..57784f6b --- /dev/null +++ b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopeFlushMode.java @@ -0,0 +1,42 @@ +package no.entur.logging.cloud.appender.scope; + +/** + * + * Configure when to flush log statements; some log statements should always be written (i.e. error messages), + * so technically do not need to be cached. But in case there is other log statements which end up being written, + * log statements appear out of order even within a single request.

+ * + * Log accumulation tools will normally sort the log statements on the timestamp, so then order does not matter. + * But for local development (i.e. printing to console) logging out-of-order quickly gets very messy. + * + */ + +public enum LoggingScopeFlushMode { + + /** + * + * Flush log statements as soon it is determined they should be written. + * Results in out-of-order log statements. Uses less memory. + * + */ + EAGER("eager"), + + /** + * + * Flush when the on-demand scope closes, i.e. after all log statements have been made. + * Results in-order log statements. Uses more memory. + * + */ + LAZY("lazy"); + + private final String id; + + LoggingScopeFlushMode(String id) { + this.id = id; + } + + public String getId() { + return id; + } + +} diff --git a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopePostProcessing.java b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopePostProcessing.java index 686a3180..b7cd6281 100644 --- a/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopePostProcessing.java +++ b/appender/src/main/java/no/entur/logging/cloud/appender/scope/LoggingScopePostProcessing.java @@ -4,7 +4,7 @@ * * Interface for performing additional work on log event markers if they are to be logged (not dropped). * - * This work will be performed on the same thread which collected the log events. + * This work will be performed on the same thread which collected the log events, i.e. or at least a "worker" thread. * * In other words, this interface is intended to offload heavy work from the async logging thread. * diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java new file mode 100644 index 00000000..047a2d1a --- /dev/null +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java @@ -0,0 +1,109 @@ +package org.entur.example.web; + +import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControl; +import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControlClosable; +import org.entur.example.web.rest.MyEntity; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * + * Test additional logging due to a log statement with high log level. + * + */ + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(properties = { + "entur.logging.http.ondemand.enabled=true", + "entur.logging.http.ondemand.failure.http.enabled=false", + "entur.logging.http.ondemand.failure.logger.level=error", + "entur.logging.http.ondemand.flushMode=lazy", +}) +public class OndemandWebLoggingHttpOkHighLogLevelLazyTest { + + @LocalServerPort + private int randomServerPort; + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void useHumanReadablePlainEncoderExpectFullLoggingInOrder() { + MyEntity entity = new MyEntity(); + entity.setName("Entur"); + entity.setSecret("mySecret"); + + ResponseEntity response = restTemplate.postForEntity("/api/document/some/method", entity, MyEntity.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + public void useHumanReadablePlainEncoderExpectReducedLoggingInOrder() { + MyEntity entity = new MyEntity(); + entity.setName("Entur"); + entity.setSecret("mySecret"); + + ResponseEntity response = restTemplate.postForEntity("/api/document/some/method/infoLoggingOnly", entity, MyEntity.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + public void useHumanReadableJsonEncoderExpectFullLoggingInOrder() { + MyEntity entity = new MyEntity(); + entity.setName("Entur"); + entity.setSecret("mySecret"); + + try (CompositeConsoleOutputControlClosable c = CompositeConsoleOutputControl.useHumanReadableJsonEncoder()) { + ResponseEntity response = restTemplate.postForEntity("/api/document/some/method", entity, MyEntity.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + } + + + + @Test + public void useHumanReadableJsonEncoderExpectReducedLoggingInOrder() throws InterruptedException { + MyEntity entity = new MyEntity(); + entity.setName("Entur"); + entity.setSecret("mySecret"); + + try (CompositeConsoleOutputControlClosable c = CompositeConsoleOutputControl.useHumanReadableJsonEncoder()) { + ResponseEntity response = restTemplate.postForEntity("/api/document/some/method/infoLoggingOnly", entity, MyEntity.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + } + + @Test + public void useMachineReadableJsonEncoderExpectFullLoggingInOrder() { + MyEntity entity = new MyEntity(); + entity.setName("Entur"); + entity.setSecret("mySecret"); + + try (CompositeConsoleOutputControlClosable c = CompositeConsoleOutputControl.useMachineReadableJsonEncoder()) { + ResponseEntity response = restTemplate.postForEntity("/api/document/some/method", entity, MyEntity.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + } + + @Test + public void useMachineReadableJsonEncoderExpectReducedLoggingInOrder() throws InterruptedException { + MyEntity entity = new MyEntity(); + entity.setName("Entur"); + entity.setSecret("mySecret"); + + try (CompositeConsoleOutputControlClosable c = CompositeConsoleOutputControl.useMachineReadableJsonEncoder()) { + ResponseEntity response = restTemplate.postForEntity("/api/document/some/method/infoLoggingOnly", entity, MyEntity.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + } + +} \ No newline at end of file diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/GrpcOndemandLoggingAutoConfiguration.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/GrpcOndemandLoggingAutoConfiguration.java index 59138898..961d8c69 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/GrpcOndemandLoggingAutoConfiguration.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/GrpcOndemandLoggingAutoConfiguration.java @@ -66,7 +66,7 @@ public GrpcLoggingScopeContextInterceptor grpcLoggingScopeContextInterceptor(Ond } } - GrpcContextLoggingScopeFactory grpcContextLoggingScopeFactory = new GrpcContextLoggingScopeFactory(); + GrpcContextLoggingScopeFactory grpcContextLoggingScopeFactory = new GrpcContextLoggingScopeFactory(properties.getFlushMode()); GrpcLoggingScopeContextInterceptor interceptor = GrpcLoggingScopeContextInterceptor .newBuilder() diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java index e3e3a99d..7d08e0df 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java @@ -1,5 +1,6 @@ package no.entur.logging.cloud.spring.ondemand.grpc.properties; +import no.entur.logging.cloud.appender.scope.LoggingScopeFlushMode; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.Ordered; @@ -21,6 +22,8 @@ public class OndemandProperties { private List paths = new ArrayList<>(); + private LoggingScopeFlushMode flushMode = LoggingScopeFlushMode.EAGER; + public void setEnabled(boolean enabled) { this.enabled = enabled; } @@ -68,4 +71,12 @@ public int getInterceptorOrder() { public void setInterceptorOrder(int interceptorOrder) { this.interceptorOrder = interceptorOrder; } + + public LoggingScopeFlushMode getFlushMode() { + return flushMode; + } + + public void setFlushMode(LoggingScopeFlushMode flushMode) { + this.flushMode = flushMode; + } } \ No newline at end of file diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcContextLoggingScopeFactory.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcContextLoggingScopeFactory.java index e61757e6..db2e6fdc 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcContextLoggingScopeFactory.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcContextLoggingScopeFactory.java @@ -8,13 +8,20 @@ public class GrpcContextLoggingScopeFactory implements LoggingScopeFactory, LoggingScopeProvider { + protected final LoggingScopeFlushMode flushMode; + + public GrpcContextLoggingScopeFactory(LoggingScopeFlushMode flushMode) { + this.flushMode = flushMode; + + } + @Override public LoggingScope openScope(Predicate queuePredicate, Predicate ignorePredicate, Predicate logLevelFailurePredicate) { LoggingScope scope; if(logLevelFailurePredicate == null) { - scope = new DefaultLoggingScope(queuePredicate, ignorePredicate); + scope = new DefaultLoggingScope(queuePredicate, ignorePredicate, flushMode); } else { - scope = new LogLevelLoggingScope(queuePredicate, ignorePredicate, logLevelFailurePredicate); + scope = new LogLevelLoggingScope(queuePredicate, ignorePredicate, logLevelFailurePredicate, flushMode); } return scope; diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java index 1569427e..00f3370c 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java @@ -113,13 +113,12 @@ public void close(Status status, Metadata trailers) { try { if (filter.getGrpcStatusPredicate().test(status)) { // was there an error response - sink.write(scope); - } else if(scope.isFailure()) { - // there some dangerous error message - sink.write(scope); + scope.failure(); } else if(filter.hasFailureDuration() && System.currentTimeMillis() - scope. getTimestamp() > filter.getFailureDuration()) { - sink.write(scope); + scope.failure(); } + + sink.write(scope); } finally { factory.closeScope(scope); // this is really a noop operation } diff --git a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java index 65dd61ad..5a14e46a 100644 --- a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java +++ b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java @@ -47,7 +47,13 @@ public class GcpWebOndemandLoggingAutoConfiguration { @ConditionalOnProperty(name = {"entur.logging.http.ondemand.enabled"}, havingValue = "true", matchIfMissing = false) public static class OndemandConfiguration { - private ThreadLocalLoggingScopeFactory factory = new ThreadLocalLoggingScopeFactory(); + private final ThreadLocalLoggingScopeFactory factory; + private OndemandProperties properties; + + public OndemandConfiguration(OndemandProperties properties) { + this.properties = properties; + this.factory = new ThreadLocalLoggingScopeFactory(properties.getFlushMode()); + } @Bean public LoggingScopeControls loggingScopeControls() { @@ -56,12 +62,12 @@ public LoggingScopeControls loggingScopeControls() { @Bean @ConditionalOnMissingBean(LoggingScopeThreadUtils.class) - public LoggingScopeThreadUtils loggingScopeThreadUtils() { + public LoggingScopeThreadUtils loggingScopeThreadUtils(OndemandProperties properties) { return new DefaultLoggingScopeThreadUtils(factory); } @Bean - public FilterRegistrationBean ondemandFilter(OndemandProperties properties) { + public FilterRegistrationBean ondemandFilter() { LoggingScopeAsyncAppender appender = getAppender(); LOGGER.info("Enable on-demand HTTP logging filter"); @@ -109,7 +115,6 @@ private static LoggingScopeAsyncAppender getAppender() { throw new IllegalStateException("Expected on-demand log appender implementing " + LoggingScopeAsyncAppender.class.getName()); } - public HttpLoggingScopeFilter toFilter(String matcher, OndemandSuccess success, OndemandFailure failure, OndemandTroubleshoot troubleshoot) { HttpLoggingScopeFilter filter = new HttpLoggingScopeFilter(); diff --git a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/OndemandFilter.java b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/OndemandFilter.java index ac21d5fb..30c4dbca 100644 --- a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/OndemandFilter.java +++ b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/OndemandFilter.java @@ -136,13 +136,12 @@ private void flush(HttpServletRequest httpServletRequest, HttpServletResponse se if (filter.getHttpStatusFailurePredicate().test(servletResponse.getStatus())) { // was there an error response - sink.write(scope); - } else if (scope.isFailure()) { - // was there some dangerous error message? - sink.write(scope); + scope.failure(); } else if(filter.hasFailureDuration() && System.currentTimeMillis() - scope. getTimestamp() > filter.getFailureDuration()) { - sink.write(scope); + scope.failure(); } + + sink.write(scope); } } diff --git a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/properties/OndemandProperties.java b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/properties/OndemandProperties.java index 8fc2d876..a3a95ba1 100644 --- a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/properties/OndemandProperties.java +++ b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/properties/OndemandProperties.java @@ -1,5 +1,6 @@ package no.entur.logging.cloud.spring.ondemand.web.properties; +import no.entur.logging.cloud.appender.scope.LoggingScopeFlushMode; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.Ordered; @@ -27,6 +28,8 @@ public OndemandProperties() { private List paths = new ArrayList<>(); + private LoggingScopeFlushMode flushMode = LoggingScopeFlushMode.EAGER; + public void setEnabled(boolean enabled) { this.enabled = enabled; } @@ -82,4 +85,12 @@ public OndemandTroubleshoot getTroubleshoot() { public void setTroubleshoot(OndemandTroubleshoot troubleshoot) { this.troubleshoot = troubleshoot; } + + public LoggingScopeFlushMode getFlushMode() { + return flushMode; + } + + public void setFlushMode(LoggingScopeFlushMode flushMode) { + this.flushMode = flushMode; + } } \ No newline at end of file diff --git a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/scope/ThreadLocalLoggingScopeFactory.java b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/scope/ThreadLocalLoggingScopeFactory.java index 58520ba6..47c7a3cc 100644 --- a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/scope/ThreadLocalLoggingScopeFactory.java +++ b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/scope/ThreadLocalLoggingScopeFactory.java @@ -1,23 +1,25 @@ package no.entur.logging.cloud.spring.ondemand.web.scope; -import no.entur.logging.cloud.appender.scope.DefaultLoggingScope; -import no.entur.logging.cloud.appender.scope.LogLevelLoggingScope; -import no.entur.logging.cloud.appender.scope.LoggingScope; -import no.entur.logging.cloud.appender.scope.LoggingScopeFactory; +import no.entur.logging.cloud.appender.scope.*; import java.util.function.Predicate; public class ThreadLocalLoggingScopeFactory implements LoggingScopeFactory, LoggingScopeControls { - private final ThreadLocal queues = new ThreadLocal<>(); + protected final ThreadLocal queues = new ThreadLocal<>(); + protected final LoggingScopeFlushMode flushMode; + + public ThreadLocalLoggingScopeFactory(LoggingScopeFlushMode flushMode) { + this.flushMode = flushMode; + } @Override public LoggingScope openScope(Predicate queuePredicate, Predicate ignorePredicate, Predicate logLevelFailurePredicate) { LoggingScope scope; if(logLevelFailurePredicate == null) { - scope = new DefaultLoggingScope(queuePredicate, ignorePredicate); + scope = new DefaultLoggingScope(queuePredicate, ignorePredicate, flushMode); } else { - scope = new LogLevelLoggingScope(queuePredicate, ignorePredicate, logLevelFailurePredicate); + scope = new LogLevelLoggingScope(queuePredicate, ignorePredicate, logLevelFailurePredicate, flushMode); } queues.set(scope); return scope;