MDC logging in Core Java [duplicate] - java

This question already has answers here:
Why log4j stop running MDC logic if Java version is 11, 11.1x, etc
(2 answers)
Closed 1 year ago.
While using MDC with log4j in a simple java(JDK-9) code, I am not getting any value for the MDC defined field. Below are My java code and log4j.properties file.
Java code:
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
public class Logging {
public static void main(String[] args) {
Logger log = Logger.getLogger("Logging.class");
String a="BOB";
try {
log.info("Hello");
MDC.put("userid",a);
log.debug("Texting 1");
} catch(Exception e) {
log.error(e.getMessage());
} finally {
MDC.remove("userid");
} } }
log4j.properties:
log4j.rootLogger=DEBUG,consoleAppender
log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %5p %c %x - %m - [%X{userid}]%n
Output:
0 [main] INFO Logging.class - Hello - []
4 [main] DEBUG Logging.class - Texting 1 - []

In your code, just try to change the order and then try. I was getting same issue, I did change the order and tried,it is working for me. Let me share my code.
public class MyMDC {
public static void main(String[] args) {
Logger log = Logger.getLogger(MyMDC.class);
String a="BOB";
try {
MDC.put("userid",a);
log.info("Hello");
log.debug("Texting 1");
}
catch(Exception e) {
log.error(e.getMessage());
}
finally {
MDC.remove("userid");
}
}

Related

Strange log4j declaration

I have a problem with an old project: The log file doesn't append in the console view of Eclipse. Instead of declaring the properties of log4j uses in log4j.xml or log4j.properties, the logger is defined in java:
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class GCLogger {
private static GCLogger _self;
private Logger logger;
private static final String NAME_FILE = "fichierLog.log";
public static GCLogger getInstance() {
if (_self == null || _self.logger == null) {
GCLogger logger = new GCLogger();
logger.initLogger();
_self = logger;
}
return _self;
}
public void error(String msg, Exception e) {
if (logger != null) {
logger.error(msg, e);
}
}
public void debug(String msg) {
if (logger != null) {
logger.debug(msg);
}
}
private void initLogger() {
logger = Logger.getRootLogger();
FileAppender fa = new FileAppender();
PatternLayout monLayout = new PatternLayout("%d{DATE} - %5p %c{1} - %m%n");
logger.removeAllAppenders();
try {
File repLogs = new File(GCConstants.GC_REPERTOIRE_LOGS);
if (!repLogs.exists()) {
repLogs.mkdir();
}
fa = new FileAppender(monLayout, GCConstants.GC_REPERTOIRE_LOGS + File.separator + NAME_FILE, true);
fa.activateOptions();
fa.setImmediateFlush(true);
logger.addAppender(fa);
logger.setLevel(Level.ALL);
} catch(Exception e) {
logger = null;
}
}
}
Is there a simple way to show fichierLog.log in the console view (using eclipse configuration)?
If not, what is the minimal change to make it works?
Minimum change - add a console appender:
ConsoleAppender console = new ConsoleAppender(monLayout); // re-use the layout
logger.addAppender(console);
<opinion>
However, if you're making other changes to the codebase, I would strongly recommend changing this to use external configuration - it'll make your life much easier in the long (and probably short) term.</opinion>

SyslogAppender not working in windows

i used the following code without using lo4j.properites,but it not working,no logs are added in to the Systems log .
i am using windows platform.
public class SysLogApp extends SyslogAppender {
public static void main(String[] args) {
try {
System.out.println("Start");
Logger myLogger = Logger.getLogger("LoggerAppenderSyslog");
System.out.println(myLogger);
SysLogApp syslogAppender = new SysLogApp();
myLogger.addAppender(syslogAppender);
syslogAppender.setName("SYSTEM_SYSLOG");
syslogAppender.setLayout(new PatternLayout("%d{MMM dd HH:mm:ss} %F %L %5p [%t] %m %n"));
syslogAppender.setFacility("SYSLOG");
syslogAppender.setFacilityPrinting(true);
syslogAppender.setSyslogHost("localhost");
System.out.println(syslogAppender.getName());
syslogAppender.activateOptions();
Logger.getRootLogger().addAppender(syslogAppender);
myLogger.warn(" HEllo TEST ");
System.out.println("End");
} catch (Exception exc) {
System.out.println("Exception " + exc);
}
}
}
i had done this by using NTEventLogAppender in log4j.
https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/nt/NTEventLogAppender.html

saving the logs in text file which gets generated in selenium webdriver

How to save the logs in text file which gets generated in selenium webdriver?
I know how to log normal logs in java like using logger.
Below is the step which i tried to log.
Logger logger = Logger.getRootLogger();
PropertyConfigurator.configure("data/config/log4j.properties");
FileAppender appender = (FileAppender)logger.getAppender("file");
String logFilePath ="C:\\Users\\priyarsi\\Desktop\\LdapLog.txt";
appender.setFile(logFilePath);
appender.setThreshold(Level.DEBUG);
appender.setAppend(true);
appender.activateOptions();
log.debug("Hello this is an debug message");
log.info("Hello this is an info message");
Can anyone please help me in logging selenium webdriver output to a text file?
Try this out -
# Root logger option
log4j.rootLogger=INFO, file, stdout
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=../AutoLogs.log
#log4j.appender.file.File=${file.name}
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %5p %c{1}:%L %t - %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %5p %c{1}:%L %t - %m%n
You can try logging Log4j API. It is very easy to understand and implement. Perform following steps:
Download Log4j jars from (https://logging.apache.org/log4j/1.2/download.html)
Add downloaded jars to project's build path.
Create a new XML file – log4j.xml and place it under the Project root folder.
Add new xml file or you can customise it the way you want. (http://toolsqa.com/selenium-webdriver/log4j-logging/)
Create new Java Class and paste following code:
package utility;
import org.apache.log4j.Logger;
public class Log {
// Initialize Log4j logs
private static Logger Log = Logger.getLogger(Log.class.getName());//
// This is to print log for the beginning of the test case, as we usually
// run so many test cases as a test suite
public static void startTestCase(String sTestCaseName) {
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
Log.info("$$$$$$$$$$$$$$$$$$$$$ " + sTestCaseName + " $$$$$$$$$$$$$$$$$$$$$$$$$");
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
}
// This is to print log for the ending of the test case
public static void endTestCase(String sTestCaseName) {
Log.info("XXXXXXXXXXXXXXXXXXXXXXX " + "-E---N---D-" + " XXXXXXXXXXXXXXXXXXXXXX");
Log.info("X");
Log.info("X");
Log.info("X");
Log.info("X");
}
// Need to create these methods, so that they can be called
public static void info(String message) {
Log.info(message);
}
public static void warn(String message) {
Log.warn(message);
}
public static void error(String message) {
Log.error(message);
}
public static void fatal(String message) {
Log.fatal(message);
}
public static void debug(String message) {
Log.debug(message);
}
}
Call above methods in your test scripts.

generating logs of simple java class with log4j api

I have one query is that if I write a simple Java class and I want to see the logs that are executed at the behind, such that are executed at the backend by the JVM. I have log4j JAR with me. Could you please give me advice to how to achieve this?
I would to see the same logs that are generated in case of a WebApp, so I can reuse it for a Java App.
try looking at log4j api/demo here http://www.vaannila.com/log4j/log4j-tutorial/log4j-tutorial.html
you can generate log for any class and any application afaik using log4j , which needs not necessarily be a web app
Here is a very simple example that you should be able to adapt to what you are trying to achieve.
Step 1:Import log4j jar file in your project
Step 2:-Create a Log java file
public Log(Class className) {
logger = Logger.getLogger(className.getClass());
logger.getClass();
final String LOG_PROPERTIES_FILE_NAME = "log4j.properties";
props = loadLogFile(LOG_PROPERTIES_FILE_NAME, className);
//props =getPropsFile(LOG_PROPERTIES_FILE_NAME, className);
PropertyConfigurator.configure(props);
}
public static Properties loadLogFile(String propertyFile, Class className) {
//String filePath="";
try {
Properties ps = null;
ResourceBundle bundle = ResourceBundle
.getBundle("resource.DbProperties");
String logPath = bundle.getString("logs.path");
File filePath = new File(logPath);
if (!filePath.exists()) {
filePath.mkdirs();
}
props.clone();
props = getPropsFile(propertyFile, className);
props.setProperty("info_file_path", filePath.toString());
// PropertyConfigurator.configure(props);
} catch (Exception e) {
e.printStackTrace();
}
return props;
}
public void info(String message) {
logger.info(message);
}
public void warn(String message) {
logger.warn(message);
}
public void error(String message) {
logger.error(message);
}
public void fatal(String message) {
logger.fatal(message);
}
public void printStackTrace(Throwable ex) {
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
logger.error("\n" + sw.toString());
}
log4j.properties
log4j.rootCategory=LOGFILE
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=${info_file_path}\\info_Pension_application.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=INFO
log4j.appender.LOGFILE.Threshold=DEBUG
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
If your "simple Java class" happens to be in a Java EE container (like a .jsp or servlet in Tomcat, JBoss or WebSphere), then all you need to do is:
1) import org.apache.log4j.Logger;
2) declare a static instance in your class:
EXAMPLE: `static Logger logger = Logger.getLogger ("MyApp");`
3) Use your logger
EXAMPLE: `logger.info ("something interesting happened");`
4) If you include log4j.java and your own log4j.properties in your CLASSPATH, then you don't need to do anything else.
Here's a bit more info on using log4j with Tomcat or app servers:
http://tomcat.apache.org/tomcat-5.5-doc/logging.html
http://logging.apache.org/log4j/1.2/manual.html
http://www.tutorialspoint.com/log4j/log4j_quick_guide.htm
Here's a very simple example program that "does logging", from the above tutorialspoint.com link:
import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class log4jExample{
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(
log4jExample.class.getName());
public static void main(String[] args)
throws IOException,SQLException{
log.debug("Hello this is an debug message");
log.info("Hello this is an info message");
}
}

Writing duplicate data when using Log4j in Jboss webservice

I am using Log4j with Jboss EJB webservice. I am logging the application flow in the File.
This is the code I am using for logging
FileAppender fileappender;
File file = new File("jws_" + getCurrentDate("dd_MMM_yyyy") + ".log");
Logger log = null;
System.out.println(file.getAbsolutePath() );
try
{
log = Logger.getLogger(ConnMan.class);
fileappender = new FileAppender(new PatternLayout(),"f2cjws_" + getCurrentDate("dd_MMM_yyyy") + ".log");
log.addAppender(fileappender);
if (!theLogLevel.equalsIgnoreCase("error"))
{
if ("yes".equalsIgnoreCase(getProperties().getProperty("log")))
{
log.debug(getCurrentDate("dd MMM yyyy HH:mm:ss 1")+" "+theError);
}
}
else
{
log.debug(getCurrentDate("dd MMM yyyy HH:mm:ss 1")+" "+theError);
}
}
catch (IOException e)
{
System.out.println("Logger failed due to "+e.getMessage());
}
catch(Exception e)
{
System.out.println("Logger failed due to "+e.getMessage());
}
When I run the application, I am getting duplicate data in my file, i.e.., same data is written twice or thrice. The above code worked fine in webapplication deployed in tomcat.
So I feel I am missing something in related to JBoss.
This webservice now currently uses the log4j properties built in with the server. Can I know how to make it to use application's own properties file?
Please help me,
Thanks in advance,
You need to create your own log writer,
public final class LogWriter
{
private static Logger appLogger = null;
private static String className = LogWriter.class.getName() + ".";
static
{
try
{
appLogger = Logger.getLogger("Demologer");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void logDebug(String message)
{
appLogger.log(className, Level.DEBUG, LogWriter.getMessage(message), null);
}
public static void logInfo(String message)
{
appLogger.log(className, Level.INFO, LogWriter.getMessage(message), null);
}
public static void logError(String message)
{
appLogger.log(className, Level.ERROR, LogWriter.getMessage(message), null);
}
private static String getMessage(String message)
{
String retValue;
Calendar cale = Calendar.getInstance();
Date now = cale.getTime();
//retValue=now.getDate()+"/"+(now.getMonth()+1)+"/"+(now.getYear()+1900)+" "+now.getHours()+":"+now.getMinutes()+":"+now.getSeconds();
retValue = now + "\n";
now = null;
cale = null;
return retValue + message;
}
}
You can use this one as you need.
If you have some thing like following in your log4j.properties you will see duplications in output:
log4j.rootLogger=error, myappender
log4j.logger.com.sample=warn, myappender
log4j.logger.com.sample.deeper.package=all, myappender
correct it to:
log4j.rootLogger=error, myappender
log4j.logger.com.sample=warn
log4j.logger.com.sample.deeper.package=all
Edit:
Following will write fatal and error level logs from every classes, fatal, error and warning level logs from com.sample.* classes and every logs from com.sample.deeper.package.* classes to /var/log/myappender/myappender.log file.
Save as log4j.properties in you root package:
# This appender is not used in this example.
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c - %m%n
# But this one is used.
log4j.appender.myappender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.myappender.DatePattern='.'yyyy-MM-dd
log4j.appender.myappender.File=/var/log/myappender/myappender.log
log4j.appender.myappender.layout=org.apache.log4j.PatternLayout
log4j.appender.myappender.layout.ConversionPattern=%d{ABSOLUTE} %5p %c - %m%n
log4j.appender.myappender.Encoding=UTF-8
log4j.rootLogger=error, myappender
log4j.logger.com.sample=warn
log4j.logger.com.sample.deeper.package=all
In your every classes you need a logger:
private static Logger logger = Logger.getLogger(ThisClassName.class);
And you don't need the snippet code you have in you question any more.

Categories

Resources