self4g logback two logger in same class not working - java

i use slf4j+logback
Here is logback.xml with 3 appenders (1 - console, 2 different files)
`
<configuration>
<property name="LOG_HOME" value="D:/logs" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- <file>D:/logs/all/all_log.txt</file>-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_HOME}/all/all_log.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<appender name="CONNECT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<file>D:/logs/connect/connect_log.txt</file>-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_HOME}/connect/connect_log.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<!--<logger name="connect" level="info" additivity="false">
<appender-ref ref="CONNECT_FILE"/>
</logger>-->
<logger name = "com" level="info">
<appender-ref ref="FILE"/>
</logger>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
`
and simple class:
package com.gitHub.xMIFx.Servlets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by bukatinvv on 25.05.2015.
*/
#WebServlet("/main.do")
public class MainController extends HttpServlet{
private static final String PAGE_OK = "pages/main.jsp";
private static final Logger lOGGER = LoggerFactory.getLogger(MainController.class.getName());
private static final Logger CONNECT_FILE_lOGGER = LoggerFactory.getLogger("connect");
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp){
req.setAttribute("User","Vlad");
try {
lOGGER.info("logger: forwarding");
CONNECT_FILE_lOGGER.info("Connect-logger: forwarding");
// if(true){throw new IOException("blad");}
req.getRequestDispatcher(PAGE_OK).forward(req,resp);
} catch (ServletException e) {
lOGGER.error("Exception", e);
} catch (IOException e) {
lOGGER.error("Exception", e);
}
}
}
lOGGER & CONNECT_FILE_lOGGER write info in the same file, so they are the same loggers.
Why when we calling LoggerFactory.getLogger("connect"); we get logger with name "com", even when logger with name "connect" is not commented.
I try this, but had the same situation.
logs from file all_log.2015-05-28.log:
4968 [http-nio-8081-exec-5] INFO c.g.xMIFx.Servlets.MainController - logger: forwarding
4968 [http-nio-8081-exec-5] INFO connect - Connect-logger: forwarding

Interestingly, logback will create a logger even if you have no logger declared with the name you pass to LoggerFactory. Therefore:
When 'connect' was commented out CONNECT_FILE_lOGGER was a ROOT child logger which also logged to the console.
By uncommenting 'connect' you created a logger which appended to the desired file. As the additivity flag is false, any message logged to it is not propagated to its parents.

Sorry, I don't know what was that. But when I added additivity="false" to the logger with name "com" it works. Then I returned it back and uncommented "connect" - now it all works fine.

Related

Logback NOT writing in log.txt

Problem Statement: Logback is printing in console properly but not in log.txt file. There are many solutions given in other pages but apparently none worked. Could someone help me in this regard?
Java:-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger("Example App");
logger.info("'sup? I'm your info logger");
logger.debug("hey HEY hey! I'm your debug logger");
}
}
Config:- logback-fileAppender.xml
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${project.basedir}/Log.txt</file>
<append>true</append>
<!-- set immediateFlush to false for much higher logging throughput -->
<immediateFlush>true</immediateFlush>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Expected:- The logs should be printed in log.txt
Actual:- The logs is not printed in log.txt
Note: I am using my customized directory structure in maven not the default provided by maven "src/main/resources".

logs doesn't getting printed using Logback using ConsoleAppender

I wrote a simple program in which I am using Logback. My intention was to use ASYNS which internally will use STDOUT.
Here is the Java code listing:
package com.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogBackMainApp {
private static final Logger LOGGER =
LoggerFactory.getLogger(LogBackMainApp.class);
public static void main(String[] args) throws InterruptedException {
LOGGER.info("Hello world");
LOGGER.info("Hello world again");
Thread.sleep(5000);
}
}
The below is the configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" >
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- %d{yyyy-MM-dd HH:mm:ss.SSS} %thread %-5level %logger{0}:%L
If you required class name ,enable %logger{0}:%L -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %thread %-5level - %msg
%n</pattern>
</encoder>
</appender>
<appender name="ASYNC-STDOUT" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1</queueSize>
<discardingThreshold>20</discardingThreshold>
<neverBlock>true</neverBlock>
<appender-ref ref="STDOUT" />
</appender>
<root level="INFO">
<appender-ref ref="ASYNC-STDOUT" />
</root>
I am defining root logger which would cater to my com.example package, and it refers to ASYNC-STDOUT, which internally uses ch.qos.logback.core.ConsoleAppender.
As per my current understanding, it should be able to log to console. However, nothing is coming. Is there something wrong in my code or configuration OR do i miss to understand the concept altogether.
If you use maven have a look: Dependency management for SLF4J and Logback. Maybe you're missing a required dependency. Sl4j is only an abstraction for you're real logger implementation which has to be added as dependency.

Logback Dynamic Files using Two Properties

my problem is : My application maintains three buildings, and each building has a different process.
So, using logback, I want to create a log which has a specification :
each building will have a specific folder, and inside that specific folder of each building, there will be many log files, with each log file indicates a process.
My logback.xml right now is :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="logAppender" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>processName</key>
<defaultValue>unknown</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${processName}"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/${distributor}/${processName}.log</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
</layout>
<rollingPolicy
class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/${distributor}/${processName}.%i.log</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5KB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> -->
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</triggeringPolicy>
</appender>
</sift>
</appender>
<logger name="processLog" level="debug" additivity="false">
<appender-ref ref="logAppender" />
<appender-ref ref="stdout" />
</logger>
<root level="debug">
<appender-ref ref="stdout" />
<appender-ref ref="logAppender" />
</root>
</configuration>
And my java servlet code is :
public class DistributorServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger processLog = LoggerFactory.getLogger("processLog");
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String office = req.getParameter("office");
MDC.put("distributor", office);
String process = req.getParameter("process");
MDC.put("process", process);
processLog.debug("Processing");
}
}
However, a log file is not generated.
Can anyone help me?
Thank you very much
1. Make the below change
private static Logger processLog = LoggerFactory.getLogger("processLog");
to
private static Logger processLog = LoggerFactory.getLogger(DistributorServlet .class);
2. Add additional discriminator for distributor
From the logback.xml it appears that only one discriminator has been added. Did you try adding another one for distributor
3. Do not forget
To add MDC.remove("keyName"); after its usage.
4. In case if you observe issue with multiple MDC keys
I faced an issue with the MDC.put in trying to add multiple keys into it. (I wondered why no putAll has been defined)
Although the underlying implementation is that of a HashMap<Key k, Value v> that should allow adding multiple keys, I was only able to see that the last key you put into MDC would be applied to logback.xml
While for the other keys I observed _IS_UNDEFINED value that gets appended instead.
Of course then again you can refer to the other various links and although this may not be a best idea, here is what I have done in my Java code,
System.setProperty("distributor", req.getParameter("office"));
System.setProperty("process", req.getParameter("process"));
Modify the logback.xml by removing discriminator. Well, alternatively you can remove one of the above properties and have the MDC.put for that property.
However please do refer to the links System.setProperty is safe in java?
Alternatively I suggest https://stackoverflow.com/a/32615172/3838328

Make logback pattern part optional?

Is it possible to make parts of logbacks pattern layout depending on an attribute?
e.g. show bdid (...) just in the case when %X{bdid} exists?
This appender
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>bdid\(%X{bdid}\) - %d{HH:mm:ss.SSS} %msg%n</pattern>
</encoder>
</appender>
prints
bdid(0b5d3877-f3dd-4189-8b1b-489c8b617f2a) 18:22:25.206 if bdid exists, but prints
bdid() 18:22:20.928 if it doesn't.
How do I omit the empty bdid() in my log?
You can use the replace function, details are in the docs here. A working example is the following:
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%replace(bdid\(%X{bdid}\)){'bdid\(\)', ''} - %d{HH:mm:ss.SSS} %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Test Function
public class PatternTest
{
#Test
public void test()
{
Logger logger = LoggerFactory.getLogger(PatternTest.class);
MDC.put("bdid", "hola");
logger.info("Check enclosed.");
MDC.remove("bdid");
logger.info("Check enclosed.");
}
}
Test output
bdid(hola) - 18:40:40.233 Check enclosed.
- 18:40:40.234 Check enclosed.

How to hide the output of a single Logback logger?

I use logback in the following case
package ninja.template;
public class TemplateEngineManagerImpl implements TemplateEngineManager {
private final Logger logger = LoggerFactory.getLogger(TemplateEngineManagerImpl.class);
...
logger.info("Registered response template engines");
...
and I want to hide all the INFO output of this TemplateEngineManagerImpl class (or all the output - the class only logs at INFO level) but this class only.
Unfortunately, the following configuration doesn't work as I can still see "Registered response template engines" in my console output.
<configuration>
<appender name="STDOUT_TERSE" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern> | %msg%n</pattern>
</encoder>
</appender>
<logger name="ninja.template.TemplateEngineManagerImpl" level="OFF"/>
<root level="info">
<appender-ref ref="STDOUT_TERSE" />
</root>
</configuration>
note I tried also the following without results
<logger name="ninja.template.TemplateEngineManagerImpl" level="WARN"/>
and
<logger name="ninja.template" level="WARN"/>
and
<logger name="TemplateEngineManagerImpl" level="WARN"/>
The provided logback configuration works
<logger name="ninja.bodyparser.BodyParserEngineManagerImpl" level="WARN" additive="false"/>
The error I had that the string was logged in two different places.
So by displaying the full logger name with the following configuration:
<appender name="STDOUT_TERSE" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern> | %logger | %msg%n</pattern>
</encoder>
I was able to copy and paste the string that should be used as the logger name!

Categories

Resources