[logback-user] Migrating from Log4j
Ligaya Cornelio
Ligaya.Cornelio at qvc.com
Fri Apr 22 22:11:29 UTC 2016
Hi,
Could you please help me on migrating from log4j to logback. I am using a layout and appender.
What I was trying to do is create a different log file for each thread.
I really appreciate any help from anyone.
Thank you so much in advance.
Below is my codes:
Log4j version of the layout:
package com.selenium.reporting;
import java.io.*;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.commons.lang3.StringEscapeUtils;
public class ReportNGTestLayout extends PatternLayout {
public ConcurrentHashMap<String, String> threadTestName = new ConcurrentHashMap<String, String>();
public int consoleLevel = Level.DEBUG_INT;
public String reportParentFolder = "test-output";
public String executionDate;
@Override
public String format(LoggingEvent event) {
String logline = "";
String logFileName;
String logPrefix;
String consolePrefix;
// Get test name by thread id
String testName = threadTestName.get(Long.toString(Thread.currentThread().getId()));
String curThreadName = Thread.currentThread().getName();
if (testName == null) {
// log to a file by thread name, if no test name
consolePrefix = logPrefix = " " + curThreadName + " : ";
logFileName = Paths.get(reportParentFolder, "main.log").toString();
} else {
// log to <test name>.log file
logFileName = Paths.get(reportParentFolder, "DetailReport", "Attachments", testName + ".log").toString();
logPrefix = " : ";
if (!curThreadName.contains("pool") && !curThreadName.equalsIgnoreCase("TestNG"))
logPrefix = logPrefix + "[" + curThreadName + "] ";
consolePrefix = testName + logPrefix;
}
// Console output
if (event.getLevel().toInt() >= consoleLevel) {
if (event.getLevel().toInt() > consoleLevel)
consolePrefix += event.getLevel() + " : ";
String consoleMessage = new SimpleDateFormat("HH:mm:ss.SSS ").format(new Date(event.timeStamp))
+ consolePrefix + event.getMessage();
if (event.getLevel().toInt() >= Level.INFO_INT)
consoleMessage = "\n" + consoleMessage;
System.out.println(consoleMessage);
}
if (!reportParentFolder.isEmpty()){
// Create log file if needed
File logFile = new File(logFileName);
if (!logFile.exists()){
try {
File parentFolder = new File(logFile.getParent());
parentFolder.mkdirs();
logFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Append to log file
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logFile, true)))) {
out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.format(new Date(event.timeStamp)) +
" [" + event.getLevel() + "]" +
logPrefix +
event.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
// Append to old report if INFO message
if (event.getLevel().toInt() == Level.INFO_INT) {
String newMsg = StringEscapeUtils.escapeHtml3(event.getMessage()
.toString());
Throwable t = null;
ThrowableInformation ti = event.getThrowableInformation();
if (ti != null) {
t = ti.getThrowable();
}
LoggingEvent encodedEvent = new LoggingEvent(
event.fqnOfCategoryClass, Logger.getLogger(event
.getLoggerName()), event.timeStamp,
event.getLevel(), newMsg, t);
String baseFmt = super.format(encodedEvent).replace("@{{", "<")
.replace("@}}", ">");
logline = "<div class=step" + "event.level.toString()" + ">"
+ baseFmt + "</div><br/>";
}
return logline;
}
}
Logback version of the layout:
It is the same as the Log4j version but the only difference is I am extending ch.qos.logback.classic.PatternLayout and I use ILoggingEvent in the format instead of LoggingEvent.
//@Override
public String format(ILoggingEvent event) {
Log4j version of the appender:
package com.selenium.reporting;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
import org.testng.Reporter;
public class TestNGAppender extends AppenderSkeleton {
public TestNGAppender(String name) {
super();
setName(name);
}
@Override
protected void append(LoggingEvent event) {
String logMessage = layout.format(event);
if (!logMessage.isEmpty()) {
Reporter.log(logMessage);
String[] thorwableCrap = event.getThrowableStrRep();
if (thorwableCrap != null) {
Reporter.log(thorwableCrap.toString());
}
}
}
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return true;
}
}
Logback version of the appender:
package com.selenium.reporting;
import org.testng.Reporter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
public class TestNGAppender extends AppenderBase<ILoggingEvent> {
public TestNGAppender(String name) {
super();
setName(name);
}
//@Override
protected void append(ILoggingEvent event) {
String logMessage = this.layout.format(event); ===> in here layout cannot be resolved. How can I access the format method in the ReportNGTestLayout class?
if (!logMessage.isEmpty()) {
Reporter.log(logMessage);
}
}
@Override
public void stop() {
}
/* @Override
public boolean requiresLayout() {
return true;
}*/
}
This is how I setup the appender and layout in the logger:
Logger rootLogger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
TestNGAppender testNGAppender = new TestNGAppender("TestNG");
ReportNGTestLayout logLayout = new ReportNGTestLayout();
logLayout.executionDate = new SimpleDateFormat("MM-dd-yyyy-HH-mm").format(new Date());
logLayout.reportParentFolder = Paths.get(System.getProperty("reportRootPath"), logLayout.executionDate).toString();
logLayout.consoleLevel = Level.toLevel(logLevel.toUpperCase(), Level.DEBUG).toInt();
testNGAppender.setLayout(logLayout); ==> I am also having an error on this line. The method setLayout(ReportNGTestLayout) is undefined for the type TestNGAppender
testNGAppender.start();
rootLogger.addAppender(testNGAppender);
logger.debug("Log4j appender configuration is successful !!");
----------------------------
This message (including any attachments) contains confidential information intended for a specific individual and purpose, and is protected by law. If you are not the intended recipient of this e-mail (even if the e-mail address above is yours), (i) you may not use, copy or retransmit it, (ii) please delete this message and (iii) please notify the sender immediately. Any disclosure, copying, or distribution of this message or the taking of any action based on it, is strictly prohibited.
----------------------------
----------------------------
This message (including any attachments) contains confidential information intended for a specific individual and purpose, and is protected by law. If you are not the intended recipient of this e-mail (even if the e-mail address above is yours), (i) you may not use, copy or retransmit it, (ii) please delete this message and (iii) please notify the sender immediately. Any disclosure, copying, or distribution of this message or the taking of any action based on it, is strictly prohibited.
----------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.qos.ch/pipermail/logback-user/attachments/20160422/86302981/attachment-0001.html>
More information about the logback-user
mailing list