• 使用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 ExpressWeb.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="LogLogInfo" />
                <!--是否是向文件中追加日志-->
                <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);
            }
        }  
    }
  • 相关阅读:
    Requests
    探索式测试(概念)
    IDEA_Java+maven+selenium3+testng自动化测试环境安装
    RobotFramework Formate
    Robot Framework_dictionary search
    Git
    配置robotframework框架的自动化环境
    Python学习之路
    对 Jenkins+ANT+Jmeter 接口测试的实践
    自动生成测试脚本方案浅析
  • 原文地址:https://www.cnblogs.com/lq67/p/11348421.html
Copyright © 2020-2023  润新知