How to write below configuration using Java code?
log4j.com.saurabh.util.LogUtil=DEBUG, myAppender
I am working on legacy code which is using log4j 1.x, I don't have choice to upgrade log4j version.
Basically, my requirement is to have session level logging. For each user session separate log file should be created.
RollingFileAppender userSessionAppender = null;
try {
String logFile = new StringBuffer(CATALINA_HOME)
.append(File.separator)
.append(LOG_DIR)
.append(File.separator)
.append(InetAddress.getLocalHost().getHostName())
.append("_")
.append(userName)
.append("_")
.append((new SimpleDateFormat("yyyy-MM-dd.hh-mm-ss")).format(new Date()).toString())
.append(LOG_FILE_EXTN)
.toString();
userSessionAppender = new RollingFileAppender(new PatternLayout(pattern), logFile);
userSessionAppender.setName(sessionId);
userSessionAppender.setThreshold(Level.DEBUG);
// add a filter so we can ignore any logs from other user sessions
userSessionAppender.addFilter(new SessionIdFilter(sessionId));
rootLogger.addAppender(userSessionAppender);
Logger.getLogger(sessionId).addAppender(userSessionAppender);
Logger.getLogger(sessionId).setLevel(Level.DEBUG);
Logger.getLogger(sessionId).setAdditivity(false);
} catch (Exception e) {
LOG.error("createLogger() : Exception while creating appender for user: " + userName, e);
}
and to actually log the message:
if (isLoggingEnabled(userName)) {
Logger.getLogger(sessionId).debug(message);
}
Using this code, I am able to create separate file and log into that however, log statements from other classes are also going into the same file.
I want to restrict the logging to this file for specific classes/packages.
And I think below line of config helps for this:
log4j.com.saurabh.util.LogUtil=DEBUG, myAppender
I need programmatic way to achieve above line of config.
Thanks in advance.
Related
I have an app in java using log4j as my logging jar, but when I try to debug my app and open the log file I find it short and with only the last lines I logged and the rotation files don't show any of the logs that I have seen before.
Is there something wrong with my configuration file? I have multiple projects pointing to the same log file, Could this be the problem?
Here is my log4j.properties:
log4j.rootLogger=ERROR,logfile
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=/opt/tomcat7/logs/mylogs.log
log4j.appender.logfile.MaxFileSize=500KB
# Keep one backup file
log4j.appender.logfile.MaxBackupIndex=2
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %5p (%F:%L) - %m%n
Thanks
You specified level of root logger to be ERROR, while in most cases there won't be a lot of ERROR messages - maybe one-two per many INFO level messages, while you suppressed them: ERROR level allows only ERROR and FATAL messages to be logged. And it filders out any INFO, WARN, DEBUG, TRACE level. Usually you don't use such setup in development. And in production you usually suppress only some verbose classes/packages, but not everything like in config you posted (meaning here ERROR level applies to every class).
So I suppose you should replace ERROR with INFO in your config.
UPDATE: Also likely log4j simply doesn't see your config file. I encountered this issues several times personally and each time I had a workaround like this:
public class Log4JProperties {
public static void setupLog4j(){
String log4jPathFile = Log4JProperties.class.getResource("/log4j.properties").getFile();
Properties props = new Properties();
try {
InputStream configStream = new FileInputStream(log4jPathFile);
props.load(configStream);
configStream.close();
} catch (IOException e) {
System.out.println("log4j configuration file not found");
}
LogManager.resetConfiguration();
PropertyConfigurator.configure(props);
}
}
This is not necessary when I run code from inside Intellij, but when I run using Maven, logging doesn't work without calling this function in the beginning of the execution.
When you specify MaxBackupIndex=2 it will only keep last 2 backups, if log file fills up quickly old backup files will be overridden.
You might have to increase the MaxFileSize or MaxBackupIndex based on your file logging behaviour…
https://logging.apache.org/log4php/docs/appenders/rolling-file.html
I am running into logging issues after upgrading my Java EE app from Weblogic/JDeveloper to 12.1.2 to 12.1.3.
System.out.println is printing to the server log fine but log.info("test") is not. The logging works if I set the log level e.g. log.setLevel(Level.INFO). Here are my test results.
// This works
System.out.println("test1");
// Output when run: test1
// This does not work. Nothing prints to the server log
log.info("test2");
// The above works if I set the log level
log.setLevel(Level.INFO);
log.info("test3");
// Output when run: test3
// This prints null. It appears that logging level is set to null on server startup
System.out.println(" what is my current logging level: " + log.getLevel());
As per Oracle documentation if no logging configuration is provided then the default logging.properties in JDK/JRE/Lib is used. The default log level is INFO.
I have also tried to load up logging.properties and switch log4j but nothing works.
I don't want to set log level to something in every class. Is there a way to set this on server startup or debug what is causing/setting the logging level to null.
From the logger documentation:
The result may be null, which means that this logger's effective level will be inherited from its parent.
So you only have to set the level of the root logger. You should check that a ConsoleHandler is installed and that the level is set to INFO or lower. You should also check that writing to System.err shows up in the log file as that is the stream that is used for the ConsoleHandler.
I use this code for mine "Logg class" so every class is connected with it, so every exception from every class use this. if you have many classes you want to get logged from this is kind a smart and easy way. I just have one problem too, this code creates a txt file every time you run a program and it's connected with the Logg class. I will fix it soon, so i will edit this answer then. heres my code:
Top of class
private final static Logger logger = Logger.getLogger(Logg.class.getName());
private static FileHandler fh = null;
and in the method you can have this;
Properties prop = new Properties();
InputStream in = Logg.class.getResourceAsStream("loggconfig");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
Some exemple, this txt file will be named the current year, date and time.
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm");
fh = new FileHandler((dateFormat.format(date) + ".log"), false);
Logger l = Logger.getLogger("");
fh.setFormatter(new SimpleFormatter());
l.addHandler(fh);
l.setLevel(Level.INFO);
have this under argument you want to logg:
logger.log(Level.WARNING, "Bla bla");
you can also have a file, like a config so you can choose what level you want to get logged. Then you need to create a property file, my is named loggconfig.
in the config file i have this code:
Level=WARNING
so it just every exception i have as a WARNING, i can change it to INFO to so i get everything logged. Smart to only use two levels in the code.
So if you want to use config file u need to change l.setLevel too this:
l.setLevel(Level.parse(prop.getProperty("Level")));
so it takes the level from config file.
I have a application that write a log file to .log.
But now i make a html jar file to implement to the application (1 log per request).
The problem is when 2 or more thread running at the same time, the html log is mixed up.
Example:
aaa.log and bbb.log
aaa.log content contain bbb.log content vice versa
how to make it separate log file with own content.
ctx.htmllogger = new HTMLLogger(
ctx.control.getCodeValue(),
ctx.AvailRequest.getTrip().getSegmentProductType()
.getCodeValue(), ctx.OPT_TYPE);
String htmllogdir = System.getProperty("user.dir");
htmllogdir = htmllogs + "\" + ctx.htmllogger.getCurrentTS( "ddMMyyyy" ) + "\" + ctx.OPT_TYPE.toLowerCase();
ctx.htmllogger.MakeDirectories( htmllogdir );
try {
ctx.htmllogger.initLogger(DlgKuoni.class.getCanonicalName(), htmllogdir);
} catch (IOException e) {
ctx.htmllogger = null;
e.printStackTrace();
}
ctx.htmllogger.startHTMLLog();
Appreciated who help me.
You should take a look at log4j (and maybe self4j). There is really no need th handle these things on your own.
That can all be configured with log4j, including html-formatter etc.
This is happening because you have a bug in your program. Most likely you have a global/shared variable used by both threads to access the log.
I suggest you have a resource for your log which is visible to only one thread at a time. This avoids the chance for confusion.
I want to maintain a log file or txt file ,where I am able to maintain the exception details as well as some other details either in txt or log file.The scenario is like this
try {
.......
} catch(exception e) {
here the file should be created
}
what will be the best optimize solution for this without using logging frameworks.
Could this work for me?
try {
// something
} catch (Exception ex) {
ex.printStackTrace(new PrintStream(new File("error.log")));
}
If you don't want to use any logging framework, you might look at the Java Logging Framework and use it to create your own implementation
The java.util.logging contains all required classes that you need for your implementation
You still have to run some code that appends the required information to a (log) file. So at the end you will have a logger class that provides some static methods like logException or logError. A trivial draft for this:
public class MyLogger {
public static log(Object sender, Throwable e) {
String className = sender;
String message = e.getMessage();
append(sender, message);
}
private static void append(String classname, String message) {
// append something to your file
}
}
You may want to add the timestamp and some line number information, which is available from Thread.currentThread().getStackTrace()[n] (play with the values for n until you find the frame from the calling method, it's 2, 3 or 4)
Then, whenever you handle an exception, do
catch(SomeException e) {
MyLogger.log(this, e);
}
Logging Frameworks are there to help you maintain your log files.
If you don't want to use them, you can design your own logging mechanism with all the pain
of writing to text file.
In case of log4j:
1. You can set the logging levels like debug,error,info etc...
2. You can set appenders like File Appender, Console Appender etc..
These 2 things might suffice your need.
I'm using java logging to write log messages of my application to a log file and other destinations. Having set the log level to FINE, I also get (unwanted) messages from AWT/Swing, such as:
{0}, when grabbed {1}, contains {2}
and others. Looking at the JDK source code (see e.g. here), one sees that the name of the corresponding logger is sun.awt.X11.grab.XWindowPeer.
What I understood from the Java logging framework is that this logging handler should inherit its loglevel from its parents like sun.awt.
I tried the following:
Logger.getLogger("sun.awt").setLevel(Level.OFF);
but the AWT/Swing debug messages still appear in the log output.
What's the recommended way of programmatically disabling these log messages (while still allowing FINE messages from other sources) ?
If you just want to log the messages of your own application, you can disable all messages and then explicitly enable messages for your application:
Logger.getRootLogger().setLevel(Level.OFF);
Logger.getLogger("package.of.your.application").setLevel(Level.ALL);
Inside the properties-file for logging (e.g. logging.properties) this would be:
.level = OFF
package.of.your.application.level = ALL
I had the same problem today. Searching on google this is the top url and I don't find a good source to a answer, so I will post mine :)
Assuming that Andre use the java.util.logging API, it's possible to add a Handler that will control the format of your log, using setFormatter(Formatter newFormatter).
So I extended Formatter and checked if the class of the log contains java.awt, javax.swing or sun.awt.
class MyFormatLog extends Formatter {
#Override
public String format(LogRecord record) {
if( !record.getSourceClassName().contains("java.awt") &&
!record.getSourceClassName().contains("javax.swing.") &&
!record.getSourceClassName().contains("sun.awt.") ) {
//format my output...
} else {
return "";
}
}
}
I could not find the getRootLogger() method in the Logger class any more. This is what works for me:
logger = Logger.getLogger("my.package");
Logger l = logger;
while (l != null) {
l.setLevel(Level.OFF);
l = l.getParent();
}
logger.setLevel(Level.FINER);
Logger.getLogger("java.awt").setLevel(Level.OFF);
Logger.getLogger("sun.awt").setLevel(Level.OFF);
Logger.getLogger("javax.swing").setLevel(Level.OFF);
Try
Logger.getRootLogger().setLevel(Level.OFF);