zoukankan      html  css  js  c++  java
  • Quartz任务调度 服务日志+log4net打印日志+制作windows服务

    引言

      现在许多的项目都需要定时的服务进行支撑,而我们经常用到的定时服务就是Quartz任务调度了。不过我们在使用定时Job进行获取的时候,有时候我们就需要记录一下自定义的日志,甚至我们还会对执行定时Job脚本中,本身的线程启动和触发器等相关信息进行记录,这就用到了Common.Logging.log4net了,但同时它在控制台上输出相应信息的同时,并不能对这些信息进行日志文件的记录与存储。

      有关log4net的相关使用,详情请看之前的博文:http://www.cnblogs.com/huanghzm/p/4754890.html

      而本文的主要目的就是处理Quartz系统日志与log4net的相互结合,最后附带说明了利用Topshlef坐直windows服务。

    准备

      1、安装指定的程序包

      Install-Package Quartz

      Install-Package Common.Logging.Log4Net1211(安装这个的时候会自定安装其依赖项,即Log4Net)

      Install-Package Topshelf

      2、配置文件设置

    <configSections>
        <sectionGroup name="common">
          <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
        </sectionGroup>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
      </configSections>
    
    
    <common>
        <logging>
          <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net1211">
            <arg key="configType" value="INLINE" />
          </factoryAdapter>
        </logging>
      </common>
    
      <log4net>
        <!--错误日志-->
        <!--自定义错误异常-->
        <appender name="CustomExAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\LogCustomEx\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\yyyyMM\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n日志描述:%message%newline %n" />
          </layout>
        </appender>
    
        <appender name="ErrorExAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\LogErrorEx\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\yyyyMM\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n日志描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--CustomEx日志-->
        <logger name="LogCustomEx">
          <level value="INFO" />
          <appender-ref ref="CustomExAppender" />
        </logger>
        <!--Error日志-->
        <logger name="LogErrorEx">
          <level value="ERROR" />
          <appender-ref ref="ErrorExAppender" />
        </logger>
    
        <!--服务执行日志-->
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\ServerLog\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\yyyyMM\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
          </layout>
        </appender>
    
        <!-- 控制台前台显示日志 -->
        <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
          <mapping>
            <level value="ERROR" />
            <foreColor value="Red, HighIntensity" />
          </mapping>
          <mapping>
            <level value="Info" />
            <foreColor value="Green" />
          </mapping>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
          </layout>
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="Info" />
            <param name="LevelMax" value="Fatal" />
          </filter>
        </appender>
    
        <root>
          <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
          <level value="all" />
          <appender-ref ref="ColoredConsoleAppender"/>
          <appender-ref ref="RollingLogFileAppender"/>
        </root>
    
      </log4net>
    App.Config

    让世界跑起来

      1、配置相关Job类(JobInfo[对象]、JobType[类型]、JobInfoList[触发器、时间]) 名称、触发器、群组、类型(根据不同的类型执行不同的Job内容)

    public class JobInfo
        {
            public JobInfo(string jobName, string group, string trigger, JobType jobType)
            {
                if (jobName == null || trigger == null || group == null)
                {
                    throw new ArgumentNullException("jobName");
                }
                this.JobName = jobName;
                this.Trigger = trigger;
                this.Group = group;
                this.JobType = jobType;
            }
    
            /// <summary>
            /// 名称
            /// </summary>
            public string JobName { get; set; }
    
            /// <summary>
            /// Job的触发器  cron表达式
            /// </summary>
            public string Trigger { get; set; }
    
            /// <summary>
            /// 群组
            /// </summary>
            public string Group { get; set; }
    
            /// <summary>
            /// Job类型
            /// </summary>
            public JobType JobType { get; set; }
        }
    
        /// <summary>
        /// Job类型枚举
        /// </summary>
        public enum JobType
        {
            /// <summary>
            /// 任务1
            /// </summary>
            Job1 = 1,
            /// <summary>
            /// 任务2
            /// </summary>
            Job2 = 2
        }
    JobInfo
    public class JobInfoList
        {
            /// <summary>
            /// 脚本服务组
            /// </summary>
            public static List<JobInfo> JobList_ZhongShanHos = new List<JobInfo>
            {
                new JobInfo("任务1", "测试脚本", "*/5 * * * * ?", JobType.Job1),
                new JobInfo("任务2", "测试脚本", "*/7 * * * * ?", JobType.Job2)
                
            };
        }
    JobInfoList

      2、配置具体的Job内容与需要输出的自定义日志,这里的日志使用log4net作为记录 (TestJob.cs)

    public class TestJob : IJob
        {
            private static readonly log4net.ILog LogInfo = log4net.LogManager.GetLogger("LogCustomEx");
            private static readonly log4net.ILog LogError = log4net.LogManager.GetLogger("LogError");
    
            public void Execute(IJobExecutionContext context)
            {
                var map = context.JobDetail.JobDataMap;
                var jobInfo = map["KEY"] as JobInfo;
                if (jobInfo == null) { return; }
    
                //记录日志
                LogInfo.Info("
    【服务已启动】" + "
    【启动组】:" + jobInfo.Group + "
    【启动名称】:" + jobInfo.JobName + "
    【启动时间】:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
    
                try
                {
                    switch (jobInfo.JobType)
                    {
                        //基础信息
                        case JobType.Job1: LogInfo.Info("这是任务1"); break;
                        case JobType.Job2: LogInfo.Info("这是任务2"); break;
    
                        default: break;
                    }
                }
                catch (Exception ex)
                {
                    //记录日志
                    LogError.Error("
    【服务执行出错】" +
                                  "
    【启动组】:" + jobInfo.Group +
                                  "
    【启动名称】:" + jobInfo.JobName +
                                  "
    【时间】:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
                                  "
    【错误信息】:" + ex.Message);
                    return;
                }
            }
        }
    TestJob

      3、配置Job执行方法

    public sealed class ServerRunner : ServiceControl, ServiceSuspend
        {
            private readonly IScheduler scheduler;
    
            public ServerRunner()
            {
                scheduler = StdSchedulerFactory.GetDefaultScheduler();
            }
    
            public bool Start(HostControl hostControl)
            {
                var jobList = new List<JobInfo>();
    
                //配置JobList任务
                jobList.AddRange(JobInfoList.JobList_ZhongShanHos);
    
                jobList.ForEach(
                    x =>
                    {
                        var dic = new Dictionary<string, JobInfo> { { "KEY", x } };
                        var map = new JobDataMap(dic);
                        var job =
                            JobBuilder.Create<TestJob>()
                                .WithIdentity(x.JobName, x.Group)
                                .UsingJobData(map)
                                .RequestRecovery()
                                .Build();
                        var trigger =
                            TriggerBuilder.Create()
                                .WithIdentity(x.JobName, x.Group)
                                .WithCronSchedule(x.Trigger)
                                .Build();
                        scheduler.ScheduleJob(job, trigger);
                    });
                scheduler.Start();
                return true;
            }
    
            public bool Stop(HostControl hostControl)
            {
                scheduler.Shutdown(false);
                return true;
            }
    
            public bool Continue(HostControl hostControl)
            {
                scheduler.ResumeAll();
                return true;
            }
    
            public bool Pause(HostControl hostControl)
            {
                scheduler.PauseAll();
                return true;
            }
        }
    ServerRunner

      4、配置入口文件

    class Program
        {
            static void Main(string[] args)
            {
                //配置Log4日志
                log4net.Config.XmlConfigurator.Configure();
    
                //Windows服务
                HostFactory.Run(x =>
                {
                    x.UseLog4Net();
    
                    x.Service<ServerRunner>();
    
                    x.SetDescription("Quartz日志记录服务");
                    x.SetDisplayName("Quartz");
                    x.SetServiceName("QuartzLog");
    
                    x.EnablePauseAndContinue();
                });
            }
        }
    Program

      至此,基本的所有配置就这样完成了,只要运行,就可以看到对应的服务的信息了。

      

      日志信息也记录在对应的(前面说设计的文档中)按照相面的代码选定的地址是根目录文件,如图所示:

    windows服务

      制作windows服务,非常简单,只要调出cmd命令行,cd到指定文件的目录,输入应用程序名+install就可以,卸载的话就输入uninstall就可以了。如图所示:

    源代码地址:GitHub

    链接:https://github.com/JaminHuang/QuartzLog.git

    真正的谦卑是对真理持续不断的追求。
  • 相关阅读:
    你看那个人他像一条狗
    jvm系列(八):jvm知识点总览
    jvm系列(七):jvm调优-工具篇
    百亿互金平台救火故事
    一个脚本引发的血案
    一次dns缓存引发的惨案
    一次生产事故的优化经历
    从零到百亿互联网金融架构发展史
    2016颠倒梦想,2017静心前行
    Spring Boot(九):定时任务
  • 原文地址:https://www.cnblogs.com/huanghzm/p/5892703.html
Copyright © 2011-2022 走看看