使用Quartz.Net定时删除Log

时间:2019-08-13
本文章向大家介绍使用Quartz.Net定时删除Log,主要包括使用Quartz.Net定时删除Log使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Log4Net是我们经常使用的记log框架,但是最近发现了两个问题:

1. 按日期(rollingStyle)生成的文件没有自动删除(MaxSizeRollBackups);(按大小生成的会自动删除)

2. 如果按混合(Composite)生成的文件,在程序重启后,.1之后的文件会被重写,.0文件是appendToFile。(按日期和按大小生成的不存在该问题)

该文章主要就是解决第1个问题,通过写程序定期执行的方式,删除过期的log文件夹。可以使用定时器完成,但是我为了学习使用Quartz.Net,所以用了该框架来实现。

参考文档:

  1. C#实现定时删除日志文件夹及文件夹下文件

我们记录的日志是按天生成文件夹(yyyyMMdd),文件夹里按小时生成log(HH.log)。
所以删除过期日志时可以直接删除文件夹。
删除文件/文件夹使用语言自带的类库(System.IO)即可。

  2. C# 中字符串转换成日期

我们可以根据文件夹的创建日期来决定是否删除,也可以根据文件夹的名称来判断。
DateTime.Pares()转换对string有格式要求。
可以使用该方法来转换:
DateTime.ParseExact(dateString, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture)

  3. c# 获取当前程序运行根目录

为了增强程序的适用性,我们判断过期文件夹的路径是从webconfig获取的log4net的设置路径。
如果xml.Load()的属性直接写Web.Config,程序会报错:C:\Program Files (x86)\IIS Express\Web.Config不存在。可以指定绝对路径。
因为我们是在MVC WEB程序,所以使用下述方法获取Web应用程序的根目录。
System.Web.HttpRuntime.AppDomainAppPath

  4. C#的.Net作业调度(一) -Quartz.Net入门

  5. Quartz.NET实现作业调度

  6. 基于ASP.NET MVC(C#)和Quartz.Net组件实现的定时执行任务调度

参考文档4和5是Quartz.Net的入门案例。
参考文档6是在MVC中使用Quartz.Net。
但是最新的Quartz.Net使用方法和前3篇播客中的有变化,引入了异步机制,参考文档7是对此的案列。

  7. .Net Core中使用Quartz.Net实践记录

参考上述文档,我的代码实现如下:

<log4net>
        <appender name="infoLog" type="log4net.Appender.RollingFileAppender,log4net">
            <!--日志文件路径,按文件大小方式输出时在这里指定文件名,并且前面的日志按天在文件名后自动添加当天日期形成文件-->
            <file value="Log\LogInfo\" />
            <!--是否是向文件中追加日志-->
            <appendToFile value="true" />
            <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
            <rollingStyle value="Date" />
            <!--每个文件的大小。只在混合方式与文件大小方式下使用,超出大小的在文件名后自动增加1重新命名-->
            <param name="maximumFileSize" value="10MB" />
            <!--按日期产生文件,文件名[在日期方式与混合方式下使用]日志文件名格式为:20190809-info.log -->
            <datePattern value="yyyyMMdd\\'LogInfo'HH'.log'" />
            <!--日志文件名是否是固定不变的(是否只写到一个文件中)-->
            <staticLogFileName value="false" />
            <!--扩展名-->
            <!--<preserveLogFileNameExtension value="true" />-->
            <!--设置文件的编号顺序-->
            <!--<countDirection value="1" />-->
            <!--log保留天数-->
            <param name="MaxSizeRollBackups" value="-1" />
            <!--记录的格式。-->
            <layout type="log4net.Layout.PatternLayout">
                <param name="Header" value="=========================================================&#xD;&#xA;" />
                <conversionPattern value="%d [%t] %-5p %c [%class]-[%M] - %m%n" />
                <param name="Footer" value="=========================================================&#xD;&#xA;" />
            </layout>
        </appender>
        <root>
            <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
            <level value="ALL" />
            <appender-ref ref="infoLog"/>
        </root>
    </log4net>
log4net配置档
namespace DeleteLog
{
    public class DeleteLogJobScheduler
    {
        public static async Task Start()
        {
            //获取web.config中log的路径
            XmlDocument xml = new XmlDocument();
            string webConfig = HttpRuntime.AppDomainAppPath + "Web.config";
            xml.Load(webConfig);
            XmlNode log4netNode = (xml.GetElementsByTagName("file"))[0];
            string logDirectory = ((XmlElement)log4netNode).GetAttribute("value");

            ISchedulerFactory factory = new StdSchedulerFactory();
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<DeleteLogDirectory>()
                .WithIdentity("myJob", "group1")
                .UsingJobData("directory", logDirectory)
          //保存周期30天 .UsingJobData(
"expire", 30) .Build(); ITrigger trigger = TriggerBuilder.Create() .WithIdentity("myTrigger", "group1") .StartNow()
          //一天执行一次 .WithSimpleSchedule(x
=> x .WithIntervalInHours(24) .RepeatForever()) .Build(); await scheduler.ScheduleJob(job, trigger); } } public class DeleteLogDirectory : IJob { Task IJob.Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; string logDirectory = HttpRuntime.AppDomainAppPath + dataMap.GetString("directory"); int logExpire = dataMap.GetInt("expire"); DateTime nowTime = DateTime.Now; DirectoryInfo root = new DirectoryInfo(logDirectory); DirectoryInfo[] dics = root.GetDirectories(); FileAttributes attr = File.GetAttributes(logDirectory); return Task.Run(() => { if (attr == FileAttributes.Directory) { foreach (DirectoryInfo dic in dics) { try { TimeSpan t = nowTime - DateTime.ParseExact(dic.Name, "yyyyMMdd", CultureInfo.CurrentCulture); int day = t.Days; if (day > logExpire) { Directory.Delete(dic.FullName, true); } } catch (Exception) { } } } }); } } }
//MVC中调用前文定义的任务调度
namespace DeleteLog
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            log4net.Config.XmlConfigurator.Configure(new FileInfo("Web.config"));
            DeleteLogJobScheduler.Start();

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }  
}

原文地址:https://www.cnblogs.com/lq67/p/11348421.html