问题
We are using log4j 2.5. My question is in regards to the ConferenceLog so please disregard other configurations below.
log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="180">
<Properties>
<!-- change the path to conference logs below to fit your system -->
<Property name="LOG_DIR">C:\CodeRepos\logs</Property>
<Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level
%logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}" />
</Console>
<Routing name="DailyLog">
<Routes pattern="${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}"
fileName="${LOG_DIR}/symproxy.log"
filePattern="${LOG_DIR}/symproxy-%i.log">
<PatternLayout pattern="${PATTERN}" />
<SizeBasedTriggeringPolicy size="20971520" />
<DefaultRolloverStrategy max="100" />
</RollingFile>
</Route>
</Routes>
</Routing>
<Routing name="ConferenceLog">
<Routes pattern="${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}"
fileName="${LOG_DIR}/conferences/${ctx:logFileName}.log"
filePattern="${LOG_DIR}/conferences/${ctx:logFileName}.%i.log.gz">
<PatternLayout pattern="${PATTERN}" />
<SizeBasedTriggeringPolicy size="20971520" />
</RollingFile>
</Route>
</Routes>
</Routing>
<Routing name="DeviceLog">
<Routes pattern="${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}"
fileName="${LOG_DIR}/devices/${ctx:logFileName}.log"
filePattern="${LOG_DIR}/devices/${ctx:logFileName}.%i.log.gz">
<PatternLayout pattern="${PATTERN}" />
<SizeBasedTriggeringPolicy size="5kb" />
<DefaultRolloverStrategy max="3" />
</RollingFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="DailyLog" />
</Root>
<Logger name="conference.logger" level="debug" additivity="false">
<AppenderRef ref="ConferenceLog" />
<AppenderRef ref="Console" />
</Logger>
<Logger name="device.logger" level="info" additivity="false">
</Logger>
</Loggers>
</Configuration>
I have a small wrapper and in there i instantiate this conference logger
private final Log conferenceLogger = LogFactory.getLog("conference.logger");
After that it is used like so
private void logger(Long meetingId, Log log, String className, Level level, String message, Throwable error) {
ThreadContext.put(LOG_FILE_NAME, String.valueOf(meetingId));
logger(conferenceLogger, level, className + "." + message, error);
ThreadContext.remove(LOG_FILE_NAME);
}
private static void logger(Log log, Level level, String message, Throwable error) {
if (level == Level.DEBUG) {
log.debug(message);
} else if (level == Level.ERROR) {
if (error == null) {
log.error(message);
} else {
log.error(message, error);
}
} else if (level == Level.FATAL) {
log.fatal(message);
} else if (level == Level.TRACE) {
log.trace(message);
} else if (level == Level.INFO) {
log.info(message);
} else if (level == Level.WARN) {
log.warn(message);
}
}
This creates a bunch of files named with the "meeting id". My problem however is that these files are never closed after they are opened.
I read over this similar SO post however I don't have references to my FileAppender
to call close on, nor do I have a Logger
object, so I'm not sure how to implement its fix. How do i trigger the closing of these files programmatically?
One of our servers is getting the "too many open files" error due to this.
After reading through the documentation more it seems like IdlePurgePolicy should be what I need but I do not see it having any effect on the number of open files. I tried the below line if a few difference places of my log4j2 file but as I mentioned, it had no effect
<IdlePurgePolicy timeToLive="1" timeUnit="minutes"/>
回答1:
If the wrapper itself is not instantiated statically, the logger instance will be created for each object invoking it. This might result in a new socket connection to the concrete logger instance each time. However, too many open sockets might also result in this exception while you are having only one logging file.
Possible solutions
- Instantiate the wrapper statically
- Instantiate the logger reference statically
- Make the wrapper a singleton with static invocation of the logging method
回答2:
IdlePurgePolicy did end up fixing this
<Routing name="ConferenceLog">
<Routes pattern="${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}"
fileName="${LOG_DIR}/conferences/${ctx:logFileName}.log"
filePattern="${LOG_DIR}/conferences/${ctx:logFileName}.%i.log.gz">
<PatternLayout pattern="${PATTERN}" />
<SizeBasedTriggeringPolicy size="20971520" />
</RollingFile>
</Route>
</Routes>
<IdlePurgePolicy timeToLive="30" timeUnit="seconds"/>
</Routing>
来源:https://stackoverflow.com/questions/47165886/too-many-open-files-due-to-log4j-config