How to enable logging debug messages when root logger is INFO? - log4j

I use logger org.apache.commons.logging.Log.
File log4j.properties is:
log4j.rootCategory=INFO, S
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.logger.org.springsource.sawt=DEBUG
log4j.logger.org.w3c.tidy=INFO
...................
When I use debug method of org.apache.commons.logging.Log it doesn't log anything.
How to change log4j.properties to enable logger log debug messages?

It is really simple.
If you want to log all debug,info,warn.error,fatal messages from logger you need to take name of logger provided at instantiation by method LogFactory.getLog(loggerName) and append it to log4j.logger`. Thus you get
log4j.logger.loggerName=DEBUG
But it's common that loggerName is String from getClass() method. Thus you can use package name to set logger's level for that package.

Related

How Can I Add Console Appender In Logger Object Using log4j-over-slf4j Dependency?

I can't be able to add console appender using logger.addAppender method with log4j-over-slf4j 1.7.x dependency. Moreover, I am unable to set target of that particular Console Appender(i.e., SYSTEM_OUT/SYSTEM_ERR).
I have initialized a console appender object and tried to push that reference into addAppender method by typecasting that reference to Appender. But in that case I am unable to set Target/WriterLocation(i.e., SYSTEM_OUT/SYSTEM_ERR) for console appender reference. I have used the below code snippet-
ConsoleAppender ca = new ConsoleAppender();
ca.setWriter(new OutputStreamWriter(System.out)); // this line is not compatible with log4j-over-slf4j jar
ca.setLayout(new PatternLayout("%-5p [%t]: %m%n"));
logger.addAppender(ca);
Please help me to sort out this problem.
What you are doing doesn't make a lot of sense. log4j-over-slf4j will route calls like logger.debug(), logger.info(), etc to slf4j and then presumably to some other logging framework to be logged. Your code is trying to manipulate log4j 1 objects which won't be involved in logging since you are routing log events to SLF4J (which is why many of them aren't supported by log4j-over-slf4j).
In order to help you we would know what logging implementation you really want to use.

Can I check this in ArchUnit

I have a a proverbial Log4J logger.
Logger logger = new Logger(MyClass.class);
Can I check that the correct filed is pass to the Logger?
Not with Log4j 1 by itself. With Log4j 2 you could just do:
Logger logger = new LogManager.getLogger();
Or you could use Lombok and just use #Log4j (or #Log4j2) at the beginning of your class.
You can't: ArchUnit does not analzye method call parameter values, see also #596.

Log4j mapping all loggers to a single logger

Our middleware team assignes logger names to each application and that is how they know where to direct our socket appenders to.
I would like to use the standard Logger.getLogger(Clazz.class) paradigm but that does not work with the above constraint. Also we can't log library statements out to our socket appender which would come in handy a lot.
Is there a fairly painless way to map everything from all loggers to this middleware assigned logger?
I think our middleware group messed up in how the configured the enterprise logging system. It looks like there is a setApplication property on the SocketAppender that should be used instead. Regardless, this is what we have to deal with...
You'd like to redirect your "regular" loggers' output to the "middleware logger" directly, i.e. without setting the middleware logger's appender on all the "regular" loggers, right?
If this is the case, try writing your own appender:
class MiddlewareRedirectingAppender extends AppenderSkeleton {
private Logger middlewareLogger = Logger.getLogger("your 'middleware' logger name");
public void doAppend(LoggingEvent event) {
// implement whatever filtering, etc. you want
middlewareLogger.log(...);
}
}
Attach this appender to your "regular" loggers, or just to the root logger (depending on how your "middleware" logger behaves).
Disclaimer: this is just a loose idea, I haven't tested it.

How to get log4net to output to the same place as TestContext.WriteLine

How can I setup log4net to write to the Output window of MsTest?
The only function I've been able to output to that window with is TestContext.WriteLine, but I do not know if there is an appender that can do that. Trace and Console outputs do not work.
I created a custom appender that I could pass the TestContext to, and use the WriteLine method on that for logging.
To setup log4net to use the TestContext, I created a custom appender (NUnitLogAppender.cs):
https://gist.github.com/dropthemic/f360c389c35758bbb94e67b3aee09157
This is based off Console appender. To write to TestContext or TestContext.Progress, set the "Target" in NUnitLogAppender class.

How do I make log4j create log files on demand only?

We have a modular application where modules have their own log4j logs (i.e. communication log and error log). The appenders and categories for these are all configured in the core log4j XML, but not all modules are always installed.
The DailyRollingFileAppender creates its file regardless of use and that exposes the full set of modules although not present and as some of them are customer specific we'd like to hide logs not in use.
Is there a way to make DailyRollingFileAppender create its file on first use instead of automatically at startup?
I had the same problem, so I have extended the standard FileAppender class and I have created a new LazyFileAppender that is a FileAppender that lazily initialize the log file(creates it only when the first write operation happens).
The LazyFileAppender and some other additions to the standard log4j library can be found into a simple library that I have created : log4j-additions .
You can look at the source to develop your own extension or you can use it as is ...
In Log4j 2, both FileAppender and RollingFileAppender has the parameter "createOnDemand" which can be used to configure to create the log file only when a log event passed to the appender.
Example:
<RollingFile name="LogFile" fileName="test.log" filePattern="test-%i.log.gz" createOnDemand="true">
<Policies>
<SizeBasedTriggeringPolicy size="1MB"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
More details here: https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingRandomAccessFileAppender
The file appenders have no option to lazily create the log files - the setFile method automatically creates the file if it doesn't already exist: ostream = new FileOutputStream(fileName, append);
You'll have to extend the appender and overwrite the file initialisation code yourself to get the behaviour you're after.
Extend the standard FileAppender class was unsuccessful for me. So I have found an other solution using appenders programmatically to create log files on demand only (and with timestamp in the name file). I have written these two methods :
public void startLog() {
SimpleDateFormat sdf_long = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
FileAppender fa = new FileAppender();
fa.setName("foo");
fa.setFile(sdf_long.format(new Date()) + ".log");
fa.setLayout(new PatternLayout("%d{HH:mm:ss.SSS} %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();
Logger.getRootLogger().addAppender(fa);
}
public void stopLog() {
Logger.getRootLogger().getAppender("foo").close();
Logger.getRootLogger().removeAppender("foo");
}
My log4j.properties file only configures the console appender. When I want to start logging I call the startLog() method. When I want to log in an other file I call stopLog() first and then startLog() method.

Resources