What is the way to identify and enable logging for a library (for a class and at root level) - logback

I am using scalardb library. I want to enable logging in it.
I believe the way to enable logging is to add a line similar to <logger name="classnameinclduingpackage" level="DEBUG" additivity="false"> <appender-ref ref="FILE"/> </logger> in logback.xml.
I can see that Scalardb support Sl4J and some of its classes use the logger. - https://github.com/scalar-labs/scalardb/tree/master/src/main/java/com/scalar/db/transaction/consensuscommit
Question 1
If I want to enable logging for each class, would I have to add, for example, the following entry in logback.xml?
<logger name="com.scalar.db.transaction.consensuscommit.CommitHandler" level="ALL" additivity="false"> <appender-ref ref="STDOUT"/> </logger>
Adding each class like this would take a lot of time and I might miss some classes. Is there a way to provide a selector that would enable logging in all classes?
Would this work?
Is this the right way?

Related

Playspec not picking logger configuration

In my play application, I have provided a logback.xml. The configuration for controller AnswerController is <logger name="controllers.AnswerController" level="TRACE" additivity="false">
<appender-ref ref="STDOUT"/> </logger>
But when I run my test case, I don't see any logs. Do I need to configure logback explicitly? I am using custom application loader.
Why are the logs now showing?
I added the LoggerConfigurator to my code and it seem to work (still early day to confirm if this will create some side effect. Though I don't the flow of why this makes things work (BTW, I do the same for my customer application loader as well)
class AnswerControllerUnitSpec extends PlaySpec with BeforeAndAfterAll with BeforeAndAfterEach with OneAppPerSuiteWithComponents{
override def beforeEach() = {
println("------------new test -----------------")
}
LoggerConfigurator(context.environment.classLoader).foreach {
_.configure(context.environment, context.initialConfiguration, Map.empty)
}
...
}

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.

How to configure logback for package?

Is it possible to configure logback to log at e.g. WARN or INFO level for all packages but x.y? And then separate configuration for package x.y only.
I don't know of any way you can get the "NOT" package aspect of your question, but I routinely log one package at DEBUG and all the rest at INFO and...above is it...WARN and ERROR. This is straight up-the-middle logback. My loggers are all like...
package rekdev.org.service.api;
public class DefaultConfigResource {
// ...
private static final Logger log = LoggerFactory.getLogger( DefaultConfigResource.class );
// ...
}
...on a logback.xml configuration like...
<logger name="rekdev.org.service.api" level="debug" />
...
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="DAILY_ROLLING" />
<appender-ref ref="SYSLOG" />
</root>
Has the effect of most output popping out at INFO, WARN, ERROR but all the rekdev.org.service.api classes. All the classes in the rekdev.org.service.api package produce output at DEBUG, INFO, WARN, ERROR.
Or did I misunderstand your questions entirely?

log4net logger configuration

Is it possible to set the logger from configuration. I have a web app
using a framework. The framework is extensible and has the logger.
When I log, currently, the logger is set to the framework class.
Is it possible that I can configure my web app and set the logger for the web app to
loggerForWebApp and the logger for a console app (which is using the
same framework) to loggerForConsoleApp?
In addition to the root logger (which must always be there) you can have named loggers with their own appender-refs and levels.
For instance, you could have something like this:
<root>
....
</root>
<logger name="loggerForWebApp">
<level value="WARN" />
<appender-ref ... />
</logger>
<logger name="loggerForConsoleApp">
<level value="WARN" />
<appender-ref ... />
</logger>
In code, you would summon these loggers by their name:
var log = LogManager.GetLogger("loggerForWebApp");
Most definitely, and this is one of the great things about log4net: it can log out to a wide range of loggers.
For examples of the appenders, see here. Probably the most common one in use is the RollingFileAppender, but the ConsoleAppender can be very handy for console applications. Alternatively the TraceAppender can write out to the standard .NET trace listeners for further redirection (or display in the debug Output window in Visual Studio).
To create your own, implement IAppender.
details to follow