On a closer look, it seems that returning null causes a non-fatal error: 2019-10-27 11:26:36,898 main ERROR No node named null in org.apache.logging.log4j.core.appender.AppenderSet@71f67a79 2019-10-27 11:26:36,900 main ERROR Null object returned for ScriptAppenderSelector in Appenders. 2019-10-27 11:26:36,902 main ERROR Unable to locate appender "SelectSMTP" for logger config "root" 2019-10-27 11:26:37,057 main ERROR No node named null in org.apache.logging.log4j.core.appender.AppenderSet@48bfb884 2019-10-27 11:26:37,058 main ERROR Null object returned for ScriptAppenderSelector in Appenders. 2019-10-27 11:26:37,059 main ERROR Unable to locate appender "SelectSMTP" for logger config "root"
Best regards, Behrang Saeedzadeh blog.behrang.org On Sun, Oct 27, 2019 at 11:02 AM Behrang Saeedzadeh <behran...@gmail.com> wrote: > Hi Ralph, > > Thanks for the reply. That worked for me, but I have a couple of > suggestions: > > 1. > > In the documentation, it is not mentioned that the script can return > null to signal that none of the appenders in that block’s AppenderSet > should be selected. It is worthwhile to mention that in the docs. > 2. > > With how ScriptAppenderSelector is working now, the log configuration > becomes quite verbose: > > <?xml version="1.0" encoding="UTF-8"?><Configuration status="debug" > name="ScriptAppenderSelectorExample"> > <Appenders> > <ScriptAppenderSelector name="SelectConsole"> > <Script language="groovy"><![CDATA[ > if (System.getProperty("CONSOLE_APPENDER_ENABLED", > 'true').equalsIgnoreCase('true')) { > return "Console" > } else { > return null > } > ]]></Script> > <AppenderSet> > <Console name="Console" target="SYSTEM_OUT"> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level > %logger{36} - %msg%n"/> > </Console> > </AppenderSet> > </ScriptAppenderSelector> > > <ScriptAppenderSelector name="SelectFile"> > <Script language="groovy"><![CDATA[ > if (System.getProperty("FILE_APPENDER_ENABLED", > 'true').equalsIgnoreCase('true')) { > return "File" > } else { > return null > } > ]]></Script> > <AppenderSet> > <File name="File" fileName="application.log"> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level > %logger{36} - %msg%n" /> > </File> > </AppenderSet> > </ScriptAppenderSelector> > > <ScriptAppenderSelector name="SelectSMTP"> > <Script language="groovy"><![CDATA[ > if (System.getProperty("SMTP_APPENDER_ENABLED", > 'true').equalsIgnoreCase('true')) { > return "SMTP" > } else { > return null > } > ]]></Script> > <AppenderSet> > <SMTP name="SMTP" > subject="App: Error" > from="lo...@example.com" > to="supp...@example.com" > smtpHost="smtp.example.com" > smtpPort="25" > bufferSize="5"> > </SMTP> > </AppenderSet> > </ScriptAppenderSelector> > </Appenders> > <Loggers> > <Root level="info"> > <AppenderRef ref="SelectConsole"/> > </Root> > </Loggers></Configuration> > > If the script could return a list of appenders to be selected instead of > just one appender, the configuration would become more concise: > > <?xml version="1.0" encoding="UTF-8"?> > <Configuration status="debug" name="ScriptAppenderSelectorExample"> > <Appenders> > <ScriptAppenderSelector name="SelectMultiple"> > <Script language="groovy"><![CDATA[ > def selected = [] > > if (System.getProperty("CONSOLE_APPENDER_ENABLED", > 'true').equalsIgnoreCase('true')) { > selected.add("Console") > } > > if (System.getProperty("FILE_APPENDER_ENABLED", > 'true').equalsIgnoreCase('true')) { > selected.add("File") > } > > if (System.getProperty("SMTP_APPENDER_ENABLED", > 'true').equalsIgnoreCase('true')) { > selected.add("SMTP") > } > > return selected > ]]></Script> > <AppenderSet> > <Console name="Console" target="SYSTEM_OUT"> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level > %logger{36} - %msg%n"/> > </Console> > <File name="File" fileName="application.log"> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level > %logger{36} - %msg%n" /> > </File> > <SMTP name="SMTP" > subject="App: Error" > from="lo...@example.com" > to="supp...@example.com" > smtpHost="smtp.example.com" > smtpPort="25" > bufferSize="5"> > </SMTP> > </AppenderSet> > </ScriptAppenderSelector> > </Appenders> > <Loggers> > <Root level="info"> > <AppenderRef ref="SelectMultiple"/> > </Root> > </Loggers> > </Configuration> > > If that makes sense, I can work on a PR. > Best regards, > Behrang Saeedzadeh > blog.behrang.org > > > On Sun, Oct 27, 2019 at 3:21 AM Ralph Goers <ralph.go...@dslextreme.com> > wrote: > >> Take a look at the ScriptAppenderSelector - >> http://logging.apache.org/log4j/2.x/manual/appenders.html#ScriptAppenderSelector >> < >> http://logging.apache.org/log4j/2.x/manual/appenders.html#ScriptAppenderSelector> >> - and see if that does what you want. If not, please let us know. >> >> Ralph >> >> > On Oct 26, 2019, at 5:26 AM, Behrang Saeedzadeh <behran...@gmail.com> >> wrote: >> > >> > Let’s say I have three appenders: >> > >> > <?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN"> >> > <Appenders> >> > <Console name="Console" target="SYSTEM_OUT"> >> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level >> > %logger{36} - %msg%n"/> >> > </Console> >> > >> > <File name="File" fileName="application.log"> >> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level >> > %logger{36} - %msg%n" /> >> > </File> >> > >> > <SMTP name="SMTP" >> > subject="App: Error" >> > from="lo...@example.com" >> > to="supp...@example.com" >> > smtpHost="mailserver" >> > smtpPort="25" >> > bufferSize="100"> >> > </SMTP> >> > </Appenders></Configuration> >> > >> > I want to enable/disable these appenders using system properties in >> > different environments. >> > >> > One option is to control this using scripts: >> > >> > <?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN"> >> > <Scripts> >> > <Script name="isConsoleAppenderEnabled" >> language="groovy"><![CDATA[ >> > return System.getProperty("CONSOLE_APPENDER_ENABLED", >> > 'true').equalsIgnoreCase('true'); >> > ]]></Script> >> > >> > <Script name="isFileAppenderEnabled" language="groovy"><![CDATA[ >> > return System.getProperty("FILE_APPENDER_ENABLED", >> > 'true').equalsIgnoreCase('true'); >> > ]]></Script> >> > >> > <Script name="isSmtpAppenderEnabled" language="groovy"><![CDATA[ >> > return System.getProperty("SMTP_APPENDER_ENABLED", >> > 'true').equalsIgnoreCase('true'); >> > ]]></Script> >> > </Scripts> >> > >> > <Appenders> >> > <Console name="Console" target="SYSTEM_OUT"> >> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level >> > %logger{36} - %msg%n"/> >> > </Console> >> > >> > <File name="File" fileName="application.log"> >> > <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level >> > %logger{36} - %msg%n" /> >> > </File> >> > >> > <SMTP name="SMTP" >> > subject="App: Error" >> > from="lo...@example.com" >> > to="supp...@example.com" >> > smtpHost="smtp.example.com" >> > smtpPort="25" >> > bufferSize="5"> >> > </SMTP> >> > </Appenders> >> > >> > <Loggers> >> > <Root level="info"> >> > <AppenderRef ref="Console"> >> > <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY"> >> > <ScriptRef ref="isConsoleAppenderEnabled"/> >> > </ScriptFilter> >> > </AppenderRef> >> > >> > <AppenderRef ref="File"> >> > <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY"> >> > <ScriptRef ref="isFileAppenderEnabled"/> >> > </ScriptFilter> >> > </AppenderRef> >> > >> > <AppenderRef ref="SMTP"> >> > <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY"> >> > <ScriptRef ref="isSmtpAppenderEnabled"/> >> > </ScriptFilter> >> > </AppenderRef> >> > </Root> >> > </Loggers></Configuration> >> > >> > However, this doesn’t really disable the appender, but computes the >> value >> > of the script for each log event and based on that suppresses the event >> > from being sent to the appender. >> > >> > Another option is to write a custom appender that implements this logic >> and >> > that can decorate other appenders to achieve this behavior. >> > >> > But I was wondering if there’s already a built-in feature available that >> > can enable/disable appenders based on environment variables and/or >> system >> > properties? >> > >> > >> > Best regards, >> > Behrang Saeedzadeh >> > blog.behrang.org >> >>