Which can be prevented using the Null appender ;)
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" 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> <Null name="Null" /> </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> <Null name="Null" /> </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> <Null name="Null" /> </AppenderSet> </ScriptAppenderSelector> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="SelectConsole"/> <AppenderRef ref="SelectFile"/> <AppenderRef ref="SelectSMTP"/> </Root> </Loggers> </Configuration> Best regards, Behrang Saeedzadeh blog.behrang.org On Sun, Oct 27, 2019 at 11:28 AM Behrang Saeedzadeh <behran...@gmail.com> wrote: > 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 >>> >>>