2011-01-16 8 views
7

Próbuję skonfigurować plik log4j.xml w taki sposób, aby plik był formatowany po rozmiarze pliku, a nazwa zwiniętego pliku będzie taka: "C:/temp/badany/test_log4j-% d {rrrr MM-dD-HH_mm_ss} .log” I po dyskusji: http://web.archiveorange.com/archive/v/NUYyjJipzkDOS3reRiMzkonfiguracja log4j.xml za pomocą <rollingPolicy> i <triggeringPolicy>

Wreszcie pracował mi tylko wtedy, gdy dodaje się:

try { 
    Thread.sleep(1); 
    } catch (InterruptedException e) { 
    e.printStackTrace(); 
    } 

metody:

public boolean isTriggeringEvent(Appender appender, LoggingEvent event, 
      String filename, long fileLength) 

, które sprawiają, że działa.

Pytanie brzmi, czy istnieje lepszy sposób, aby działało? ponieważ ta metoda wielokrotnie wywołuje i spowalnia mój program.

Oto kod:

package com.mypack.rolling; 

import org.apache.log4j.rolling.RollingPolicy; 
import org.apache.log4j.rolling.RolloverDescription; 
import org.apache.log4j.rolling.TimeBasedRollingPolicy; 

/** 
* Same as org.apache.log4j.rolling.TimeBasedRollingPolicy but acts only as 
* RollingPolicy and NOT as TriggeringPolicy. 
* 
* This allows us to combine this class with a size-based triggering policy 
* (decision to roll based on size, name of rolled files based on time) 
* 
*/ 
public class CustomTimeBasedRollingPolicy implements RollingPolicy { 

TimeBasedRollingPolicy timeBasedRollingPolicy = new TimeBasedRollingPolicy(); 

/** 
    * Set file name pattern. 
    * @param fnp file name pattern. 
    */ 
public void setFileNamePattern(String fnp) { 
    timeBasedRollingPolicy.setFileNamePattern(fnp); 
} 
/* 
public void setActiveFileName(String fnp) { 
    timeBasedRollingPolicy.setActiveFileName(fnp); 
}*/ 

/** 
    * Get file name pattern. 
    * @return file name pattern. 
    */ 
public String getFileNamePattern() { 
    return timeBasedRollingPolicy.getFileNamePattern(); 
} 

public RolloverDescription initialize(String file, boolean append) throws SecurityException { 
    return timeBasedRollingPolicy.initialize(file, append); 
} 

public RolloverDescription rollover(String activeFile) throws SecurityException { 
    return timeBasedRollingPolicy.rollover(activeFile); 
} 

public void activateOptions() { 
    timeBasedRollingPolicy.activateOptions(); 
} 
} 



package com.mypack.rolling; 

import org.apache.log4j.helpers.OptionConverter; 
import org.apache.log4j.Appender; 
import org.apache.log4j.rolling.TriggeringPolicy; 
import org.apache.log4j.spi.LoggingEvent; 
import org.apache.log4j.spi.OptionHandler; 

/** 
* Copy of org.apache.log4j.rolling.SizeBasedTriggeringPolicy but able to accept 
* a human-friendly value for maximumFileSize, eg. "10MB" 
* 
* Note that sub-classing SizeBasedTriggeringPolicy is not possible because that 
* class is final 
*/ 
public class CustomSizeBasedTriggeringPolicy implements TriggeringPolicy, OptionHandler { 

/** 
    * Rollover threshold size in bytes. 
    */ 
private long maximumFileSize = 10 * 1024 * 1024; // let 10 MB the default max size 

/** 
    * Set the maximum size that the output file is allowed to reach before 
    * being rolled over to backup files. 
    * 
    * <p> 
    * In configuration files, the <b>MaxFileSize</b> option takes an long 
    * integer in the range 0 - 2^63. You can specify the value with the 
    * suffixes "KB", "MB" or "GB" so that the integer is interpreted being 
    * expressed respectively in kilobytes, megabytes or gigabytes. For example, 
    * the value "10KB" will be interpreted as 10240. 
    * 
    * @param value 
    *   the maximum size that the output file is allowed to reach 
    */ 
public void setMaxFileSize(String value) { 
    maximumFileSize = OptionConverter.toFileSize(value, maximumFileSize + 1); 
} 

public long getMaximumFileSize() { 
    return maximumFileSize; 
} 

public void setMaximumFileSize(long maximumFileSize) { 
    this.maximumFileSize = maximumFileSize; 
} 

public void activateOptions() { 
} 

public boolean isTriggeringEvent(Appender appender, LoggingEvent event, 
      String filename, long fileLength) { 
    try { 
    Thread.sleep(1); 
    } catch (InterruptedException e) { 
    e.printStackTrace(); 
    } 

    boolean result = (fileLength >= maximumFileSize); 

    return result; 
} 

} 

i log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> 

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true"> 
<appender name="console" class="org.apache.log4j.ConsoleAppender"> 
    <param name="Target" value="System.out" /> 
    <layout class="org.apache.log4j.PatternLayout"> 
    <param name="ConversionPattern" value="%d [%t] %-5p %c -> %m%n" /> 
    </layout> 
</appender> 

<appender name="FILE" class="org.apache.log4j.rolling.RollingFileAppender"> 
    <param name="file" value="C:/temp/test/test_log4j.log" /> 
    <rollingPolicy class="com.mypack.rolling.CustomTimeBasedRollingPolicy"> 
    <param name="fileNamePattern" value="C:/temp/test/test_log4j-%d{yyyy-MM-dd-HH_mm_ss}.log" /> 
    </rollingPolicy> 
    <triggeringPolicy class="com.mypack.rolling.CustomSizeBasedTriggeringPolicy"> 
    <param name="MaxFileSize" value="200KB" /> 
    </triggeringPolicy> 
    <layout class="org.apache.log4j.PatternLayout"> 
    <param name="ConversionPattern" value="%d [%t] %-5p %c -> %m%n" /> 
    </layout> 
</appender> 

<logger name="com.mypack.myrun" additivity="false"> 
    <level value="debug" /> 
    <appender-ref ref="FILE" /> 
</logger> 

<root> 
    <priority value="debug" /> 
    <appender-ref ref="console" /> 
</root> 

</log4j:configuration> 

Odpowiedz

0

Jeśli dodać wyjście debugowania metody, widać, że metoda nazywa się bardzo często, nawet po uruchomieniu wyzwalacza, ale rozmiar pliku jest wciąż większy niż maksymalny rozmiar pliku.

Zakładam, że zachowanie przechyłowe ma jakiś bufor, który jest opróżniany przed faktycznym najazdem (synchronicznym?).

Myślę, że ma to coś wspólnego z fileNamePattern w com.mypack.rolling.CustomTimeBasedRollingPolicy. Dopóki "sekunda" w nazwie pliku nie ulegnie zmianie, metoda CustomSizeBasedTriggeringPolicy.isTriggeringEvent jest stale wywoływana z wartościami większymi niż maksymalny rozmiar pliku.

0

Dziękuję za odpowiedź.

zrobiłem 2 zmiany:
1) dodam milisekund do wzorca nazwy pliku:

<param name="fileNamePattern" value="C:/temp/test/test_log4j-%d{yyyy-MM-dd-HH_mm_ss_SSS}.log" /> 

2) Zmieniłem

com.mypack.rolling.CustomSizeBasedTriggeringPolicy.isTriggeringEvent 

do

public boolean isTriggeringEvent(Appender appender, LoggingEvent event, 
               String filename, long fileLength) { 

     boolean result = (fileLength >= maximumFileSize); 

     if (result) { 
      try { 
       Thread.sleep(1); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     return result; 
    } 

więc teraz , Thread.sleep (1) jest wywoływany tylko wtedy, gdy tworzony jest nowy plik (zwijany).

Powiązane problemy