2014-10-09 13 views
7

Chcę skonfigurować log4net w taki sposób, aby wszystkie dzienniki poprzedniego dnia były archiwizowane automatycznie. Czy istnieje możliwość automatycznego archiwizowania poprzednich logów w Log4Net. Chcę to zrobić tylko za pomocą konfiguracji bez pisania kodu za pomocą dowolnej biblioteki zewnętrznej, takiej jak sharplibzip, w celu utworzenia archiwum.Jak zaimplementować automatyczną archiwizację pliku dziennika przy użyciu Log4Net

Jeszcze jedna rzecz do dodania przez archiwizację, to znaczy kompresowanie pliku w formacie zip/rar, aby zaoszczędzić miejsce na dysku.

Odpowiedz

2

log4net nie zawiera żadnej funkcji kompresowania plików dziennika. Jednak kompresja jest w środowisku .Net (od wersji 4.5) lub możesz użyć the Windows Shell API do spakowania plików, więc będziesz mieć kod, który okresowo pobiera wszystkie pliki dziennika, które nie są bieżącym plikiem dziennika i zip je:

-- assuming you don't have more that one appender 
appender = LogManager.GetRepository().GetAppenders() 
        .OfType<RollingFileAppender>().FirstOrDefault(); 

if (appender == null) return; // no appenders found 

var currentFile = appender.File; 

-- dropping to pseudocode: 
var files = Get_all_files_in_log_directory_which_match_log_file_pattern 
     but_aren't_the_current_file(current file); 

if (ZipFiles(files...)) 
    (DeleteFiles(files); // presumably 
4

Nie można archiwizować plików bez pisania kodu, przepraszam. Jednak kod nie byłby bardzo skomplikowany.

Możesz utworzyć niestandardowego aplikanta dziedziczącego po RollingFileAppender i zastąpić metodę AdjustFileBeforeAppend w celu dodania zachowania do toczenia pliku. Oto istniejąca metoda, która wyrzuca plik dla pliku RollingFileAppender, który można przesłonić, aby dodać archiwizację.

Użyj właściwości File znaleźć proces nazwa pliku to

// log4net.Appender.RollingFileAppender 
protected virtual void AdjustFileBeforeAppend() 
{ 
    var fileToZip = File; // save the current file 
    if (this.m_rollDate) 
    { 
     DateTime now = this.m_dateTime.Now; 
     if (now >= this.m_nextCheck) 
     { 
      this.m_now = now; 
      this.m_nextCheck = this.NextCheckDate(this.m_now, this.m_rollPoint); 
      this.RollOverTime(true); 
      // zip the file if roll occurs here 
     } 
    } 
    if (this.m_rollSize) 
    { 
     if (this.File != null && ((CountingQuietTextWriter)base.QuietWriter).Count >= this.m_maxFileSize) 
     { 
      this.RollOverSize(); 
      // zip the file if roll occurs here 
     } 
    } 
} 

Alternatywnie można znaleźć istniejący appender, że robi to, co chcesz, ale ja nie znam żadnego.


Wolę podnosić komentarz @ stuartda do odpowiedzi, ponieważ to, co proponuje, jest dość eleganckie. można po prostu zastąpić AdjustFileBeforeAppend w ten sposób:

protected override void AdjustFileBeforeAppend() { 
    var previousFile = File; 
    base.AdjustFileBeforeAppend(); 
    if (File != previousFile) { // zip the file } 
} 

Jest całkiem zgrabny sposób to zrobić, ale może chcesz być w stanie rozróżnić obu rodzajów bułek (czyli data i rozmiar). Na przykład tylko skompresowanie daty w celu zachowania plików dla zakresu dat.

+4

Aby uniknąć konieczności wymiany istniejącego kodu w sposób, który nie jest najlepszy pomysł na dłuższą metę może to być zrobione tak: protected override void AdjustFileBeforeAppend() { var previousFile = Plik; base.AdjustFileBeforeAppend(); if (File! = PreviousFile) { // zip plik } } – stuartd

+0

To bardzo dobry pomysł! Myślę, że nie zaszkodzi rozróżniać między toczeniem rozmiaru a datowaniem, ponieważ możesz chcieć skompresować pliki na ten sam dzień razem. Szkoda, że ​​nie możemy nagradzać komentatorów – samy

+2

log4net jest zainspirowany log4j. Następca log4j nazywa się logback i ma wbudowane skompresowanie w konfiguracji, więc ma dokładnie to, czego ty (i ja) chcesz. Teraz potrzebujemy inspirowanego zespołu do napisania logback.NET! –

0

To było moje rozwiązanie przy użyciu zmniejszonej DotNetZip.

public class CustomRollingFileAppender : RollingFileAppender 
    { 
     protected override void AdjustFileBeforeAppend() 
     { 
      var currentFile = File; 

      FileInfo fa = new System.IO.FileInfo(currentFile); 

      if (fa.Length >= 10000000) 
      { 
       using (ZipFile zip = new ZipFile(File + ".zip")) 
       { 
        string newFile = DateTime.Now.ToString("HHmmss") + fa.Name; 
        zip.AddFile(File).FileName = newFile; 
        zip.Save(File + ".zip"); 
       } 
      } 

      base.AdjustFileBeforeAppend(); 
     } 
    } 
+1

Rozwiązanie robocze, ale moim zdaniem ma koszmarny narzut wydajności z powodu wywoływania FileInfo dla każdego rozwiązania write.samys wydaje się znacznie bardziej przyjazne dla io ;-) –

Powiązane problemy