1. Introduction
This Library brings back the Groovy DSL for configuring Logback. There was some concern about security of the DSL so this library adds security via the SecureASTCustomizer.
Note while this is meant to be more secure than the initial implementation, and while I will give some opinions on how you might be use this library is a more secure manner, your application security is up to you. You use this library at your own risk. If you find any flaws/security risks you can log them on the GitHub Issues Page: https://github.com/virtualdogbert/logback-groovy-config/issues
It is suggested that you use or make a sample app when submitting an issue. A shell app is provided under the examples directory. You can alter this adding your logback groovy config, and dependencies relevant to the issue.
This library uses a Java Service Configuator GroovyConfigurator.groovy
which is dynamically called by logback-classic
on startup.
Pull requests are welcome provided you provide any tests demonstrating/testing any new features, and documentation to go along with it.
The app does have default security configuration, which can be overridden see the section:
Pull request changing the default configuration will not be accepted unless they fix a security flaw, or there is a really good reason provided, that makes sense for all users of the library.
You can find the default configuration here:
These defaults limit what can be done in the DSL, in terms of imports and method calls.
The overrides do not provide for overriding the ScriptExpressionChecker
this checker, checks for methods that are allowed by the DSL
and are part of the over all security. If you find that a DSL method is missing, or if an extension library like the logstash-logback-encoder
adds DSL methods that are not allowed you can open an issue on GitHub:
https://github.com/virtualdogbert/logback-groovy-config/issues
Please be sure to include sample configuration showing all the DSL methods you used, preferably is a sample app. If the DSL method comes from an Opensource extension please provide a link to the project. Additions to the DSL allowed methods will be handled on a case by case basis, at my description, and the documentation will be updated noting the additions in the version history.
2. Version History
-
1.14.5, 1.13.5, 1.12.5
-
Adding
jsonGeneratorDecorator
andfieldNames
as accepted DSL methods for use with the logstash-logback-encoder.
-
-
1.14.4, 1.13.4, 1.12.4
-
Adding missing DSL element, adding some more default imports and making the defaults always apply, and are just added on to, rather than overwritten with the
logbackCompiler.groovy
-
-
1.14.3, 1.13.3, 1.12.3
-
Adding on to default to make the default a little nicer.
-
-
1.14.2, 1.13.2, 1.12.2
-
Found that the DSL methods are "added" to Object, because the dynamic nature of the runtime DSL. So I added on to the ScriptExpressionChecker accounting for that. I also updated the default config explaining the config of the ScriptExpressionChecker asking if there is a missing DSL method to submit a bug report.
-
-
1.14.1, 1.13.1, 1.12.1
-
Found an issue in #4 where the ScriptExpressionChecker was being overzealous on method calls from objects that has sub objectExpressions that had types. So I loosened that up, and check for System and String types under the object type, and those have a restricted set of methods that they can call.
-
Upgraded to versions 1.4.6, 1.3.6, and 1.2.12 for logback versions
-
1.2.12 is being release because there are still a lot of popular projects still using the old version(updated recently). With this version the config file will be name logback-config.groovy, because at this point logback will error if you have a logback.groovy.
-
-
1.14.0
-
Upgrading to Logback 1.4.5
-
-
1.13.0
-
Upgrading to Logback 1.3.5
-
Changing default filename back to
logback.groovy
-
removing JMX config because it was removed from 1.3.5 because of potential vulnerability
-
-
1.0
-
Initial Release
-
3. Getting Started
-
Add the following dependency to .build.gradle:
Logback version 1.4.x:
implementation 'io.github.virtualdogbert:logback-groovy-config:1.14.5'
Logback version 1.3.x:
implementation 'io.github.virtualdogbert:logback-groovy-config:1.13.5'
Logback version 1.2.x:
implementation 'io.github.virtualdogbert:logback-groovy-config:1.12.5'
Add a logback.groovy
file to your resources(e.g. grails-app/config, src/main/resources) using the Groovy DSL. The file name was defaulted
to logback-config.groovy
in 1.12.1 but was rolled back to logback.groovy
because newer versions of logback shouldn’t throw and exception.
However, you can be the config file name to anything you want. To change the file name you can use the system property: logback.config.file
or the environment variable: LOGBACK_CONFIG_FILE
You can provide an external config file by setting the VM property logback.config.external.file
or the environment property
LOGBACK_CONFIG_EXTERNAL_FILE
. The external file if provided will take president over the config in the resource.
Depending on the environment external files might make sense, although an alternative is to have environment variables in your internal config that can control aspects of your logging.
4. Examples
Here are some base example for the logback-config.groovy using the Logback Groovy DSL:
4.1. Spring Boot/Grails
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.FileAppender
import grails.util.BuildSettings
import org.springframework.boot.logging.logback.ColorConverter
import org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter
import java.nio.charset.StandardCharsets
import static grails.util.Environment.isDevelopmentMode
conversionRule 'clr', ColorConverter
conversionRule 'wex', WhitespaceThrowableProxyConverter
// See http://logback.qos.ch/manual/groovy.html for details on configuration
appender('STDOUT', ConsoleAppender) {
encoder(PatternLayoutEncoder) {
charset = StandardCharsets.UTF_8
pattern =
'%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date
'%clr(%5p) ' + // Log level
'%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread
'%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger
'%m%n%wex' // Message
}
}
def targetDir = BuildSettings.TARGET_DIR
if (isDevelopmentMode() && targetDir != null) {
appender("FULL_STACKTRACE", FileAppender) {
file = "${targetDir}/stacktrace.log"
append = true
encoder(PatternLayoutEncoder) {
charset = StandardCharsets.UTF_8
pattern = "%level %logger - %msg%n"
}
}
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
}
root(INFO, ['STDOUT'])
4.2. Micronaut
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.FileAppender
import java.nio.charset.StandardCharsets
// See http://logback.qos.ch/manual/groovy.html for details on configuration
appender('STDOUT', ConsoleAppender) {
encoder(PatternLayoutEncoder) {
charset = StandardCharsets.UTF_8
pattern = '%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n' // Message
}
}
root(INFO, ['STDOUT'])
5. Default Config
The following is the default accept lists that are used by SecureASTCustomizer to help add security to the Groovy DSL for Logback.
package ch.qos.logback.classic.gaffer
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.core.boolex.Matcher
import groovy.transform.CompileStatic
import static org.codehaus.groovy.syntax.Types.*
/**
* Default Accept Lists for the AST Customizer used to limit what can be done in the Groovy DSL for Logback.
*/
@CompileStatic
class DefaultAcceptLists {
/**
* This Limits the acceptable tokens that can bs use in the Groovy DSL file. Like +-/% etc.
*/
static final List tokensAcceptList = [
DIVIDE, PLUS, MINUS,
MULTIPLY, MOD, POWER,
PLUS_PLUS, MINUS_MINUS,
PLUS_EQUAL, LOGICAL_AND, COMPARE_EQUAL,
COMPARE_NOT_EQUAL, COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL,
LOGICAL_OR, NOT, COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL,
EQUALS, COMPARE_NOT_EQUAL, COMPARE_EQUAL, KEYWORD_INSTANCEOF
]
/**
* This limits the acceptable constant types that can be used in the DSL
*/
static final List constantTypesClassesAcceptList = [
Object,
Integer,
Float,
Long,
Double,
BigDecimal,
String,
Integer.TYPE,
Long.TYPE,
Float.TYPE,
Double.TYPE,
Boolean.TYPE,
Matcher,
LoggerContext,
ch.qos.logback.classic.Level
]
/**
* This limits the acceptable static imports for the Groovy DSL
*/
static final List<String> staticImportsAcceptList = [
'java.nio.charset.Charset.forName',
'java.lang.Object.conversionRule',
'java.lang.Object.appender',
'java.lang.Object.layout',
'java.lang.Object.appenderRef',
'java.lang.Object.encoder',
'java.lang.Object.filter',
'java.lang.Object.evaluator',
'java.lang.Object.logger',
'java.lang.Object.root',
'ch.qos.logback.classic.Level.toLevel',
'ch.qos.logback.classic.Level',
'ch.qos.logback.classic.Level.OFF',
'ch.qos.logback.classic.Level.ERROR',
'ch.qos.logback.classic.Level.WARN',
'ch.qos.logback.classic.Level.INFO',
'ch.qos.logback.classic.Level.DEBUG',
'ch.qos.logback.classic.Level.TRACE',
'ch.qos.logback.classic.Level.ALL',
'ch.qos.logback.core.spi.FilterReply',
'ch.qos.logback.core.spi.FilterReply.DENY',
'ch.qos.logback.core.spi.FilterReply.NEUTRAL',
'ch.qos.logback.core.spi.FilterReply.ACCEPT',
'ch.qos.logback.core.boolex.Matcher.start',
'java.lang.Object.putProperty',
'java.lang.Object.getProperty',
'java.lang.System',
'java.lang.System.getenv',
'java.lang.System.getProperty',
'java.lang.Object.getOrDefault',
'java.lang.Object.println',
'java.lang.Object.rollingPolicy',
'java.lang.Object.triggeringPolicy',
'java.lang.Object.statusListener'
]
/**
* This limits the acceptable imports for the Groovy DSL.
*/
static final List<String> importsAcceptList = [
'ch.qos.logback.core.testUtil.StringListAppender',
'java.lang.Object',
'org.springframework.beans.factory.annotation.Autowired', //Grails requires this for some reason, but you can not autowire any service because those classes are not on the import list.
'java.nio.charset.Charset.forName',
'com.logentries.logback.LogentriesAppender',
'grails.util.BuildSettings',
'grails.util.Environment',
'org.slf4j.MDC',
'org.springframework.boot.logging.logback.ColorConverter',
'org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter',
'java.nio.charset.Charset',
'java.nio.charset.StandardCharsets',
'ch.qos.logback.classic.AsyncAppender',
'ch.qos.logback.classic.boolex.JaninoEventEvaluator',
'ch.qos.logback.classic.encoder.PatternLayoutEncoder',
'ch.qos.logback.classic.Level',
'ch.qos.logback.core.ConsoleAppender',
'ch.qos.logback.core.FileAppender',
'ch.qos.logback.classic.PatternLayout',
'ch.qos.logback.core.encoder.LayoutWrappingEncoder',
'ch.qos.logback.classic.LoggerContext',
'ch.qos.logback.core.boolex.Matcher',
'ch.qos.logback.core.filter.EvaluatorFilter',
'ch.qos.logback.classic.filter.ThresholdFilter',
'java.lang.System',
'java.lang.System.getenv',
'java.lang.System.getProperty',
'java.lang.Object.getOrDefault',
'java.lang.Object.getOrDefault',
'ch.qos.logback.classic.Level.toLevel',
'ch.qos.logback.core.status.OnConsoleStatusListener',
'ch.qos.logback.core.rolling.TriggeringPolicyBase',
'ch.qos.logback.core.rolling.helper.Compressor',
'ch.qos.logback.core.rolling.helper.PeriodicityType',
'ch.qos.logback.core.rolling.helper.TokenConverter',
'ch.qos.logback.core.rolling.helper.IntegerTokenConverter',
'ch.qos.logback.core.rolling.helper.CompressionMode',
'ch.qos.logback.core.rolling.helper.ArchiveRemover',
'ch.qos.logback.core.rolling.helper.FileFilterUtil',
'ch.qos.logback.core.rolling.helper.RenameUtil',
'ch.qos.logback.core.rolling.helper.DateTokenConverter',
'ch.qos.logback.core.rolling.helper.FileNamePattern',
'ch.qos.logback.core.rolling.helper.RollingCalendar',
'ch.qos.logback.core.rolling.helper.FileStoreUtil',
'ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover',
'ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover',
'ch.qos.logback.core.rolling.helper.MonoTypedConverter',
'ch.qos.logback.core.rolling.RollingPolicyBase',
'ch.qos.logback.core.rolling.RollingFileAppender',
'ch.qos.logback.core.rolling.FixedWindowRollingPolicy',
'ch.qos.logback.core.rolling.TimeBasedRollingPolicy',
'ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicyBase',
'ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy',
'ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy',
'ch.qos.logback.core.rolling.RollingPolicy',
'ch.qos.logback.core.rolling.TimeBasedRollingPolicy',
'ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy',
'ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy',
'ch.qos.logback.core.rolling.RolloverFailure',
'ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP',
'ch.qos.logback.core.rolling.TriggeringPolicy',
'ch.qos.logback.classic.net.SMTPAppender'
]
/**
* This limits the acceptable star imports for the Groovy DSL.
*/
static final List<String> starImportsAcceptList = []
/**
* This limits the acceptable star static imports for the Groovy DSL.
*/
static final List<String> staticStarImportsAcceptList = [
'grails.util.Environment',
'io.micronaut.context.env.Environment'
]
}
6. Overriding Default Config
The default config can be added on to by providing a logbackCompiler.groovy
file in your resources
directory. This makes it so that you can
add to the default in your code, but not externally. If you are working where resources could be exposed externally, like in an exploded
war scenario or something similar, then you will have to secure that directory. The following are the lists from the default config that you
can override:
-
tokensAcceptList
-
constantTypesClassesAcceptList
-
staticImportsAcceptList
-
importsAcceptList
-
starImportsAcceptList
-
staticStarImportsAcceptList
The format in the file will be:
tokensAcceptList = [
//your list here.
]
constantTypesClassesAcceptList = [
//your list here.
]
staticImportsAcceptList = [
//your list here.
]
importsAcceptList = [
//your list here.
]
starImportsAcceptList = [
//your list here.
]
staticStarImportsAcceptList = [
//your list here.
]
Here is an example given every class you could import from the parent library Logback library:
importsAcceptList = [
'ch.qos.logback.core.testUtil.SampleConverter',
'ch.qos.logback.core.testUtil.StringListAppender',
'java.lang.Object',
'org.springframework.beans.factory.annotation.Autowired',
'java.nio.charset.Charset.forName',
'com.logentries.logback.LogentriesAppender',
'grails.util.BuildSettings',
'grails.util.Environment',
'io.micronaut.context.env.Environment',
'org.slf4j.MDC',
'org.springframework.boot.logging.logback.ColorConverter',
'org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter',
'java.nio.charset.Charset',
'java.nio.charset.StandardCharsets',
'ch.qos.logback.core.BasicStatusManager',
'ch.qos.logback.core.ConsoleAppender',
'ch.qos.logback.core.hook.ShutdownHook',
'ch.qos.logback.core.hook.ShutdownHookBase',
'ch.qos.logback.core.hook.DelayingShutdownHook',
'ch.qos.logback.core.spi.PropertyContainer',
'ch.qos.logback.core.spi.ContextAwareBase',
'ch.qos.logback.core.spi.LogbackLock',
'ch.qos.logback.core.spi.FilterAttachableImpl',
'ch.qos.logback.core.spi.ContextAwareImpl',
'ch.qos.logback.core.spi.ScanException',
'ch.qos.logback.core.spi.DeferredProcessingAware',
'ch.qos.logback.core.spi.ContextAware',
'ch.qos.logback.core.spi.LifeCycle',
'ch.qos.logback.core.spi.FilterReply',
'ch.qos.logback.core.spi.PreSerializationTransformer',
'ch.qos.logback.core.spi.AppenderAttachable',
'ch.qos.logback.core.spi.CyclicBufferTracker',
'ch.qos.logback.core.spi.FilterAttachable',
'ch.qos.logback.core.spi.ComponentTracker',
'ch.qos.logback.core.spi.AppenderAttachableImpl',
'ch.qos.logback.core.spi.PropertyDefiner',
'ch.qos.logback.core.spi.AbstractComponentTracker',
'ch.qos.logback.core.property.FileExistsPropertyDefiner',
'ch.qos.logback.core.property.ResourceExistsPropertyDefiner',
'ch.qos.logback.core.CoreConstants',
'ch.qos.logback.core.layout.EchoLayout',
'ch.qos.logback.core.Appender',
'ch.qos.logback.core.joran.JoranConfiguratorBase',
'ch.qos.logback.core.joran.spi.ActionException',
'ch.qos.logback.core.joran.spi.HostClassAndPropertyDouble',
'ch.qos.logback.core.joran.spi.JoranException',
'ch.qos.logback.core.joran.spi.NoAutoStart',
'ch.qos.logback.core.joran.spi.EventPlayer',
'ch.qos.logback.core.joran.spi.XMLUtil',
'ch.qos.logback.core.joran.spi.ConsoleTarget',
'ch.qos.logback.core.joran.spi.Interpreter',
'ch.qos.logback.core.joran.spi.SimpleRuleStore',
'ch.qos.logback.core.joran.spi.InterpretationContext',
'ch.qos.logback.core.joran.spi.RuleStore',
'ch.qos.logback.core.joran.spi.NoAutoStartUtil',
'ch.qos.logback.core.joran.spi.ElementSelector',
'ch.qos.logback.core.joran.spi.ConfigurationWatchList',
'ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry',
'ch.qos.logback.core.joran.spi.DefaultClass',
'ch.qos.logback.core.joran.spi.ElementPath',
'ch.qos.logback.core.joran.conditional.ThenOrElseActionBase',
'ch.qos.logback.core.joran.conditional.Condition',
'ch.qos.logback.core.joran.conditional.PropertyWrapperForScripts',
'ch.qos.logback.core.joran.conditional.ThenAction',
'ch.qos.logback.core.joran.conditional.PropertyEvalScriptBuilder',
'ch.qos.logback.core.joran.conditional.ElseAction',
'ch.qos.logback.core.joran.conditional.IfAction',
'ch.qos.logback.core.joran.util.beans.BeanDescriptionCache',
'ch.qos.logback.core.joran.util.beans.BeanDescriptionFactory',
'ch.qos.logback.core.joran.util.beans.BeanDescription',
'ch.qos.logback.core.joran.util.beans.BeanUtil',
'ch.qos.logback.core.joran.util.PropertySetter',
'ch.qos.logback.core.joran.util.ConfigurationWatchListUtil',
'ch.qos.logback.core.joran.util.StringToObjectConverter',
'ch.qos.logback.core.joran.GenericConfigurator',
'ch.qos.logback.core.joran.action.ImplicitAction',
'ch.qos.logback.core.joran.action.IncludeAction',
'ch.qos.logback.core.joran.action.NOPAction',
'ch.qos.logback.core.joran.action.IADataForBasicProperty',
'ch.qos.logback.core.joran.action.TimestampAction',
'ch.qos.logback.core.joran.action.AbstractEventEvaluatorAction',
'ch.qos.logback.core.joran.action.ParamAction',
'ch.qos.logback.core.joran.action.AppenderAction',
'ch.qos.logback.core.joran.action.DefinePropertyAction',
'ch.qos.logback.core.joran.action.StatusListenerAction',
'ch.qos.logback.core.joran.action.ContextPropertyAction',
'ch.qos.logback.core.joran.action.NestedComplexPropertyIA',
'ch.qos.logback.core.joran.action.NestedBasicPropertyIA',
'ch.qos.logback.core.joran.action.Action',
'ch.qos.logback.core.joran.action.AppenderRefAction',
'ch.qos.logback.core.joran.action.ActionUtil',
'ch.qos.logback.core.joran.action.ShutdownHookAction',
'ch.qos.logback.core.joran.action.IADataForComplexProperty',
'ch.qos.logback.core.joran.action.ConversionRuleAction',
'ch.qos.logback.core.joran.action.ActionConst',
'ch.qos.logback.core.joran.action.PropertyAction',
'ch.qos.logback.core.joran.action.NewRuleAction',
'ch.qos.logback.core.joran.node.ComponentNode',
'ch.qos.logback.core.joran.event.EndEvent',
'ch.qos.logback.core.joran.event.SaxEventRecorder',
'ch.qos.logback.core.joran.event.SaxEvent',
'ch.qos.logback.core.joran.event.BodyEvent',
'ch.qos.logback.core.joran.event.StartEvent',
'ch.qos.logback.core.joran.event.InPlayListener',
'ch.qos.logback.core.joran.event.stax.EndEvent',
'ch.qos.logback.core.joran.event.stax.StaxEventRecorder',
'ch.qos.logback.core.joran.event.stax.BodyEvent',
'ch.qos.logback.core.joran.event.stax.StartEvent',
'ch.qos.logback.core.joran.event.stax.StaxEvent',
'ch.qos.logback.core.LogbackException',
'ch.qos.logback.core.PropertyDefinerBase',
'ch.qos.logback.core.helpers.CyclicBuffer',
'ch.qos.logback.core.helpers.ThrowableToStringArray',
'ch.qos.logback.core.helpers.Transform',
'ch.qos.logback.core.helpers.NOPAppender',
'ch.qos.logback.core.net.LoginAuthenticator',
'ch.qos.logback.core.net.DefaultSocketConnector',
'ch.qos.logback.core.net.ssl.KeyStoreFactoryBean',
'ch.qos.logback.core.net.ssl.SSLParametersConfiguration',
'ch.qos.logback.core.net.ssl.SSLComponent',
'ch.qos.logback.core.net.ssl.SSLNestedComponentRegistryRules',
'ch.qos.logback.core.net.ssl.SSLConfigurableSocket',
'ch.qos.logback.core.net.ssl.SSLConfigurableServerSocket',
'ch.qos.logback.core.net.ssl.SSLConfiguration',
'ch.qos.logback.core.net.ssl.ConfigurableSSLSocketFactory',
'ch.qos.logback.core.net.ssl.ConfigurableSSLServerSocketFactory',
'ch.qos.logback.core.net.ssl.SecureRandomFactoryBean',
'ch.qos.logback.core.net.ssl.SSLContextFactoryBean',
'ch.qos.logback.core.net.ssl.SSL',
'ch.qos.logback.core.net.ssl.SSLConfigurable',
'ch.qos.logback.core.net.ssl.TrustManagerFactoryFactoryBean',
'ch.qos.logback.core.net.ssl.KeyManagerFactoryFactoryBean',
'ch.qos.logback.core.net.SMTPAppenderBase',
'ch.qos.logback.core.net.SyslogAppenderBase',
'ch.qos.logback.core.net.SocketConnector',
'ch.qos.logback.core.net.SyslogOutputStream',
'ch.qos.logback.core.net.QueueFactory',
'ch.qos.logback.core.net.HardenedObjectInputStream',
'ch.qos.logback.core.net.AbstractSocketAppender',
'ch.qos.logback.core.net.AbstractSSLSocketAppender',
'ch.qos.logback.core.net.ObjectWriterFactory',
'ch.qos.logback.core.net.ObjectWriter',
'ch.qos.logback.core.net.AutoFlushingObjectWriter',
'ch.qos.logback.core.net.SyslogConstants',
'ch.qos.logback.core.net.server.ServerRunner',
'ch.qos.logback.core.net.server.Client',
'ch.qos.logback.core.net.server.ServerListener',
'ch.qos.logback.core.net.server.RemoteReceiverStreamClient',
'ch.qos.logback.core.net.server.AbstractServerSocketAppender',
'ch.qos.logback.core.net.server.ClientVisitor',
'ch.qos.logback.core.net.server.RemoteReceiverClient',
'ch.qos.logback.core.net.server.RemoteReceiverServerRunner',
'ch.qos.logback.core.net.server.SSLServerSocketAppenderBase',
'ch.qos.logback.core.net.server.ConcurrentServerRunner',
'ch.qos.logback.core.net.server.ServerSocketListener',
'ch.qos.logback.core.net.server.RemoteReceiverServerListener',
'ch.qos.logback.core.UnsynchronizedAppenderBase',
'ch.qos.logback.core.AsyncAppenderBase',
'ch.qos.logback.core.util.CloseUtil',
'ch.qos.logback.core.util.DatePatternToRegexUtil',
'ch.qos.logback.core.util.StatusListenerConfigHelper',
'ch.qos.logback.core.util.SystemInfo',
'ch.qos.logback.core.util.DefaultInvocationGate',
'ch.qos.logback.core.util.CachingDateFormatter',
'ch.qos.logback.core.util.InterruptUtil',
'ch.qos.logback.core.util.LocationUtil',
'ch.qos.logback.core.util.TimeUtil',
'ch.qos.logback.core.util.COWArrayList',
'ch.qos.logback.core.util.Loader',
'ch.qos.logback.core.util.CharSequenceState',
'ch.qos.logback.core.util.StatusPrinter',
'ch.qos.logback.core.util.Duration',
'ch.qos.logback.core.util.ContentTypeUtil',
'ch.qos.logback.core.util.FileUtil',
'ch.qos.logback.core.util.DynamicClassLoadingException',
'ch.qos.logback.core.util.InvocationGate',
'ch.qos.logback.core.util.OptionHelper',
'ch.qos.logback.core.util.IncompatibleClassException',
'ch.qos.logback.core.util.ExecutorServiceUtil',
'ch.qos.logback.core.util.StringCollectionUtil',
'ch.qos.logback.core.util.CharSequenceToRegexMapper',
'ch.qos.logback.core.util.FixedDelay',
'ch.qos.logback.core.util.FileSize',
'ch.qos.logback.core.util.DelayStrategy',
'ch.qos.logback.core.util.EnvUtil',
'ch.qos.logback.core.util.ContextUtil',
'ch.qos.logback.core.util.AggregationType',
'ch.qos.logback.core.util.PropertySetterException',
'ch.qos.logback.core.LifeCycleManager',
'ch.qos.logback.core.LayoutBase',
'ch.qos.logback.core.encoder.NonClosableInputStream',
'ch.qos.logback.core.encoder.Encoder',
'ch.qos.logback.core.encoder.ByteArrayUtil',
'ch.qos.logback.core.encoder.EncoderBase',
'ch.qos.logback.core.encoder.EchoEncoder',
'ch.qos.logback.core.encoder.LayoutWrappingEncoder',
'ch.qos.logback.core.recovery.RecoveryCoordinator',
'ch.qos.logback.core.recovery.ResilientOutputStreamBase',
'ch.qos.logback.core.recovery.ResilientSyslogOutputStream',
'ch.qos.logback.core.recovery.ResilientFileOutputStream',
'ch.qos.logback.core.AppenderBase',
'ch.qos.logback.core.subst.Node',
'ch.qos.logback.core.subst.Parser',
'ch.qos.logback.core.subst.Token',
'ch.qos.logback.core.subst.NodeToStringTransformer',
'ch.qos.logback.core.subst.Tokenizer',
'ch.qos.logback.core.FileAppender',
'ch.qos.logback.core.sift.AppenderFactory',
'ch.qos.logback.core.sift.SiftingAppenderBase',
'ch.qos.logback.core.sift.SiftingJoranConfiguratorBase',
'ch.qos.logback.core.sift.AbstractDiscriminator',
'ch.qos.logback.core.sift.Discriminator',
'ch.qos.logback.core.sift.AbstractAppenderFactoryUsingJoran',
'ch.qos.logback.core.sift.AppenderTracker',
'ch.qos.logback.core.sift.DefaultDiscriminator',
'ch.qos.logback.core.html.CssBuilder',
'ch.qos.logback.core.html.NOPThrowableRenderer',
'ch.qos.logback.core.html.HTMLLayoutBase',
'ch.qos.logback.core.html.IThrowableRenderer',
'ch.qos.logback.core.rolling.TriggeringPolicyBase',
'ch.qos.logback.core.rolling.helper.Compressor',
'ch.qos.logback.core.rolling.helper.PeriodicityType',
'ch.qos.logback.core.rolling.helper.TokenConverter',
'ch.qos.logback.core.rolling.helper.IntegerTokenConverter',
'ch.qos.logback.core.rolling.helper.CompressionMode',
'ch.qos.logback.core.rolling.helper.ArchiveRemover',
'ch.qos.logback.core.rolling.helper.FileFilterUtil',
'ch.qos.logback.core.rolling.helper.RenameUtil',
'ch.qos.logback.core.rolling.helper.DateTokenConverter',
'ch.qos.logback.core.rolling.helper.FileNamePattern',
'ch.qos.logback.core.rolling.helper.RollingCalendar',
'ch.qos.logback.core.rolling.helper.FileStoreUtil',
'ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover',
'ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover',
'ch.qos.logback.core.rolling.helper.MonoTypedConverter',
'ch.qos.logback.core.rolling.RollingPolicyBase',
'ch.qos.logback.core.rolling.RollingFileAppender',
'ch.qos.logback.core.rolling.FixedWindowRollingPolicy',
'ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicyBase',
'ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy',
'ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy',
'ch.qos.logback.core.rolling.RollingPolicy',
'ch.qos.logback.core.rolling.TimeBasedRollingPolicy',
'ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy',
'ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy',
'ch.qos.logback.core.rolling.RolloverFailure',
'ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP',
'ch.qos.logback.core.rolling.TriggeringPolicy',
'ch.qos.logback.core.pattern.ReplacingCompositeConverter',
'ch.qos.logback.core.pattern.ConverterUtil',
'ch.qos.logback.core.pattern.parser.Compiler',
'ch.qos.logback.core.pattern.parser.Node',
'ch.qos.logback.core.pattern.parser.Parser',
'ch.qos.logback.core.pattern.parser.Token',
'ch.qos.logback.core.pattern.parser.OptionTokenizer',
'ch.qos.logback.core.pattern.parser.TokenStream',
'ch.qos.logback.core.pattern.parser.CompositeNode',
'ch.qos.logback.core.pattern.parser.FormattingNode',
'ch.qos.logback.core.pattern.parser.SimpleKeywordNode',
'ch.qos.logback.core.pattern.Converter',
'ch.qos.logback.core.pattern.PatternLayoutEncoderBase',
'ch.qos.logback.core.pattern.LiteralConverter',
'ch.qos.logback.core.pattern.PostCompileProcessor',
'ch.qos.logback.core.pattern.util.RegularEscapeUtil',
'ch.qos.logback.core.pattern.util.AsIsEscapeUtil',
'ch.qos.logback.core.pattern.util.AlmostAsIsEscapeUtil',
'ch.qos.logback.core.pattern.util.IEscapeUtil',
'ch.qos.logback.core.pattern.util.RestrictedEscapeUtil',
'ch.qos.logback.core.pattern.SpacePadder',
'ch.qos.logback.core.pattern.CompositeConverter',
'ch.qos.logback.core.pattern.PatternLayoutBase',
'ch.qos.logback.core.pattern.DynamicConverter',
'ch.qos.logback.core.pattern.color.YellowCompositeConverter',
'ch.qos.logback.core.pattern.color.ANSIConstants',
'ch.qos.logback.core.pattern.color.BoldYellowCompositeConverter',
'ch.qos.logback.core.pattern.color.BoldBlueCompositeConverter',
'ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter',
'ch.qos.logback.core.pattern.color.CyanCompositeConverter',
'ch.qos.logback.core.pattern.color.MagentaCompositeConverter',
'ch.qos.logback.core.pattern.color.BlueCompositeConverter',
'ch.qos.logback.core.pattern.color.BlackCompositeConverter',
'ch.qos.logback.core.pattern.color.ForegroundCompositeConverterBase',
'ch.qos.logback.core.pattern.color.GrayCompositeConverter',
'ch.qos.logback.core.pattern.color.BoldMagentaCompositeConverter',
'ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter',
'ch.qos.logback.core.pattern.color.RedCompositeConverter',
'ch.qos.logback.core.pattern.color.BoldGreenCompositeConverter',
'ch.qos.logback.core.pattern.color.BoldRedCompositeConverter',
'ch.qos.logback.core.pattern.color.GreenCompositeConverter',
'ch.qos.logback.core.pattern.color.WhiteCompositeConverter',
'ch.qos.logback.core.pattern.FormattingConverter',
'ch.qos.logback.core.pattern.IdentityCompositeConverter',
'ch.qos.logback.core.pattern.FormatInfo',
'ch.qos.logback.core.OutputStreamAppender',
'ch.qos.logback.core.boolex.JaninoEventEvaluatorBase',
'ch.qos.logback.core.boolex.Matcher',
'ch.qos.logback.core.boolex.EventEvaluatorBase',
'ch.qos.logback.core.boolex.EvaluationException',
'ch.qos.logback.core.boolex.EventEvaluator',
'ch.qos.logback.core.read.CyclicBufferAppender',
'ch.qos.logback.core.read.ListAppender',
'ch.qos.logback.core.Context',
'ch.qos.logback.core.ContextBase',
'ch.qos.logback.core.status.StatusListenerAsList',
'ch.qos.logback.core.status.StatusBase',
'ch.qos.logback.core.status.NopStatusListener',
'ch.qos.logback.core.status.StatusUtil',
'ch.qos.logback.core.status.OnPrintStreamStatusListenerBase',
'ch.qos.logback.core.status.StatusManager',
'ch.qos.logback.core.status.ViewStatusMessagesServletBase',
'ch.qos.logback.core.status.ErrorStatus',
'ch.qos.logback.core.status.Status',
'ch.qos.logback.core.status.StatusListener',
'ch.qos.logback.core.status.InfoStatus',
'ch.qos.logback.core.status.OnConsoleStatusListener',
'ch.qos.logback.core.status.WarnStatus',
'ch.qos.logback.core.status.OnErrorConsoleStatusListener',
'ch.qos.logback.core.filter.EvaluatorFilter',
'ch.qos.logback.core.filter.Filter',
'ch.qos.logback.core.filter.AbstractMatcherFilter',
'ch.qos.logback.core.Layout',
'ch.qos.logback.classic.ViewStatusMessagesServlet',
'ch.qos.logback.classic.ClassicConstants',
'ch.qos.logback.classic.layout.TTLLLayout',
'ch.qos.logback.classic.helpers.MDCInsertingServletFilter',
'ch.qos.logback.classic.Level',
'ch.qos.logback.classic.Level.off',
'ch.qos.logback.classic.Level.error',
'ch.qos.logback.classic.Level.warn',
'ch.qos.logback.classic.Level.info',
'ch.qos.logback.classic.Level.debug',
'ch.qos.logback.classic.Level.trace',
'ch.qos.logback.classic.Level.all,',
'ch.qos.logback.classic.net.SSLSocketReceiver',
'ch.qos.logback.classic.net.ReceiverBase',
'ch.qos.logback.classic.net.SimpleSocketServer',
'ch.qos.logback.classic.net.SimpleSSLSocketServer',
'ch.qos.logback.classic.net.SocketNode',
'ch.qos.logback.classic.net.SMTPAppender',
'ch.qos.logback.classic.net.SocketReceiver',
'ch.qos.logback.classic.net.SocketAcceptor',
'ch.qos.logback.classic.net.SSLSocketAppender',
'ch.qos.logback.classic.net.LoggingEventPreSerializationTransformer',
'ch.qos.logback.classic.net.server.RemoteAppenderStreamClient',
'ch.qos.logback.classic.net.server.RemoteAppenderServerListener',
'ch.qos.logback.classic.net.server.SSLServerSocketAppender',
'ch.qos.logback.classic.net.server.RemoteAppenderClient',
'ch.qos.logback.classic.net.server.HardenedLoggingEventInputStream',
'ch.qos.logback.classic.net.server.ServerSocketAppender',
'ch.qos.logback.classic.net.server.SSLServerSocketReceiver',
'ch.qos.logback.classic.net.server.RemoteAppenderServerRunner',
'ch.qos.logback.classic.net.server.ServerSocketReceiver',
'ch.qos.logback.classic.net.SocketAppender',
'ch.qos.logback.classic.net.SyslogAppender',
'ch.qos.logback.classic.PatternLayout',
'ch.qos.logback.classic.util.ContextSelectorStaticBinder',
'ch.qos.logback.classic.util.StatusViaSLF4JLoggerFactory',
'ch.qos.logback.classic.util.JNDIUtil',
'ch.qos.logback.classic.util.LevelToSyslogSeverity',
'ch.qos.logback.classic.util.LoggerNameUtil',
'ch.qos.logback.classic.util.LogbackMDCAdapter',
'ch.qos.logback.classic.util.CopyOnInheritThreadLocal',
'ch.qos.logback.classic.util.ContextInitializer',
'ch.qos.logback.classic.util.EnvUtil',
'ch.qos.logback.classic.util.DefaultNestedComponentRules',
'ch.qos.logback.classic.AsyncAppender',
'ch.qos.logback.classic.jul.JULHelper',
'ch.qos.logback.classic.jul.LevelChangePropagator',
'ch.qos.logback.classic.encoder.PatternLayoutEncoder',
'ch.qos.logback.classic.db.names.DBNameResolver',
'ch.qos.logback.classic.db.names.ColumnName',
'ch.qos.logback.classic.db.names.TableName',
'ch.qos.logback.classic.db.names.DefaultDBNameResolver',
'ch.qos.logback.classic.db.names.SimpleDBNameResolver',
'ch.qos.logback.classic.log4j.XMLLayout',
'ch.qos.logback.classic.LoggerContext',
'ch.qos.logback.classic.turbo.TurboFilter',
'ch.qos.logback.classic.turbo.MDCFilter',
'ch.qos.logback.classic.turbo.ReconfigureOnChangeFilter',
'ch.qos.logback.classic.turbo.DuplicateMessageFilter',
'ch.qos.logback.classic.turbo.MarkerFilter',
'ch.qos.logback.classic.turbo.MDCValueLevelPair',
'ch.qos.logback.classic.turbo.DynamicThresholdFilter',
'ch.qos.logback.classic.turbo.MatchingFilter',
'ch.qos.logback.classic.turbo.LRUMessageCache',
'ch.qos.logback.classic.selector.servlet.LoggerContextFilter',
'ch.qos.logback.classic.selector.servlet.ContextDetachingSCL',
'ch.qos.logback.classic.selector.ContextJNDISelector',
'ch.qos.logback.classic.selector.DefaultContextSelector',
'ch.qos.logback.classic.selector.ContextSelector',
'ch.qos.logback.classic.sift.MDCBasedDiscriminator',
'ch.qos.logback.classic.sift.SiftingJoranConfigurator',
'ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator',
'ch.qos.logback.classic.sift.AppenderFactoryUsingJoran',
'ch.qos.logback.classic.sift.ContextBasedDiscriminator',
'ch.qos.logback.classic.sift.SiftingAppender',
'ch.qos.logback.classic.sift.SiftAction',
'ch.qos.logback.classic.html.UrlCssBuilder',
'ch.qos.logback.classic.html.HTMLLayout',
'ch.qos.logback.classic.html.DefaultCssBuilder',
'ch.qos.logback.classic.html.DefaultThrowableRenderer',
'ch.qos.logback.classic.Logger',
'ch.qos.logback.classic.pattern.ThrowableHandlingConverter',
'ch.qos.logback.classic.pattern.ContextNameConverter',
'ch.qos.logback.classic.pattern.LocalSequenceNumberConverter',
'ch.qos.logback.classic.pattern.ClassOfCallerConverter',
'ch.qos.logback.classic.pattern.PrefixCompositeConverter',
'ch.qos.logback.classic.pattern.LineOfCallerConverter',
'ch.qos.logback.classic.pattern.EnsureExceptionHandling',
'ch.qos.logback.classic.pattern.TargetLengthBasedClassNameAbbreviator',
'ch.qos.logback.classic.pattern.FileOfCallerConverter',
'ch.qos.logback.classic.pattern.LevelConverter',
'ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter',
'ch.qos.logback.classic.pattern.NamedConverter',
'ch.qos.logback.classic.pattern.ClassicConverter',
'ch.qos.logback.classic.pattern.NopThrowableInformationConverter',
'ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter',
'ch.qos.logback.classic.pattern.MethodOfCallerConverter',
'ch.qos.logback.classic.pattern.CallerDataConverter',
'ch.qos.logback.classic.pattern.ClassNameOnlyAbbreviator',
'ch.qos.logback.classic.pattern.MarkerConverter',
'ch.qos.logback.classic.pattern.RelativeTimeConverter',
'ch.qos.logback.classic.pattern.DateConverter',
'ch.qos.logback.classic.pattern.PropertyConverter',
'ch.qos.logback.classic.pattern.ThreadConverter',
'ch.qos.logback.classic.pattern.LineSeparatorConverter',
'ch.qos.logback.classic.pattern.MDCConverter',
'ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter',
'ch.qos.logback.classic.pattern.ThrowableProxyConverter',
'ch.qos.logback.classic.pattern.Abbreviator',
'ch.qos.logback.classic.pattern.Util',
'ch.qos.logback.classic.pattern.LoggerConverter',
'ch.qos.logback.classic.pattern.SyslogStartConverter',
'ch.qos.logback.classic.pattern.MessageConverter',
'ch.qos.logback.classic.gaffer.GafferUtil',
'ch.qos.logback.classic.boolex.OnMarkerEvaluator',
'ch.qos.logback.classic.boolex.JaninoEventEvaluator',
'ch.qos.logback.classic.boolex.OnErrorEvaluator',
'ch.qos.logback.classic.boolex.GEventEvaluator',
'ch.qos.logback.classic.boolex.IEvaluator',
'ch.qos.logback.classic.filter.ThresholdFilter',
'ch.qos.logback.classic.filter.LevelFilter',
'java.lang.System',
'java.lang.System.getenv',
'java.lang.System.getProperty'
]