From 2a557417c03f9f37ab166ca6ad720379374a60fb Mon Sep 17 00:00:00 2001 From: Maximilian Pilz Date: Mon, 12 Feb 2024 14:29:43 +0100 Subject: [PATCH] Performance and resolver fixes (#134) Fix various performance issues with xml handling and also fix the local address resolver. For details see the added changelog entries or source changes. # Checklist The following aspects have been respected by the author of this pull request, confirmed by both pull request assignee **and** reviewer: * Adherence to coding conventions * [x] Pull Request Assignee * [x] Reviewer * Adherence to javadoc conventions * [x] Pull Request Assignee * [x] Reviewer * Changelog update (necessity checked and entry added or not added respectively) * [x] Pull Request Assignee * [x] Reviewer * README update (necessity checked and entry added or not added respectively) * [x] Pull Request Assignee * [x] Reviewer * config update (necessity checked and entry added or not added respectively) * [x] Pull Request Assignee * [x] Reviewer * SDCcc executable ran against a test device (if necessary) * [x] Pull Request Assignee * [x] Reviewer --- .../license-check/header-MIT-draeger-java.txt | 12 +- .github/license-check/license-config | 5 + .github/license-check/license-config.json | 9 -- .github/workflows/license-check.yml | 8 +- CHANGELOG.md | 12 ++ README.md | 4 +- .../com/draeger/medical/sdccc/TestSuite.java | 118 +++++++++++------- .../configuration/CommandLineOptions.java | 16 ++- .../configuration/DefaultTestSuiteModule.java | 5 +- .../sdccc/messages/HibernateConfigBase.java | 3 +- .../sdccc/sdcri/LocalAddressResolverImpl.java | 33 +++++ .../sdcri/testclient/TestClientUtil.java | 6 +- .../sdccc/util/LoggingConfigurator.java | 7 +- 13 files changed, 164 insertions(+), 74 deletions(-) create mode 100644 .github/license-check/license-config delete mode 100644 .github/license-check/license-config.json create mode 100644 sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/LocalAddressResolverImpl.java diff --git a/.github/license-check/header-MIT-draeger-java.txt b/.github/license-check/header-MIT-draeger-java.txt index a6357ce8..dfe8813c 100644 --- a/.github/license-check/header-MIT-draeger-java.txt +++ b/.github/license-check/header-MIT-draeger-java.txt @@ -1,6 +1,6 @@ -/* - * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) %year% Draegerwerk AG & Co. KGaA. - * - * SPDX-License-Identifier: MIT - */ \ No newline at end of file +/\* + \* This Source Code Form is subject to the terms of the MIT License. + \* Copyright \(c\) (?:([0-9]{4}-[0-9]{4})|([0-9]{4}))(?:, (?:([0-9]{4}-[0-9]{4})|([0-9]{4})))* Draegerwerk AG & Co. KGaA. + \* + \* SPDX-License-Identifier: MIT + \*/ \ No newline at end of file diff --git a/.github/license-check/license-config b/.github/license-check/license-config new file mode 100644 index 00000000..5210e1b4 --- /dev/null +++ b/.github/license-check/license-config @@ -0,0 +1,5 @@ +[DraegerLicenseMIT] +file_name_pattern: sdccc/src/**/*.java +file_header_encoding: utf-8 +header_regex_file: .github/license-check/header-MIT-draeger-java.txt +header_regex_file_encoding: utf-8 diff --git a/.github/license-check/license-config.json b/.github/license-check/license-config.json deleted file mode 100644 index 925751f7..00000000 --- a/.github/license-check/license-config.json +++ /dev/null @@ -1,9 +0,0 @@ - -[ - { - "include": [ - "sdccc/src/**/*.java" - ], - "license": "./.github/license-check/header-MIT-draeger-java.txt" - } -] \ No newline at end of file diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml index 70cabad3..e789a8d2 100644 --- a/.github/workflows/license-check.yml +++ b/.github/workflows/license-check.yml @@ -11,8 +11,8 @@ jobs: steps: # Run `git checkout` - uses: actions/checkout@v3 - - uses: viperproject/check-license-header@v1 + - uses: maximilianpilz/file-header-check@v1 with: - path: . - config: .github/license-check/license-config.json - strict: false # \ No newline at end of file + config: '.github/license-check/license-config' + config-encoding: 'utf-8' + log-level: 'DEBUG' diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a4d853e..395d3b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- a command line parameter to change the log level threshold of the log file + +### Fixed + +- a performance issue with xml unmarshalling due to finding an interface implementation for TransformerFactory +- slowdown and high memory usage due to large unfiltered logs, filter can be configured, default shrinks the log +- autocommit of the database being on, it is now always off +- local address resolver sometimes giving a wrong address +- local address resolver doing a probe which may not be tolerated by some peers + ## [8.0.1] - 2023-09-13 ### Fixed diff --git a/README.md b/README.md index 9e28dd83..c709fd12 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,7 @@ The following command line options are supported by the test tool, the first two | device_bed | bed | the bed of the target provider, overrides setting from configuration if provided | no | | ipaddress | ip | ip address of the adapter to use for communication, overrides setting from configuration if provided | no | | test_run_directory | d | base directory to store test runs in, creates a timestamped SDCcc run | no | +| file_log_level | fll | log level to be used for the log file being created, e.g. DEBUG, defaults to INFO | no | ### Enabling Tests The *test_configuration.toml* file contains the identifiers of all implemented requirement tests. It is located in the @@ -233,7 +234,8 @@ be changed with the command line argument `test_run_directory` (see Section **Ru saved in that folder. Each test run gets its own directory named according to the scheme *SDCcc-Testrun_YYYY-MM-DDTHH-mm-SS*. Inside this directory there is a subdirectory *Database* and three files *SDCcc.log*, *TEST-SDCcc_direct.xml* and *TEST-SDCcc_invariant.xml*. *Database* is a database in which all messages -exchanged during the test run are recorded. *SDCcc.log* is the complete log file of the test run. The test results +exchanged during the test run are recorded. *SDCcc.log* is the complete log file of the test run +in accordance to the log file log level. The test results are located in the two result XML files, *TEST-SDCcc_direct.xml* for the direct tests and *TEST-SDCcc_invariant.xml* for the invariant tests. diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/TestSuite.java b/sdccc/src/main/java/com/draeger/medical/sdccc/TestSuite.java index 69ffb721..7ebaaf12 100644 --- a/sdccc/src/main/java/com/draeger/medical/sdccc/TestSuite.java +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/TestSuite.java @@ -1,6 +1,6 @@ /* * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) 2023 Draegerwerk AG & Co. KGaA. + * Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA. * * SPDX-License-Identifier: MIT */ @@ -620,70 +620,92 @@ public static void setupSwingTheme() * @param args array of command line arguments */ public static void main(final String[] args) throws IOException { + // improve xml interaction performance + setSystemProperties(); + // parse command line options final var cmdLine = new CommandLineOptions(args); // setup logging final var testRunDir = TestRunConfig.createTestRunDirectory( cmdLine.getTestRunDirectory().orElse(null)); - final var logConfig = LoggingConfigurator.loggerConfig(testRunDir); + final var logConfig = LoggingConfigurator.loggerConfig(testRunDir, cmdLine.getFileLogLevel()); checkLogConfig(logConfig); - Configurator.initialize(logConfig); - final var ctx = (LoggerContext) LogManager.getContext(false); - ctx.setConfiguration(logConfig); - ctx.updateLoggers(); - // we can only log this after setting up the logger - LOG.info("Using test run directory {}", testRunDir); + try (final var ignored = Configurator.initialize(logConfig)) { + final var ctx = (LoggerContext) LogManager.getContext(false); + ctx.setConfiguration(logConfig); + ctx.updateLoggers(); + // we can only log this after setting up the logger + LOG.info("Using test run directory {}", testRunDir); - try { - setupSwingTheme(); - } catch (final ClassNotFoundException - | UnsupportedLookAndFeelException - | InstantiationException - | IllegalAccessException e) { - LOG.warn("Error while setting swing look and feel options.", e); - } + try { + setupSwingTheme(); + } catch (final ClassNotFoundException + | UnsupportedLookAndFeelException + | InstantiationException + | IllegalAccessException e) { + LOG.warn("Error while setting swing look and feel options.", e); + } - final Injector injector = createTestRunInjector(cmdLine, testRunDir); + final Injector injector = createTestRunInjector(cmdLine, testRunDir); - final TriggerOnErrorOrWorseLogAppender triggerOnErrorOrWorseLogAppender = - findTriggerOnErrorOrWorseLogAppender(logConfig); - if (triggerOnErrorOrWorseLogAppender == null) { - // should never happen - throw new IllegalStateException("Could not find an TriggerOnErrorOrWorseLogAppender in the logConfig."); - } - triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler((LogEvent event) -> { - final TestRunObserver testRunObserver = injector.getInstance(TestRunObserver.class); - // stop observing the logs - triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler(null); - // invalidate test run - testRunObserver.invalidateTestRun("TriggerOnErrorOrWorseLogAppender observed an ERROR or worse." - + " Invalidating TestRun." - + " Please see the Log for more Details."); - }); - - String versionString = - triggerOnErrorOrWorseLogAppender.getClass().getPackage().getImplementationVersion(); - if (versionString != null) { - versionString = " version " + versionString; - } else { - versionString = ""; - } - LOG.info("Starting SDCcc {}", versionString); + final TriggerOnErrorOrWorseLogAppender triggerOnErrorOrWorseLogAppender = + findTriggerOnErrorOrWorseLogAppender(logConfig); + if (triggerOnErrorOrWorseLogAppender == null) { + // should never happen + throw new IllegalStateException("Could not find an TriggerOnErrorOrWorseLogAppender in the logConfig."); + } + triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler((LogEvent event) -> { + final TestRunObserver testRunObserver = injector.getInstance(TestRunObserver.class); + // stop observing the logs + triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler(null); + // invalidate test run + testRunObserver.invalidateTestRun("TriggerOnErrorOrWorseLogAppender observed an ERROR or worse." + + " Invalidating TestRun." + + " Please see the Log for more Details."); + }); + + String versionString = + triggerOnErrorOrWorseLogAppender.getClass().getPackage().getImplementationVersion(); + if (versionString != null) { + versionString = " version " + versionString; + } else { + versionString = ""; + } + LOG.info("Starting SDCcc {}", versionString); - try { + try { - InjectorTestBase.setInjector(injector); - final var testSuite = injector.getInstance(TestSuite.class); - TestSuite.exit(testSuite.runTestSuite(), false, injector, testRunDir); - } catch (final RuntimeException | Error e) { + InjectorTestBase.setInjector(injector); + final var testSuite = injector.getInstance(TestSuite.class); + TestSuite.exit(testSuite.runTestSuite(), false, injector, testRunDir); + } catch (final RuntimeException | Error e) { - LOG.error("Unchecked exception while setting up or running the TestSuite", e); - TestSuite.exit(0, true, injector, testRunDir); + LOG.error("Unchecked exception while setting up or running the TestSuite", e); + TestSuite.exit(0, true, injector, testRunDir); + } } } + private static void setSystemProperties() { + System.setProperty( + "javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom", + "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl"); + System.setProperty( + "javax.xml.stream.XMLEventFactory", "com.sun.xml.internal.stream.events.XMLEventFactoryImpl"); + System.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl"); + System.setProperty( + "javax.xml.parsers.DocumentBuilderFactory", + "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); + System.setProperty( + "javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema", + "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory"); + System.setProperty( + "javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); + System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl"); + } + private static TriggerOnErrorOrWorseLogAppender findTriggerOnErrorOrWorseLogAppender( final BuiltConfiguration logConfig) { for (Map.Entry entry : logConfig.getAppenders().entrySet()) { diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/CommandLineOptions.java b/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/CommandLineOptions.java index 32ad10be..80061d80 100644 --- a/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/CommandLineOptions.java +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/CommandLineOptions.java @@ -1,6 +1,6 @@ /* * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) 2023 Draegerwerk AG & Co. KGaA. + * Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA. * * SPDX-License-Identifier: MIT */ @@ -21,6 +21,7 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -41,6 +42,7 @@ public class CommandLineOptions { private static final String DEVICE_LOCATION_BED = "device_bed"; private static final String IP_ADDRESS = "ipaddress"; private static final String TEST_RUN_DIRECTORY = "test_run_directory"; + private static final String FILE_LOG_LEVEL = "file_log_level"; private final Path configPath; private final Path testConfigPath; private final String deviceEpr; @@ -52,6 +54,7 @@ public class CommandLineOptions { private final String deviceBed; private final String ipAddress; private final String testRunDirectory; + private final Level fileLogLevel; /** * Parse the command line options passed. @@ -96,6 +99,7 @@ public CommandLineOptions(final String[] commandLineArguments) { this.deviceBed = cmd.getOptionValue(DEVICE_LOCATION_BED); this.ipAddress = cmd.getOptionValue(IP_ADDRESS); this.testRunDirectory = cmd.getOptionValue(TEST_RUN_DIRECTORY); + this.fileLogLevel = Level.toLevel(cmd.getOptionValue(FILE_LOG_LEVEL), Level.INFO); } private Options setupOptions() { @@ -172,6 +176,12 @@ private Options setupOptions() { testRunDirectoryOpt.setRequired(false); options.addOption(testRunDirectoryOpt); } + { + final String description = "The log level to be used for the log file. e.g. DEBUG . The default is INFO."; + final var fileLogLevelOpt = new Option("fll", FILE_LOG_LEVEL, true, description); + fileLogLevelOpt.setRequired(false); + options.addOption(fileLogLevelOpt); + } return options; } @@ -233,6 +243,10 @@ public Optional getTestRunDirectory() { return Optional.ofNullable(testRunDirectory); } + public Level getFileLogLevel() { + return this.fileLogLevel; + } + private static void printNetworkAdapterInformation() throws SocketException { System.out.println("%nAvailable network adapters are:%n"); final Iterator networkInterfaceIterator = diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/DefaultTestSuiteModule.java b/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/DefaultTestSuiteModule.java index 8201fe37..a9bba169 100644 --- a/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/DefaultTestSuiteModule.java +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/configuration/DefaultTestSuiteModule.java @@ -1,6 +1,6 @@ /* * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) 2023 Draegerwerk AG & Co. KGaA. + * Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA. * * SPDX-License-Identifier: MIT */ @@ -15,6 +15,7 @@ import com.draeger.medical.sdccc.messages.guice.ManipulationInfoFactory; import com.draeger.medical.sdccc.messages.guice.MessageFactory; import com.draeger.medical.sdccc.sdcri.CustomCryptoSettings; +import com.draeger.medical.sdccc.sdcri.LocalAddressResolverImpl; import com.draeger.medical.sdccc.sdcri.testclient.TestClient; import com.draeger.medical.sdccc.sdcri.testclient.TestClientImpl; import com.draeger.medical.sdccc.util.junit.guice.XmlReportFactory; @@ -24,6 +25,7 @@ import com.google.inject.Singleton; import com.google.inject.assistedinject.FactoryModuleBuilder; import org.somda.sdc.dpws.crypto.CryptoSettings; +import org.somda.sdc.dpws.network.LocalAddressResolver; /** * Module which provides default guice bindings for SDCcc. @@ -44,5 +46,6 @@ protected void configure() { bind(ClassUtil.class).to(ClassUtilImpl.class); bind(HibernateConfig.class).to(HibernateConfigImpl.class).in(Singleton.class); bind(Manipulations.class).to(GRpcManipulations.class).in(Singleton.class); + bind(LocalAddressResolver.class).to(LocalAddressResolverImpl.class).in(Singleton.class); } } diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/messages/HibernateConfigBase.java b/sdccc/src/main/java/com/draeger/medical/sdccc/messages/HibernateConfigBase.java index 6b2f2872..b85e8d25 100644 --- a/sdccc/src/main/java/com/draeger/medical/sdccc/messages/HibernateConfigBase.java +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/messages/HibernateConfigBase.java @@ -1,6 +1,6 @@ /* * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) 2023 Draegerwerk AG & Co. KGaA. + * Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA. * * SPDX-License-Identifier: MIT */ @@ -67,6 +67,7 @@ public Configuration getConfiguration() { config.setProperty(Environment.ORDER_UPDATES, TRUE_SETTING_VALUE); config.setProperty(Environment.ORDER_INSERTS, TRUE_SETTING_VALUE); config.setProperty(Environment.BATCH_VERSIONED_DATA, TRUE_SETTING_VALUE); + config.setProperty(Environment.AUTOCOMMIT, FALSE_SETTING_VALUE); config.addAnnotatedClass(HTTPHeaderEntity.class); config.addAnnotatedClass(MdibVersionGroupEntity.class); diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/LocalAddressResolverImpl.java b/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/LocalAddressResolverImpl.java new file mode 100644 index 00000000..d85dc21c --- /dev/null +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/LocalAddressResolverImpl.java @@ -0,0 +1,33 @@ +/* + * This Source Code Form is subject to the terms of the MIT License. + * Copyright (c) 2024 Draegerwerk AG & Co. KGaA. + * + * SPDX-License-Identifier: MIT + */ + +package com.draeger.medical.sdccc.sdcri; + +import com.draeger.medical.sdccc.configuration.TestSuiteConfig; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.google.inject.name.Named; +import java.util.Optional; +import org.somda.sdc.dpws.network.LocalAddressResolver; + +/** + * Implementation of {@linkplain LocalAddressResolver} that uses the configured address. + */ +@Singleton +public class LocalAddressResolverImpl implements LocalAddressResolver { + private final String adapterAddress; + + @Inject + LocalAddressResolverImpl(@Named(TestSuiteConfig.NETWORK_INTERFACE_ADDRESS) final String adapterAddress) { + this.adapterAddress = adapterAddress; + } + + @Override + public Optional getLocalAddress(final String remoteUri) { + return Optional.of(adapterAddress); + } +} diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/testclient/TestClientUtil.java b/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/testclient/TestClientUtil.java index 774211b3..ada24949 100644 --- a/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/testclient/TestClientUtil.java +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/sdcri/testclient/TestClientUtil.java @@ -1,6 +1,6 @@ /* * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) 2023 Draegerwerk AG & Co. KGaA. + * Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA. * * SPDX-License-Identifier: MIT */ @@ -38,6 +38,7 @@ import org.somda.sdc.dpws.crypto.CryptoSettings; import org.somda.sdc.dpws.factory.CommunicationLogFactory; import org.somda.sdc.dpws.guice.DefaultDpwsModule; +import org.somda.sdc.dpws.network.LocalAddressResolver; import org.somda.sdc.glue.consumer.ConsumerConfig; import org.somda.sdc.glue.guice.DefaultGlueConfigModule; import org.somda.sdc.glue.guice.DefaultGlueModule; @@ -55,6 +56,7 @@ public class TestClientUtil { * @param cryptoSettings crypto setting * @param communicationLogMessageStorage connector to the {@linkplain MessageStorage} to write to * @param testRunObserver observer for invalidating test runs on unexpected errors + * @param localAddressResolver resolver for getting the local address to use * @param multicastTTL TTL for multicast packets used in Discovery. * Values from 1 to 255 are valid. */ @@ -63,6 +65,7 @@ public TestClientUtil( final CryptoSettings cryptoSettings, final CommunicationLogMessageStorage communicationLogMessageStorage, final TestRunObserver testRunObserver, + final LocalAddressResolver localAddressResolver, @Named(TestSuiteConfig.NETWORK_MULTICAST_TTL) final Long multicastTTL) { injector = createClientInjector(List.of( @@ -87,6 +90,7 @@ protected void configure() { .build(CommunicationLogFactory.class)); bind(CommunicationLogSink.class).toInstance(communicationLogMessageStorage); bind(TestRunObserver.class).toInstance(testRunObserver); + bind(LocalAddressResolver.class).toInstance(localAddressResolver); } })); } diff --git a/sdccc/src/main/java/com/draeger/medical/sdccc/util/LoggingConfigurator.java b/sdccc/src/main/java/com/draeger/medical/sdccc/util/LoggingConfigurator.java index bb6028d4..8d81b2fe 100644 --- a/sdccc/src/main/java/com/draeger/medical/sdccc/util/LoggingConfigurator.java +++ b/sdccc/src/main/java/com/draeger/medical/sdccc/util/LoggingConfigurator.java @@ -1,6 +1,6 @@ /* * This Source Code Form is subject to the terms of the MIT License. - * Copyright (c) 2023 Draegerwerk AG & Co. KGaA. + * Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA. * * SPDX-License-Identifier: MIT */ @@ -33,9 +33,10 @@ private LoggingConfigurator() {} * Generates a logger configuration storing the log in the given folder. * * @param loggingFolder to store log in + * @param fileLogLevel log level to use for the log file * @return new configuration */ - public static BuiltConfiguration loggerConfig(final File loggingFolder) { + public static BuiltConfiguration loggerConfig(final File loggingFolder, final Level fileLogLevel) { final ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder(); builder.setStatusLevel(Level.ERROR); builder.setConfigurationName("SDCcc"); @@ -87,6 +88,8 @@ public static BuiltConfiguration loggerConfig(final File loggingFolder) { .addAttribute("fileName", filePath.toString()) .addAttribute("append", true) .add(layoutBuilder); + appenderBuilder.addComponent(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY) + .addAttribute("level", fileLogLevel)); builder.add(appenderBuilder); rootLogger.add(builder.newAppenderRef(appenderBuilder.getName()));