创建基于日期的Log4net滚动文件

问题描述 投票:0回答:1

我需要为45个不同的位置创建文件(例如:波士顿,伦敦等)。这些文件名必须基于日期。我也可以提供最大文件大小来滚动文件和要滚动的最大文件数。

基本上文件名必须如下所示:Info_Boston_(2019.02.25).txt

到目前为止,我已经提出了以下代码来获取日期。但我无法将文件大小限制为1MB。该文件增长超过1MB,并且不会创建新的滚动文件。请协助

    <appender name="MyAppenderInfo" type="log4net.Appender.RollingFileAppender">
  <param name="File" value="C:\\ProgramData\\Service\\Org\\Info"/>
  <param name="RollingStyle" value="Date"/>
  <param name="DatePattern" value="_(yyyy.MM.dd).\tx\t"/>
  <param name="StaticLogFileName" value="false"/>
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="1MB" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date %message%n" />
  </layout>
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="DEBUG" />
    <levelMax value="INFO" />
  </filter>
</appender>
date dynamic log4net
1个回答
0
投票

为了解决你的具体帖子,我不会用基于配置的方法做到这一点,因为我认为管理会相当麻烦。更具编程性的方法是动态生成日志记录实例。

编辑:我取下原来发布这个重新设计的例子基于这个SO帖子log4net: different logs on different file appenders at runtime

EDIT-2:我不得不重新做这件事,因为我意识到我省略了一些必要的部件,并且在返工后出了点问题。这是经过测试和运作的。但是,需要注意的一点是,您需要在控制器上提供using语句,以及您所做的日志记录类。接下来,您需要像我一样完成DI日志记录目录,或者提供另一种提供日志文件输出列表的方法。

这将允许您非常干净地动态生成所需数量的日志记录实例,以及您想要的多个独立位置。我从我做过的项目中提取了这个例子,并根据你的需要进行了一些修改。如果您有疑问,请告诉我。

创建一个动态记录器类,它继承自层次结构中的基本记录器:

using log4net;
using log4net.Repository.Hierarchy;

public sealed class DynamicLogger : Logger
{
    private const string REPOSITORY_NAME = "somename";
    internal DynamicLogger(string name) : base(name)
    {
        try
        {
            // try and find an existing repository
            base.Hierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(REPOSITORY_NAME);
        }   // try
        catch
        {
            // it doesnt exist, make it.
            base.Hierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.CreateRepository(REPOSITORY_NAME);
        }   // catch
    }   // ctor(string)
}   // DynamicLogger

然后,构建一个类来管理日志记录实例,并构建新的记录器:

using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Filter;
using log4net.Layout;
using log4net.Repository;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq;

public class LogFactory
{
    private static List<ILog> _Loggers = new List<ILog>();
    private static LoggingConfig _Settings;
    private static ILoggerRepository _Repository;

    public LogFactory(IOptions<LoggingConfig> configuration)
    {
        _Settings = configuration.Value;
        ConfigureRepository(REPOSITORY_NAME);
    }   // ctor(IOptions<LoggingConfig>)

    /// <summary>
    /// Configures the primary logging repository.
    /// </summary>
    /// <param name="repositoryName">The name of the repository.</param>
    private void ConfigureRepository(string repositoryName)
    {
        if(_Repository == null)
        {
            try
            {
                _Repository = LogManager.CreateRepository(repositoryName);
            }
            catch
            {
                // repository already exists.
                _Repository = LogManager.GetRepository(repositoryName);
            }   // catch
        }   // if
    }   // ConfigureRepository(string)

    /// <summary>
    /// Gets a named logging instance, if it exists, and creates it if it doesnt.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public ILog GetLogger(string name)
    {
        string filePath = string.Empty;

        switch (name)
        {
            case "core":
                filePath = _Settings.CoreLoggingDirectory;
                break;
            case "image":
                filePath = _Settings.ImageProcessorLoggingDirectory;
                break;
        }   // switch

        if (_Loggers.SingleOrDefault(a => a.Logger.Name == name) == null)
        {
            BuildLogger(name, filePath);
        }   // if

        return _Loggers.SingleOrDefault(a => a.Logger.Name == name);
    }   // GetLogger(string)

    /// <summary>
    /// Dynamically build a new logging instance.
    /// </summary>
    /// <param name="name">The name of the logger (Not file name)</param>
    /// <param name="filePath">The file path you want to log to.</param>
    /// <returns></returns>
    private ILog BuildLogger(string name, string filePath)
    {
        // Create a new filter to include all logging levels, debug, info, error, etc.
        var filter = new LevelMatchFilter();
        filter.LevelToMatch = Level.All;
        filter.ActivateOptions();

        // Create a new pattern layout to determine the format of the log entry.
        var pattern = new PatternLayout("%d %-5p %c %m%n");
        pattern.ActivateOptions();

        // Dynamic logger inherits from the hierarchy logger object, allowing us to create dynamically generated logging instances.
        var logger = new DynamicLogger(name);
        logger.Level = Level.All;

        // Create a new rolling file appender
        var rollingAppender = new RollingFileAppender();
        // ensures it will not create a new file each time it is called.
        rollingAppender.AppendToFile = true;
        rollingAppender.Name = name;
        rollingAppender.File = filePath;
        rollingAppender.Layout = pattern;
        rollingAppender.AddFilter(filter);
        // allows us to dynamically generate the file name, ie C:\temp\log_{date}.log
        rollingAppender.StaticLogFileName = false;
        // ensures that the file extension is not lost in the renaming for the rolling file
        rollingAppender.PreserveLogFileNameExtension = true;
        rollingAppender.DatePattern = "yyyy-MM-dd";
        rollingAppender.RollingStyle = RollingFileAppender.RollingMode.Date;
        // must be called on all attached objects before the logger can use it.
        rollingAppender.ActivateOptions();
        logger.AddAppender(rollingAppender);

        // Sets the logger to not inherit old appenders, or the core appender.
        logger.Additivity = false;
        // sets the loggers effective level, determining what level it will catch log requests for and log them appropriately.
        logger.Level = Level.Info;
        // ensures the new logger does not inherit the appenders of the previous loggers.
        logger.Additivity = false;

        // The very last thing that we need to do is tell the repository it is configured, so it can bind the values.
        _Repository.Configured = true;

        // bind the values.
        BasicConfigurator.Configure(_Repository, rollingAppender);

        LogImpl newLog = new LogImpl(logger);


        _Loggers.Add(newLog);

        return newLog;
    }   // BuildLogger(string, string)
}   // LogFactory

然后,在您的依赖注入中,您可以注入您的日志工厂。你可以这样做:

services.AddSingleton<LogFactory>();

然后在您的控制器或任何构造函数中,您可以执行以下操作:

    private LogFactory _LogFactory;

    public HomeController(LogFactory logFactory){
        _LogFactory = logFactory;
    }

    public async Task<IActionResult> Index()
    {
        ILog logger1 = _LogFactory.GetLogger("core");
        ILog logger2 = _LogFactory.GetLogger("image");
        logger1.Info("SomethingHappened on logger 1");
        logger2.Info("SomethingHappened on logger 2");
        return View();
    }

这个例子将输出:

2019-03-07 10:41:21,338 INFO  core SomethingHappened on logger 1

在自己的文件名为Core_2019-03-07.log

并且:

2019-03-07 11:06:29,155 INFO  image SomethingHappened on logger 2

在自己的文件名为Image_2019-03-07

希望更有意义!

© www.soinside.com 2019 - 2024. All rights reserved.