Writing duplicate data when using Log4j in Jboss webservice - java

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.

Related

My logging.properties custom formatter is not working

I'm actually adding java logging (can't use other framework) to my project. I build my app on a .war, and deployed it over Weblogic, the logger is working with my logging.properties config, except for the formatter i don't know why the app is ignoring it.
This is my class where i prepare the logger;
public class CtgLogger {
private static final String LOAD_ERROR = "Properties could not be loaded.";
private static final Map<String, Level> LEVEL_MAP;
private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
static {
final InputStream inputStream = CtgLogger.class.getResourceAsStream("/logging.properties");
try {
LogManager.getLogManager().readConfiguration(inputStream);
} catch (Exception e) {
Logger.getAnonymousLogger().severe(LOAD_ERROR);
Logger.getAnonymousLogger().severe(e.getMessage());
}
// and I add the LEVEL_MAP to the logger...
And this is my properties...
handlers = java.util.logging.FileHandler
java.util.logging.FileHandler.pattern=logsfolder/CTGLOG_%g.log
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.limit=3000
java.util.logging.FileHandler.count=6
#java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
#If I use the SimpleFormatter, apps goes well with it format.
java.util.logging.FileHandler.formatter = com.package.my.log.JsonCustomFormatter
#If I use my custom formatter, the weblogic works with a XMLFormatter (default)
I know the .properties is working, because logger is working with the pattern, limit and count I setted.
PD: If i run my app with JUnit, logs are working with my custom formatter, but do not at weblogic! Don't know why!
Weblogic is going to have multiple class loaders. The standard LogManager can only see classes loaded via the system class loader. Check the Server Log for errors related to not finding your custom class. If that is the case, you have to move your formatter to the system classloader. Otherwise you have have to use code to install your formatter from your web app which is running in a child classloader.
There are also bugs in the LogManager.readConfiguration and alternative methods to use in JDK9 and later.
Using Eclipse and java standard logger may be painful. I found something to produce similar output to Log4J:
"%d{HH:mm:ss,SSS} %-5p %m (%F:%L) in %t%n" in Log4J : you can click on reference and you are there log was issued
21:36:37,9 INFO process model event Digpro2021a/digpro.Digpro(Digpro.java:358) in processModelEvent
21:36:37,9 INFO start polling Digpro2021a/digpro.Digpro(Digpro.java:398) in processEventAutoreload
21:36:37,9 INFO reload now Digpro2021a/digpro.Digpro(Digpro.java:370) in processModelEvent
public class Digpro {
protected static final Logger L = Logger.getLogger("Digpro");
//logger conf
static {
L.setLevel(Level.FINE);
Handler handler = Logger.getLogger("").getHandlers()[0];
handler.setLevel(Level.FINE); // Default console handler
handler.setFormatter(new Formatter() {
#Override
public String format(LogRecord r) {
Date d = new Date(r.getMillis());
String srcClassLong = r.getSourceClassName();
String[] aClass = srcClassLong.split("\\$")[0].split("\\.");
String srcClass = aClass[aClass.length - 1];
StackTraceElement elem = (new Throwable()).getStackTrace()[7];
int line = elem.getLineNumber();
String modulName = elem.getModuleName();
return String.format("%tH:%tM:%tS,%tl %.7s %s %s/%s(%s.java:%d) in %s\n", d, d, d, d, //
r.getLevel(), r.getMessage(), // LEVEL and message
modulName, srcClassLong, srcClass, line, r.getSourceMethodName()); //ref to click on
}
});
}
...
public static class TestDigpro extends Digpro {
//TESTING:
#Test
public void testLogFormat() {
L.info("poll info");
L.fine("got fine");
}
}
}
produses:
21:51:20,9 INFO poll info Digpro2021a/digpro.Digpro$TestDigpro(Digpro.java:723) in testLogFormat
21:51:20,9 FINE got fine Digpro2021a/digpro.Digpro$TestDigpro(Digpro.java:724) in testLogFormat

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");
}
}

Categories

Resources