How to implement auto archiving for log file using Log4Net

匆匆过客 提交于 2019-12-18 16:03:08

问题


I want to configure log4net in such a manner that all the previous day logs should be archived automatically. Is there any possibility to auto archive previous logs in Log4Net. I want to do this using the configuration only without writing any code using any third party library like sharplibzip to create archive.

One more thing to add by archiving i mean compressing file in zip/rar format to save disk space.


回答1:


It is not possible to archive files without writing code, sorry. However the code would not be very complicated.

You can create a custom appender inheriting from the RollingFileAppender, and override the AdjustFileBeforeAppend method in order to add behavior to the file rolling. Here is the existing method that rolls the file for the RollingFileAppender that you can override to add archiving.

Use the File property to find the file name process it

// 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
        }
    }
}

Alternatively you could find an existing appender that does what you want, but I don't know of any.


I'm taking the liberty of lifting @stuartd's comment into the answer since what he proposes is quite elegant. You can simply override the AdjustFileBeforeAppend in this way:

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

It is quite a neat way of doing it, but you may want to be able to differentiate between both kind of rolls (ie date and size). For example only zipping on date roll in order to keep the files for a date range together.




回答2:


log4net does not contain any functionality for compressing log files. However compression is in the .Net framework (since 4.5) or you could use the Windows Shell API to zip the files, so you would have code which periodically gets all the log files which aren't the current log file and zip them up:

-- 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



回答3:


This was my solution using DotNetZip reduced.

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();
        }
    }



回答4:


I want to point out that the only way to realize this properly is to entirely copy the RollingFileAppender source code and create a subclass of FileAppender from it. In this code, you can then add the compressing part in adjustFileBeforeAppend().

The suggestions by samy above do not work

  1. Because the first code snippet uses private members (which you cannot access in a subclass)
  2. Because the second code snippet assumes that the current log file name contains the date or so. But actually, the date pattern is only applied for all old files, not the current one. So you cannot determine if the file was rolled in the way shown in the snippet.


来源:https://stackoverflow.com/questions/26276296/how-to-implement-auto-archiving-for-log-file-using-log4net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!