最近要做一个任务处理程序,是用来定时发送邮件订阅的,打算使用windows的任务计划加控制台程序实现。
控制台程序需要做一些日志操作,使用log4net组件。
下载log4net:http://logging.apache.org/log4net/download.html
我这里用vs2008打开后,会根据升级向导将程序升级到.net2.0,
一般的.net应用包含多个项目,分为可以执行项目与类库,他们的组合有如下几类
ConsoleApp.exe(控制台),多个ddl(指.net程序集)
WinForm.exe (窗体程序),以及多个ddl
WebSite(asp.net网站),以及多个ddl
-----------------------------------------------
ConsoleApp,WinForm 的配置文件是app.config
asp.net 的配置文件是 web.Config
可以在app.Config或web.Config中配置log4net
//////////////////////log4net配置样板/////////////////////////////////
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net debug="false">
<!--
<root>元素 是全局配置,定义所有logger(通过 LogManager.GetLogger("LogName")创建)
后面的<logger>元素配置节会继承(指root/appender-ref)/覆盖(指root/level节点)其设置,可以通过logger.additivity来改边这种继承/覆盖关系
-->
<root>
<level value="DEBUG" />
<!-- appender-ref ref="LogFileAppender"/ -->
<appender-ref ref="EventLogAppender"/>
</root>
<!--
<logger>定义了一个具体的logger,代码里通过LogManager.GetLogger("SubscribeHandlerLogger")创建或获取(如果已经创建)
注意<logger>节点不是必须的,你可以直接使用LogManager.GetLogger("LogName")来创建一个logger,此时,这个logger使用root中的配置
-->
<logger name="SubscribeHandlerLogger">
<level value="DEBUG"/>
</logger>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
<param name="File" value="log\Applog.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<LogName value="LogNamex"/>
<ApplicationName value="AppNamex"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
</layout>
</appender>
</log4net>
</configuration>
/////////////////////////////*End///////////////////////////////////
第一次访问时会自动创建立(应用程序需要运行在System权限下或手动创建)
以上配置可以存放于任何文件中
log4net在开始工作前需要读取配置文件以设置log4net环境,使用log4net.Config.XmlConfigurator.Configure();//使用这个函数的重载形式可以指定文件名,以及决定是否启用文件跟踪,一般在程序启动时调用.Configure()方法。
在asp.net中放在Global.asax文件中的应用程序启动事件中,而windows与控制台程序可以放在程序启动文件Programs.cs中的Main()函数中。
另外也可以在AssemblyInfo.cs文件中加入[assembly: log4net.Config.XmlConfigurator()]
在AssemblyInfo.cs中加入上面的属性后,并不是直接初始化log4net的运行环境,而是在你第一次使用LogManager.GetLogger时由log4net调用XmlConfigurator.Configure()方法,属性只是一个标记,用以提供在调用XmlConfigurator.Configure()方法的的信息--文件名、是否跟踪文件等,log4net系统只会调用一次Configure函数(不过我们可以在执行时调用任意多次Configure以设置自己需要的log4net环境),因此当你在ddl中的AssemblyInfo.cs中指定配置属性,以及在Windows程序或ConsoleApp程序中也配置了app.Config时并且设置了AssemblyInfo.cs时。
假设:
ddl 中有方法
FA(){
ILog log=LogManager.GetLogger("xxx");
}
而在WinForm或ConsoleApp中用方法
FB(){
ILog log=LogManager.GetLogger("yyyy");
}
那么
Main(){
ddl.FA();
FB();
//FB();
//ddl.FA()
}
是有区别的,如果先使用ddl.FA();log4net会设置成在ddl AssembleInfo.cs标记的方式运行。
而先调用FB()再调用ddl.FA(),则使用app.Config中的设置。
一般情况下你没必要为了少写一句XmlConfigurator.Configure();而搞的这么麻烦,通常我们在App.config或Web.Config中配置log4net.
但考虑日渐庞大的app.Config或Web.Config中一大堆的配置不好维护,而将App.config或Web.Config通过.net2.0的configSource进行分离,如:
app.config,或Web.Config
////////////////////////////////////////
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<appSettings configSource="config\appSettings.config"/>
<log4net configSource="config\log4net.config" />
<!-- 其他配置 -->
</configuration>
/////////////////////////////////
在应用程序目录下,建立config文件夹在里面放
log4net.config文件,文件内容如:
///////////////////////////////////
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="false">....</log4net>
///////////////////////////////////////////
在启动时调用log4net.XmlConfigurator.Configure();
注意:使用configSource进行分割后,不能通过AssemblyInfo.cs中的设置来加载log4net的配置信息,而必须手动调用
log4net.XmlConfigurator.Configure();