How do i define some variables in logback.xml and be able to use that variable in my java code? - logback

So, I am making a custom appender and i want elasticsearch url and index pattern to be saved in logback.xml and somehow get that value in my java code and i also want to be able to override it if i want in my append() function. I am using maven for my project if that helps.
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n</pattern>
</encoder>
</appender>
<appender name="myappender" class="esappender.EsAppender">
<m_elasticSearchUrl>http://xxx.xxx.xxx.x:xxxx</m_elasticSearchUrl>
<m_elasticSearchIndex>output-%d{yyyy-MM-dd}</m_elasticSearchIndex>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n</pattern>
</encoder>
</appender>
<logger name="esappender" level="debug" />
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="myappender" />
</root>
</configuration>
I thought directly metioning it in the tags will work and i could use it in my java code but it doesn't seem to work. When i search the internet i only find variables referenced in the logback itself but i want to be able to refrence it from append() function.

Related

Cleaning old log files with logback

I am using logback to configure logs in my application. I have SiftingAppender which creates logs per each job run. I need to automatically clean log files which are 2 weeks old. I tried to use RollingAppender, but it does not work since each log file name has unique job run id. Is there any other default logback configuration which might work for my use case? Thanks you for the help!
<appender name="JOB_RUN" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- This is MDC value -->
<!-- We will assign a value to 'jobRunId' via Java code -->
<discriminator>
<key>jobRunId</key>
<defaultValue>null</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${jobRunId}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/${jobRunId}.log</file>
<prudent>true</prudent>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%level] [%logger{60}] - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logs/${jobRunId}.log.%d{yyyy-MM-dd}</fileNamePattern>
<!-- keep 14 days of history -->
<maxHistory>14</maxHistory>
</rollingPolicy>
</appender>
</sift>

Gatling not logging request/response

Gatling is not logging anything (errors, request body, response body etc) even though I am using default logback.xml. Does anyone know what is missing?
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
<immediateFlush>false</immediateFlush>
</encoder>
</appender>
<!-- Uncomment for logging ALL HTTP request and responses -->
<logger name="io.gatling.http.ahc" level="TRACE" />
<logger name="io.gatling.http.response" level="TRACE" />
<!-- Uncomment for logging ONLY FAILED HTTP request and responses -->
<!-- <logger name="io.gatling.http.ahc" level="DEBUG" /> -->
<!-- <logger name="io.gatling.http.response" level="DEBUG" /> -->
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
Question was answered on the Gatling mailing list.
This issue is that CyberNinja has 2 slf4j implementation in his classpath (the logback Gatling provides plus one he added himself) so it fails to start.
And as he also configured a NopStatusListener (which is not here in Gatling's standard logback.xml file), slf4j fails silently.
Please try to add
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>

Logback - possible to get AsyncAppender's current queue's size?

Is it possible to get Logback's AsyncAppender's current queue size?
Here's the relevant section of our config:
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1000</queueSize>
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="FILE" />
</appender>

conditions in logback configuration

I'm trying to remove redundant logback config files by using janino's conditional processing.
Below is the conditional logic which I had added
<root level="INFO">
<appender-ref ref="ROLLING" />
<!-- use console appender on windows, email appender on linux -->
<if condition='property("os.name").contains("win")'>
<then>
<appender-ref ref="CONSOLE" />
</then>
<else>
<appender-ref ref="EMAIL" />
</else>
</if>
</root>
but this throws the below errors
12:30:34,877 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#90:55 - no applicable action for [if], current pattern is [[configuration][root][if]]
12:30:34,877 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#91:10 - no applicable action for [then], current pattern is [[configuration][root][if][then]]
12:30:34,877 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#92:35 - no applicable action for [appender-ref], current pattern is [[configuration][root][if][then][appender-ref]]
12:30:34,877 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#94:10 - no applicable action for [else], current pattern is [[configuration][root][if][else]]
12:30:34,877 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#95:35 - no applicable action for [appender-ref], current pattern is [[configuration][root][if][else][appender-ref]]
The configuration works fine if I remove the conditional logic and use something like
<root level="INFO">
<appender-ref ref="ROLLING" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="EMAIL" />
</root>
How can I configure this correctly in such a way that the CONSOLE appender is used only on Windows and the EMAIL appender everywhere else?
Can you try the latest version? I used the latest version and the above conditional statements work perfectly fine

LoggingFacility - controlling the logger that will be used

I'm using Log4Net with Castle.Windsor, the LoggingFacility, and Log4netIntegration. The project I'm using this in involves NHibernate, which also talks to log4net.
What I'm trying to do is split the logs such that NHibernate ends up in one log (data-log.txt), while all the system logging ends up in a separate log (system-log.txt).
The problem I'm having is that it seems like the Logger injected by windsor will only write to the root logger in my log4net configuration. NHibernate looks for loggers named NHibernate or Nhibernate., so I'm able to divert those logs into the data-log.txt appender, but it also writes to the root logger.
So what I've got right now is logs from Windsor and NHibernate all end up with the root logger, and logs from NHibernate additionally end up at the nhibernate specific loggers.
Here is my log4net config section in my app.config:
<log4net xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/log4net.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline"/>
</layout>
</appender>
<appender name="AspNetTraceAppender" type="log4net.Appender.AspNetTraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
</layout>
</appender>
<appender name="NHibernateLogAppender" type="log4net.Appender.RollingFileAppender">
<file value="data-log.txt" />
<!-- various stuff -->
</appender>
<appender name="SystemLogAppender" type="log4net.Appender.RollingFileAppender">
<file value="system-log.txt" />
<!-- various stuff -->
</appender>
<root>
<level value="ALL" />
<appender-ref ref="AspNetTraceAppender" />
<appender-ref ref="Console" />
</root>
<logger name="SystemLogger">
<level value="ALL" />
<appender-ref ref="SystemLogAppender" />
</logger>
<logger name="NHibernate">
<level value="WARN" />
<appender-ref ref="NHibernateLogAppender" />
</logger>
<logger name="NHibernate.SQL">
<level value="DEBUG" />
<appender-ref ref="NHibernateLogAppender"/>
</logger>
and windsor is getting configured by code like so
container.AddFacility<LoggingFacility>(f => f.UseLog4Net().WithAppConfig());
How do I tell Windsor to aim for the SystemLogger instead of the root?
I know one way to do this is by creating a specific logger for each type that wants to use logging, but that seems like a great way to shoot yourself in the foot when you forget about that later.
Have just the root logger with all appenders. Then use appender whitelist and blacklist filtering on logger name:
<appender name="NHibernateLogAppender" type="log4net.Appender.RollingFileAppender">
<file value="data-log.txt" />
<!-- various stuff -->
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="NHibernate" />
</filter>
</appender>
<appender name="SystemLogAppender" type="log4net.Appender.RollingFileAppender">
<file value="system-log.txt" />
<!-- various stuff -->
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="NHibernate" />
<acceptOnMatch value="false" />
</filter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="NHibernateLogAppender" />
<appender-ref ref="SystemLogAppender" />
</root>
Another route: I've submitted a patch to the Castle.Windsor team that allows users to specify a log name to use.
If you pull and build Windsor from github, LoggingFacility now has a configuration method ToLog(string LogName) that allows you to control which log will be used.