Log4j'de, bir FileAppender'ı BufferedIO = true ve BufferSize = xxx özellikleriyle kullanırken (yani, arabelleğe alma etkinleştirilmişse), normal kapatma yordamı sırasında günlüğü temizleyebilmeyi istiyorum. Bunu nasıl yapacağınız hakkında bir fikrin var mı?Tamponlu bir log4j FileAppender'ı nasıl temizlersiniz?
cevap
public static void flushAllLogs()
{
try
{
Set<FileAppender> flushedFileAppenders = new HashSet<FileAppender>();
Enumeration currentLoggers = LogManager.getLoggerRepository().getCurrentLoggers();
while(currentLoggers.hasMoreElements())
{
Object nextLogger = currentLoggers.nextElement();
if(nextLogger instanceof Logger)
{
Logger currentLogger = (Logger) nextLogger;
Enumeration allAppenders = currentLogger.getAllAppenders();
while(allAppenders.hasMoreElements())
{
Object nextElement = allAppenders.nextElement();
if(nextElement instanceof FileAppender)
{
FileAppender fileAppender = (FileAppender) nextElement;
if(!flushedFileAppenders.contains(fileAppender) && !fileAppender.getImmediateFlush())
{
flushedFileAppenders.add(fileAppender);
//log.info("Appender "+fileAppender.getName()+" is not doing immediateFlush ");
fileAppender.setImmediateFlush(true);
currentLogger.info("FLUSH");
fileAppender.setImmediateFlush(false);
}
else
{
//log.info("fileAppender"+fileAppender.getName()+" is doing immediateFlush");
}
}
}
}
}
}
catch(RuntimeException e)
{
log.error("Failed flushing logs",e);
}
}
Dene:
LogManager.shutdown();
tüm tamponlu günlükleri kızardı olsun:
LogFactory.releaseAll();
Bunun çağrılmasının maalesef bir etkisi yoktu. – Amos
:-)
LogManager kapatılıyor
kendi soruyu cevaplamak için Yönetilen.Lütfen bunu cevap olarak seçin - açıkça en güzel seçenek. Kendini hak ettiysen, yeşil bir kene çıkarmaktan çekinme. –
bu en iyi cevap gibi görünüyor ... ama bu "LogManager" nesnesine nasıl erişiyorsunuz? (log4php acemi) –
o log4j.flush.now
gibi özel bir günlüğü kategorisi için true
dönecekti böylece Belki, WriterAppender#shouldFlush(LoggingEvent)
geçersiz olabilir, ve aramak:
LoggerFactory.getLogger("log4j.flush.now").info("Flush")
Bir appender yazdım Bunu düzeltir, bkz. GitHub veya name.wramner.log4j: Maven'deki FlushAppender'ı kullanın. Yüksek önem derecesine sahip olayları temizlemek için yapılandırılabilir ve belirli bir mesaj aldığında, örneğin "Kapanıyor" gibi eklerin arabelleğe alınmasını engelleyebilir. Konfigürasyon örnekleri için ünite testlerini kontrol edin. Elbette özgürdür.
public static void flushAll() {
final LoggerContext logCtx = ((LoggerContext) LogManager.getContext());
for(final org.apache.logging.log4j.core.Logger logger : logCtx.getLoggers()) {
for(final Appender appender : logger.getAppenders().values()) {
if(appender instanceof AbstractOutputStreamAppender) {
((AbstractOutputStreamAppender) appender).getManager().flush();
}
}
}
}
Bu kod soruyu yanıtlarken, sorunun nasıl ve/veya neden çözüldüğüne ilişkin ek bağlam sağlayarak yanıtın uzun vadeli değerini artıracaktır. –
Bu kod yalnızca tüm atılabilir ekleri temizlemeyi deniyor (tüm "fışkırtma" yönteminin bildirildiği "AbstractOutputStreamAppender" ifadesini genişleten tüm ekleyiciler). Projemde Log4J2 v2.8.2 ile bunu kullanıyorum. –
Log4J, normal kapanma sırasında ekleyiciyi otomatik olarak temizlemiyor mu? En azından bunu yapmasını beklerdim. –
Kodu anladığım kadarıyla - BufferedIO'ya karar verirken kızarma yok. Performans kazanıyorsunuz ama bir fiyat ödüyorsunuz: son kayıt girişlerini kaybedersiniz ... –
Kendi ekleyicimi (DB'ye yazdım ama gerçekten önemli değil) yazdığımda, her birkaç saniyede bir otomatik olarak fışkırırken çıktıda tamponlama yaptım. – ripper234