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="log4j@example.com"
to="support@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 <behrangsa@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 <behrangsa@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="log4j@example.com"
>> to="support@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="log4j@example.com"
>> to="support@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.goers@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 <behrangsa@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="log4j@example.com"
>>> > to="support@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="log4j@example.com"
>>> > to="support@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
>>>
>>>
|