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

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>

Related

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

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.

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>

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

logback - remapping a log level for a specific logger

I have a logback configuration that has an appender with a threshold filter:
<appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
...
</appender>
This ensures that only info and higher (warn, error) get logged to syslog. However, one of the 3rd party libraries we use is logging a particular event at DEBUG, and I would like to log this event to syslog. The first approach I had in mind was to try remap the log level in the logger, but am not sure if this is possible? Something like:
<logger name="akka.some.Thing" level="DEBUG" logAs="INFO">
<appender-ref ref="SYSLOG" />
</logger>
obviously, the "logAs" parameter doesn't exist, so I can't do that. What would be the best approach to logging akka.some.Thing to the SYSLOG appender while leaving the filter in place for other loggers?
The other approach would be to create a 2nd appender called SYSLOG2 that doesn't have the filter in place and set the specific logger to use that, but was wondering if there was a way to configure logback with just 1 SYSLOG appender...
Thanks,
I know this is an old question - but it is actually possible to do what the OP wants to do with a single SyslogAppender.
If others are searching for an example of how to remap you can take a look at the org.springframework.boot.logging.logback.LevelRemappingAppender class.
With that appender it is possible to both remap what appender is finally used for the log event, and it is also possible to remap the level that is used for the final log event - e.g. by changing a DEBUG level into an INFO level.
Usage example in logback config file (taken from https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml):
<appender name="DEBUG_LEVEL_REMAPPER" class="org.springframework.boot.logging.logback.LevelRemappingAppender">
<!-- Optional: specify the destination logger the event ends up in -->
<destinationLogger>org.springframework.boot</destinationLogger>
<!-- Optional: specify log level remapping -->
<remapLevels>INFO->DEBUG,ERROR->WARN</remapLevels>
</appender>
<logger name="org.thymeleaf" additivity="false">
<appender-ref ref="DEBUG_LEVEL_REMAPPER"/>
</logger>
Note that remapping to a specific destination logger can make it harder to find the source code of the original log event - so use it with care.
What you can do, is writing a second logger + appender with the same output:
<appender name="SYSLOG-2" class="ch.qos.logback.classic.net.SyslogAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
...
</appender>
<logger name="akka.some.Thing" level="DEBUG">
<appender-ref ref="SYSLOG-2" />
</logger>
This will add your specific DEBUG tasks to the same output.

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.