Is it possible to retrieve a list of all appenders configured in log4j at run time?
I'll flesh out the scenario a little more. Given the following config how would I retrieve all appenders (stdout and altstdout)?
log4j.rootLogger=error, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.altstdout=org.apache.log4j.ConsoleAppender
log4j.appender.altstdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.altstdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
If you want access to all appenders configured for all loggers you must do something like this
for (Enumeration loggers=LogManager.getCurrentLoggers(); loggers.hasMoreElements(); ) {
Logger logger = (Logger) loggers.nextElement();
for (Enumeration appenders=logger.getAllAppenders(); appenders.hasMoreElements(); ) {
Appender appender = (Appender) appenders.nextElement();
...
I don't know why log4j has no method like LogManager.getAllAppenders(), but it looks like
disadvantage.
This is one what you need
log4j Method getAllAppenders
I want to add something that took me a while to understand.
If you look at the figure below (which I copied from here), you can see, that even though the logger com.foo.bar
will print to the root loggers FileAppender, its appender list is still null. So you cannot get all appenders the logger will write to with the method logger.getAllAppenders()
.
For this you need to iterate through all the parents also and the root logger seperately. Because you cannot iterate logger.getParent()
to root logger (root logger returns null - see documentation of getParent()). As far as I know, you have to access the rootLoggers' appenders seperately via Logger.getRootLogger().getAllAppenders().
Working Solution for Log4j 1:
Note: getAllAppenders will get only active log. Not the full list of files defined in your log4j.xml configuration file.
Here's how I could achieve this for setting rwxrwxrwx rights on all log files
@SuppressWarnings("unchecked")
public static <E> E safeCastNoException(Object o, Class<E> target)
{
if(target.isInstance(o)) return (E)o;
return null;
}
{
URL file;
try
{
LogManager.resetConfiguration();
file = new URL("file:" + Log4jXMLConfigFileName);
// We override DOMConfigurator to catch Appender settings
// in parseAppender and rework file rights access
new DOMConfigurator()
{
@Override
protected Appender parseAppender(Element appenderElement)
{
Appender a = super.parseAppender(appenderElement);
FileAppender fileAppender = safeCastNoException(a, FileAppender.class);
if( fileAppender != null )
{
String filePath=fileAppender.getFile();
Path pathTofile = FileSystems.getDefault().getPath(filePath);
try
{
// Create the empty file with default permissions, etc.
Files.createFile(pathTofile);
}
catch(FileAlreadyExistsException x)
{
System.err.format("file named %s already exists, no need to recreate%n", pathTofile);
}
catch(Exception x)
{
// Some other sort of failure, such as permissions.
System.err.format("createFile error: %s%n", x);
}
try
{
//using PosixFilePermission to set file permissions 777
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
//add owners permission
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
//perms.add(PosixFilePermission.OWNER_EXECUTE);
//add group permissions
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_WRITE);
//perms.add(PosixFilePermission.GROUP_EXECUTE);
//add others permissions
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OTHERS_WRITE);
//perms.add(PosixFilePermission.OTHERS_EXECUTE);
System.out.println("Trying to set 666 posix rights to log file: " + pathTofile.toAbsolutePath().toString());
Files.setPosixFilePermissions(Paths.get(pathTofile.toAbsolutePath().toString()), perms);
}
catch(Exception x)
{
// Some other sort of failure, such as permissions.
System.err.format("chmod error: %s%n", x);
}
}
return a;
}
}.
doConfigure(file, LogManager.getLoggerRepository());
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}