一、简介

    最近在做一个项目的时候,需要该项目自动启动、自动运行,不需要认为干预。不用说,大家都知道用什么技术,那就是 Windows服务。在以前的Net Framework 平台下,Windows 服务是一个不错的选择。如果现在在Net Core版本,或者Net5.0以及以上版本,我们会有另外一个选择,这就是 Worker Service,中文叫:辅助角色服务。它使用起来,维护起来更方便。话好像有点跑题了。我们言归正传,当我们做了一个Windows服务的进程来承载程序,还有另外一个工作需要做。那就是需要让我们的服务程序告诉我们,程序是否运行正常,干了什么,没有干什么,执行了哪些步骤,说道这些,就是我们所说的,要给Windows服务增加日志功能。

    为了给Windows服务增加日志功能,我们今天选择了两个日志组件,第一:EventLog,第二:Log4net。

    开发环境:

        开发工具:Visual Studio 2019

        开发语言:C#

二、具体操作

    1、为项目增加 EventLog 功能

        1.1、创建 Windows 服务项目。

            我们打开 Visual Studio 2019,在首页上选择“创建新项目”

            

            点击《创建新项目》,进入《创建新项目》窗体,可以在左侧选择使用过的模板,也可以在右侧选择我们需要的模板。

            

            点击《下一步》,进入《配置新项目》窗口,输入项目名称,解决方案名称和项目的保存路径地址。

            

            点击《创建》,开始创建项目和解决方案。

            

        1.2、修改Service1.cs文件名称为《MyWindowsService.cs》,并在服务的设计窗口中添加工具EventLog,在《工具栏》中打开组件《EventLog》,并将其拖到我们服务之上。

            

        1.3、然后在我们服务的构造函数中增加一下代码。 

            

  1 using System;
2 using System.Diagnostics;
3 using System.IO;
4 using System.ServiceProcess;
5 using System.Timers;
6
7 namespace PatrickLiu.WindowsService.RfcPlatform
8 {
9 /// <summary>
10 /// 我们定义的 Windows 服务。
11 /// </summary>
12 public partial class MyWindowsService : ServiceBase
13 {
14 private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
15
16 private int eventId = 1;
17
18 /// <summary>
19 /// 服务的构造函数
20 /// </summary>
21 public MyWindowsService()
22 {
23 //记录到event log中,地址是 C:\Windows\System32\winevt\Logs (双击查看即可,文件名为MyNewLog)
24 InitializeComponent();
25 if (!System.Diagnostics.EventLog.SourceExists("PatrickLiuEventSource"))
26 {
27 System.Diagnostics.EventLog.CreateEventSource("PatrickLiuEventSource", "PatrickLog");
28 }
29 MyEventLog.Source = "PatrickLiuEventSource";
30 MyEventLog.Log = "PatrickLog";
31 }
32
33 /// <summary>
34 /// 服务开始启动。
35 /// </summary>
36 /// <param name="args"></param>
37 protected override void OnStart(string[] args)
38 {
39 logger.Info("服务启动,启动时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
40 MyEventLog.WriteEntry("开启服务。");
41 Log("In OnStart.");
42
43 #region 可以定义个人的服务
44
45 Timer timer = new Timer();
46 timer.Interval = 60000; // 60 seconds 60秒执行一次
47 timer.Elapsed += new ElapsedEventHandler(OnTimer);
48 timer.Start();
49
50 #endregion
51 }
52
53 /// <summary>
54 /// 服务开始关闭
55 /// </summary>
56 protected override void OnStop()
57 {
58 logger.Info("服务停止,停止时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
59 MyEventLog.WriteEntry("关闭服务。");
60
61 #region 可以定义要结束服务要做的事情。
62
63 Log("In OnStop.");
64
65 #endregion
66 }
67
68 /// <summary>
69 /// 继续服务
70 /// </summary>
71 protected override void OnContinue()
72 {
73 logger.Info("服务暂停,暂停时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
74 MyEventLog.WriteEntry("In OnContinue.");
75 Log("In OnContinue.");
76 }
77
78 /// <summary>
79 /// 定时器中定时执行的任务
80 /// </summary>
81 /// <param name="sender"></param>
82 /// <param name="args"></param>
83 public void OnTimer(object sender, ElapsedEventArgs args)
84 {
85 // TODO: Insert monitoring activities here.
86 logger.Info("我开始运行了,时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
87 MyEventLog.WriteEntry("我开始运行了!", EventLogEntryType.Information, eventId++);
88 Log("the timer");
89 }
90
91 /// <summary>
92 /// 记录到指定路径:D:\log.txt
93 /// </summary>
94 /// <param name="message"></param>
95 private static void Log(string message)
96 {
97 using (FileStream stream = new FileStream("D:\\log.txt", FileMode.Append))
98 using (StreamWriter writer = new StreamWriter(stream))
99 {
100 writer.WriteLine($"{DateTime.Now}:{message}");
101 }
102 }
103 }
104 }

        1.4、右键点击我们的服务,添加安装程序。

            

            

            项目目录结构如下:

            

        1.5、修改安装程序 serviceInstaller1 名称为:MyServiceInstaller,右键,修改serviceName和Description。

            

        1.6、在 serviceProcessInstaller 上修改名称,右键,修改 Account 为 LocalSystem。

            

        1.7、如果运行 InstallUtil命令,提示不是有效命令,要执行以下操作。跟着操作就可以。

 

        1.8、将【C:\Windows\Microsoft.NET\Framework64\v4.0.30319】这个项目文件的地址增加到环境变量中;如图

             拷贝地址:C:\Windows\Microsoft.NET\Framework64\v4.0.30319
            

            在我的电脑图标上右键点击《属性》,打开《系统》窗口,点击左侧《高级系统设置》,进入设置窗口。

            

            打开《环境变量》窗口,选择《系统变量》,它可以作用域所有用户。在《系统变量》窗口,查找《Path》,然后选择编辑,把我们拷贝的目录,复制到值最后,通过英文分号分割。

            

            确定关闭所有窗口,然后打开cmd窗口,输入:installuils,看看怎么样?和以下一样就说明你可以继续了。

            

            切记:安装服务的时候,必须以管理员的身份运行。否则会有你意想不到错误。

        1.9、编译解决方案和项目,开始安装服务,首先我们以管理员身份运行cmd。

            进入到项目的目录,执行 Installutil PatrickLiu.WindowsService.RfcPlatform.exe

            

        2.0、打开服务管理器,启动MyService服务,并且等待几分钟,然后卸载服务

           

        2.1、检验是否有效果

            

              好了,这一篇就到这里了。

    2、为项目增加Log4net 功能。

      2.1、项目和上面的项目是同一个,我们在该目录下增加文件夹,名称为:LogConfig,在该文件夹下增加配置文件,名称:log4net.config

          

          log4.net.config 内容:          

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <log4net>
3 <appender name="DebugAppender" type="log4net.Appender.DebugAppender" >
4 <layout type="log4net.Layout.PatternLayout">
5 <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
6 </layout>
7 </appender>
8 <!--指定日记记录方式,以滚动文件的方式(文件记录)-->
9 <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
10 <!--日志路径-->
11 <file value="LogFiles\log-" />
12 <!--是否是向文件中追加日志-->
13 <appendToFile value="true" />
14 <!--log保留天数-->
15 <param name= "MaxSizeRollBackups" value= "10"/>
16 <!--每个文件最大1M-->
17 <param name="maximumFileSize" value="1MB" />
18 <!--日志根据日期滚动-->
19 <param name="RollingStyle" value="Date" />
20 <!--日志文件名格式为:logs_20080831.log-->
21 <param name="DatePattern" value="yyyyMMdd&quot;.log&quot;"/>
22 <!--日志文件名是否是固定不变的-->
23 <param name="StaticLogFileName" value="false" />
24 <!--布局-->
25 <layout type="log4net.Layout.PatternLayout">
26 <conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
27 </layout>
28 </appender>
29 <root>
30 <level value="ALL"/>
31 <appender-ref ref="DebugAppender" />
32 <appender-ref ref="RollingFile" />
33 </root>
34 </log4net>

            并且该文件的属性设置为:复制到输出目录-》始终复制。

          

      2.2、第二步,我们要安装 Log4net的组件,通过nuget来安装。

           在项目的《引用》上点击右键,选择《管理 NuGet 程序包》

            

              然后,点击《浏览》,在文本框中输入要查找组件的名称,在右侧选择安装。

              

          2.3、配置 AssemblyInfo.cs 文件。              

              [assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "config", ConfigFile = "LogConfig/log4net.config", Watch = true)]

              截图如下:
                                                

            

      2.4、在我们Windows服务获取Log4net 的实例。          

              private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

              

      2.3、完成之后,我们安装 Windows服务,然后在项目的运行目录里查看,确认日志是否启用。

          我们要在此安装服务,先要卸载服务。

            执行以下命令:先是切换目录,然后执行命令:installutil /u PatrickLiu.WindowsService.RfcPlatform.exe

          

           然后,我们再次执行命令:installutil PatrickLiu.WindowsService.RfcPlatform.exe 重新安装服务。

           

      2.4、Windows服务的安装过程和上面都是一样,所以这里就不重复了。

        2.5、确认log4net是否启作用。 

          

            打开LogFIles目录,我们看到了日志文件。

            

三、总结

    好了,今天就写到这里了。俗话说的好,好记性不如烂笔头,所以我就记录下来,以防自己需要的时候查找使用。而且每步都是自己试验过的。可以放心使用。不忘初心,继续努力,老天不会辜负努力人的。

如何为Windows服务增加Log4net和EventLog的日志功能。的更多相关文章

  1. C# 开发 Windows 服务 使用Log4net 组件 不能生成日志文件

    使用VS2012开发Windows服务,需要使用Log4net日志组件记录业务情况,但是始终生成不了日志文件. /// <summary> /// 入口方法 /// </summar ...

  2. 使用Topshelf开发Windows服务、log4net记录日志

    开发windows服务,除了在vs里新建服务项目外(之前有写过具体开发方法,可点击查看),还可以使用Topshelf. 不过使用topshelf需要.netframework 4.5.2版本,在vs2 ...

  3. Windows服务使用log4net记录日志

    该文章是系列文章 基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业 的其中一篇. 比较流行的日志组件有以下四种,Topshelf都有相应的组件提供 log4net NL ...

  4. windows服务与log4net应用

    有时候我们需要用到window服务来执行定时任务,然后配合log4net记录程序运行情况,这里简单记录下配置的整个过程以及注意要点: 一.添加windows服务 1.设计页面,右键添加安装程序

  5. MVC4.0 利用HandleErrorAttribute和log4net实现记录异常日志功能

    1.MVC4.0中HandleErrorAttribte已经帮我们处理了异常问题,当我们新建一个非空的MVC项目时候,在FilterConfig中会发现这样的代码 public class Filte ...

  6. ASP.NET/MVC 配置log4net启用写错误日志功能

    <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访 ...

  7. ASP.NET 配置log4net启用写错误日志功能

    http://www.cnblogs.com/yeminglong/archive/2013/05/21/3091192.html 首先我们到apche的官网下载log4net的项目编译得到log4n ...

  8. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

  9. 制作Windows服务项目详细攻略

    1.在windows服务下面获得根目录: string assemblyFilePath = Assembly.GetExecutingAssembly().Location; string asse ...

随机推荐

  1. 2021 年终总结:内推40人、全网15万粉、Code Runner 3000万下载、发扬WLB、进军视频领域

    时光飞逝,岁月如梭,蓦然回首,已是年底. 感觉写 2020 年终总结还是在不久之前.转眼间,2021 已经接近尾声了.是时候来写写 2021 年的年终总结了. 内推 40 人 2019 年,内推了 2 ...

  2. Codeforces 888D: Almost Identity Permutations(错排公式,组合数)

    A permutation \(p\) of size \(n\) is an array such that every integer from \(1\) to \(n\) occurs exa ...

  3. ZOJ 3872: Beauty of Array(思维)

    Beauty of Array Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has an array A with N integers. ...

  4. python xlwt写Excel表

    1 xlwt第三方库 说明:xlwt是一个用于将数据和格式化信息写入并生成Excel文件的库. 注意:xlwt不支持写xlsx表,打开表文件报错. 官方文档:https://xlwt.readthed ...

  5. Azure Data Lake(一) 在NET Core 控制台中操作 Data Lake Storage

    一,引言 Azure Data Lake Storage Gen2 是一组专用于大数据分析的功能,基于 Azure Blob Storage 构建的.Data Lake Storage Gen2 包含 ...

  6. 疯狂的类构造器Builder模式,链式调用

    疯狂的类构造器 最近栈长在做 Code Review 时,发现一段创建对象的方法: Task task = new Task(112, "紧急任务", "处理一下这个任务 ...

  7. Keepalived高可用、四层负载均衡

    目录 Keepalived高可用 高可用简介 常用的工具 问题 名称解释 VRRP协议 部署keepalived 下载安装 Keepalived配置 保证nginx配置一样 解决keepalived的 ...

  8. PHP靶场-bWAPP环境搭建

    0x00 靶场介绍 bwapp是一款非常好用的漏洞演示平台,包含有100多个漏洞.开源的php应用后台Mysql数据库. 0x01 安装 BWAPP有两种安装方式,一种是单独安装,需部署在Apache ...

  9. 【Java】IO

    文章目录 IO 说明 流的分类 关于相对路径 节点流 FileRead 对read()操作升级:使用read的重载方法 总结 FileWriter 复制操作 总结 FileInput(Output)S ...

  10. P5024 [NOIP2018 提高组] 保卫王国

    思路: 首先想到每次询问两个点后就从这两个点开始往上爬,沿路更新 dp 值即可. #include <bits/stdc++.h> #define For(i,a,b) for(int i ...