I'm trying to setup access-logs in micronaut, but, as logback-access library uses a servlet filter, I don't see a straight-forward way to do it.
Is there a different solution? Some hidden Micronaut config or a trustable adapter of the filter (A Micronaut Filter wrapper for Servlet filters would be great)
The Micronaut http server supports automatically adding a LoggingHandler, you have to supply micronaut.server.netty.logLevel: <<level>> in your configuration where level is one of TRACE, DEBUG, INFO, WARN, ERROR. I don't know if that will provide the same detail that logback-access does, but you can give it a try.
EDIT: Be sure to also configure a logger. For example in logback:
<logger name="io.netty.handler.logging" level="TRACE"/>
I used the mn CLI to create my application (using groovy as the language for my development), and mn code generated a trivial logback.xml. from the 1st time I ran my application, logging was working.
Here's what was generated OOTB:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Then I went to the logback home page and used its code generator to convert the mn seed xml file to logback.groovy.
here's the result, after I added my logger for the hello.world package.
// ----------------------------------------------------------
//
// Built on Sun Jul 07 02:41:38 CEST 2019 by logback-translator
// For more information on configuration files in Groovy
// please see http://logback.qos.ch/manual/groovy.html
// For assistance related to this tool or configuration files
// in general, please contact the logback user mailing list at
// http://qos.ch/mailman/listinfo/logback-user
// For professional support please see
// http://www.qos.ch/shop/products/professionalSupport
// ----------------------------------------------------------
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import static ch.qos.logback.classic.Level.DEBUG
appender("STDOUT", ConsoleAppender) {
withJansi = true
encoder(PatternLayoutEncoder) {
pattern = "%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n"
}
}
root(INFO, ["STDOUT"])
logger("hello.world", DEBUG)
When I use logback as logging framework, I add logger configuration on runtime for debugging. For example set "org.springframework" to debug level.
after I find the data I need I want to remove this configuration without restarting the application.
How can I do that?
You have two options depending upon how you want to modify the log level.
First option - using logback.xml
Logback xml provides an option to periodically scan the configuration. By setting that, you ask the logger framework to periodically update its in-memory setting to sync with the XML configuration. When you want to enable debug mode, XML configuration will look as below:
<configuration scan="true" scanPeriod="30 seconds">
<!-- Appender configurations here -->
<logger name="org.springframework" level="debug" additivity="false">
<appender-ref ref="YOUR_APPENDER_NAME"/>
</logger>
<!-- Other logger configurations (including root) go here -->
</configuration>
After you complete your task, you can either delete that logger entry or set the level to ERROR to stop logging for that package.
Second option - In-memory
If you don't want to touch your logback.xml, but somehow handle it in runtime (say, using some REST APIs of you application), you may get the specific logger instance and set the level to DEBUG. Once you complete your activity, you may set the level to 'null' so that the level is inherited from the parent. Sample code will be as below:
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import org.slf4j.LoggerFactory;
.....
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = context.getLogger("org.springframework");
logger.setLevel((Level.toLevel("DEBUG"));
// Do your task
logger.setLevel(null); // When we do this, level will be inherited from parent.
logback has an option that allows periodic rescanning of the configuration file to look for changes.
<configuration scan="true">
...
</configuration>
I created a custom layout (as shown in Chapter 6: Layouts, http://logback.qos.ch/manual/layouts.html), so do I have to patch logback, or there is a configurable way to let logback knows about my custom layout class?
Thank you.
You can reference your layout in logback.xml by using the full namespace of your custom layout. So if your layout is at com.mydomain.logback.layouts.MyCustomLayout then in your logback.xml, you'd have an appender definition that looks something like this:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="com.mydomain.logback.layouts.MyCustomLayout" />
</appender>
Now every time a log event gets passed through the STDOUT appender, it will be processed by your custom appender. No need to recompile Logback.
This seems like a carelessness error, but I can't seem to find the cause. Logging with logback/slf4j (most recent version slf4j-api-1.6.1, logback core/classic 0.9.24). Simplest log configuration for testing is:
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<!-- DONT USE THIS FORMATTER FOR LIVE LOGGING THE %L LINE NUMBER OUTPUTTER IS SLOW -->
<pattern>%le %-1r [%c{1}:%L] %m%n</pattern>
</layout>
</appender>
<root level="DEBUG">
<appender-ref ref="stdout" />
</root>
</configuration>
Every log setup starts with logback's internal status lines:
11:21:27,825 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:21:27,826 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:.../logback-test.xml]
11:21:28,116 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
11:21:28,124 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:21:28,129 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [stdout]
11:21:28,180 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Pushing component [layout] on top of the object stack.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:21:28,207 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
11:21:28,207 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [stdout] to Logger[ROOT]
which is, according to the docs, the format logback uses for default. It then finishes reading the config (which is set up to output a different format) and continues with the properly formatted output. There's a config parameter <configuration debug="false"> which does not affect this.
Anyone know how to shut this off?
If you set the debug attribute of the configuration element to true, you will get all status information to the console. If this is your problem, just set it to false or remove it.
If you have any configuration problems of level WARN or above, you will also get all status information logged to the console (including messages of level INFO). The best solution to this problem is to fix the problem (in your case replace the <layout> element with an <encoder> element).
If you for some reason cannot fix the problem, but want to remove the status-information from the console, you can instead configure an alternative StatusListener. Use the NopStatusListener to completely remove the status-information:
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<!-- etc -->
</configuration>
As described in the docs, if warnings or errors occur during the parsing of the configuration file, logback will automatically print status data on the console.
Follow http://logback.qos.ch/codes.html#layoutInsteadOfEncoder i.e.
the link mentioned by logback in its warning message. Once you follow the steps mentioned therein, that is, if you replace <layout> element with <encoder>, logback will stop printing messages on the console.
Ceki answer is correct:
(...)if warnings or errors occur during the parsing of the configuration file, logback will automatically print status data on the console.
Once you get it right, there won't be any pollution in the first lines of your log anymore.
As of March 2015, in Logback 1.1.2, you need to use <encoder> sub-component - <layout> is now deprecated and if use it, error messages will appear. You cannot control this, it´s Logback default behavior.
Some internal classes have been renamed too, and even the examples in their manual page are outdated!
Here is the code snippet from their Errors Code Help page, which has the correct way to config the logger. This fixed the issue completely in my project.
http://logback.qos.ch/codes.html#layoutInsteadOfEncoder
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
...
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%msg%n</pattern>
</encoder>
</appender>
I had the same problem i added this line
<!-- Stop output INFO at start -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
in the logback and it succefully worked
I realized Steve found the fix but he didn't mention it on the thread. In case if any other person hit the same issue here is the fix.
Replace "<layout>" elements with "<encoder>..</encoder>"
The culprit is:
<layout class="ch.qos.logback.classic.PatternLayout">
I prefer to use status listener in order to switch off own logback logs:
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
...
</configuration>
But as was mentioned NopStatusListener also prevents showing warning and errors. So you can write your custom status listener and change log level for it manually:
package com.your.package;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status;
import java.util.List;
public class PrintOnlyWarningLogbackStatusListener extends OnConsoleStatusListener {
private static final int LOG_LEVEL = Status.WARN;
#Override
public void addStatusEvent(Status status) {
if (status.getLevel() == LOG_LEVEL) {
super.addStatusEvent(status);
}
}
#Override
public void start() {
final List<Status> statuses = context.getStatusManager().getCopyOfStatusList();
for (Status status : statuses) {
if (status.getLevel() == LOG_LEVEL) {
super.start();
}
}
}
}
Then use it in your logback.xml file:
<configuration>
<statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
...
</configuration>
Struggled with the same problem myself i.e. there were a bunch of lines logged right at the beginning which were not related to my code. Here is how I fixed it.
<configuration debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level
%logger{36} - %msg%n</pattern> </encoder> -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<root level="error">
<appender-ref ref="STDOUT" />
</root>
<logger name="fun.n.games" level="DEBUG" />
This is running with the following entry in the pom.xml
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
This seems to be Fixed in 0.9.29. Just made several tests. No Joran INFO anymore. I guess this is the fixing commit.
I've tried everything and nothing worked for me. My problem was due to multiple logback.xml files in my classpath. This is the common case in multi modular projects.
When there is only one logback.xml file in classpath, there is no ambiguity and the problem is solved.
Using the logback.groovy: statusListener(NopStatusListener) (in the src/test/resources/logback.groovy) works.
(A valid use case is e.g. if working with ANT in Eclipse, using logback logging, groovy classes and unit tests where the unit tests take the src/test/resources/logback.groovy, but will also see the src/main/resources/logback.groovy (or similar) you cannot exclude (if ANT's classpath is said to use the projects classpath).)
Just for people landing here because of the status messages logged by ch.qos.logback.access.tomcat.LogbackValve#LogbackValve (recent versions). Just set the quiet flag:
var v = new LogbackValve();
v.setQuiet(true); // disable status messages!
v.setFilename("logback-access.xml");
See also the documentation for XML configuration.
I have some trouble.
My application could be divided to 3 logical parts (import, processing and export). There are some parts of code which are used in several parts of my application. How can I determine which part of code called my log4net object?
What is best practice to log info in parts of code which are called from several places in the application?
I want to turn on and off the ability to log parts of my application from a config file.
If I turn off logging for the processing part of my app, how could I log info in the export part of my app when both of them use one method, in which I initialize my logger object?
You could add a separate logger for each section of your app that you want to log and then turn them off and on as needed. They would all be independent from one another and this can all be setup via the config.
By setting the additivity property to false, the loggers will all be independent of one another. Here's an example of the config portion:
<logger name="Logger1" additivity="false">
<level value="INFO" />
<appender-ref ref="Logger1File" />
</logger>
To use it in your code, reference it like this:
private static ILog _Logger1= LogManager.GetLogger("Logger1");
Anything you log to Logger1 will be separate from any other logger, including the root one.
log4net provides contexts for this purpose. I would suggest using a context stack like this:
using(log4net.ThreadContext.Stacks["Part"].Push("Import"))
log.Info("Message during importing");
using(log4net.ThreadContext.Stacks["Part"].Push("Processing"))
log.Info("Message during processing");
using(log4net.ThreadContext.Stacks["Part"].Push("Export"))
log.Info("Message during exporting");
The value on the stack can be shown in the logs by including %property{Part} in a PatternLayout.