使用log4Net创建应用程序执行脚本的统一文件

在SQL Runner网站上,有人提出了一个需求,希望能够创建一个包含所有应用程序执行脚本的统一文件。认为log4Net库可以很容易地实现这个功能,而不需要对应用程序进行太多修改。本文将介绍为了实现这个功能所做的改动。

本文的源代码可以在SQL Runner源代码库中找到,这些修改自2.0.1.3 RC1版本起可用。

log4Net配置

log4Net库在SQL Runner图形界面应用程序中用作监控机制。命令行版本使用它来显示脚本执行的进度。记录器在应用程序的配置文件中设置:

SQLRunner.exe.config

首先,需要定义一个新的配置节:

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> ... </configSections> ... </configuration>

接下来,需要决定想要拥有的附加器类型。log4Net允许将日志请求打印到多个目的地。在log4Net中,输出目的地被称为附加器。在SQL Runner的情况下,找到了两个附加器:

<?xml version="1.0" encoding="utf-8" ?> <configuration> ... <log4net> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender, log4net"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level - %message%newline" /> </layout> </appender> <appender name="LogFileAppender" type="log4net.Appender.FileAppender,log4net"> <param name="File" value="logs\\sqlrunner.log" /> <param name="AppendToFile" value="true" /> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%date [%thread] %-5level - %message%newline" /> </layout> </appender> ... </log4net> ... </configuration>

ConsoleAppender直接打印到控制台,而LogFileAppender打印到名为sqlrunner.log的文件中。

接下来要定义的是记录器。在log4Net中,记录器是通过给它们命名来创建层次结构的。这种命名约定与类中的命名空间非常相似。一个好主意是在使用记录器时使用类的完全限定名。

根记录器是所有记录器的父记录器,配置文件中需要为它分配一个级别:

<?xml version="1.0" encoding="utf-8" ?> <configuration> ... <log4net> ... <root> <level value="INFO" /> <appender-ref ref="ConsoleAppender" /> <appender-ref ref="LogFileAppender" /> </root> ... </log4net> ... </configuration>

根的级别设置为INFO,并且使用了两个附加器。因此,任何使用INFO级别或更高级别调用记录器的代码都会打印到两个记录器中。

如何修改应用程序以合并执行的脚本

这里的想法是创建一个新的附加器,每次执行脚本时都打印到一个新的文件:allscripts.sql。还需要创建一个新的记录器。最后,需要修改代码;只需要添加两行新代码就可以让一切工作。

配置文件需要更改为:

<?xml version="1.0" encoding="utf-8" ?> <configuration> ... <log4net> <appender name="ScriptConsolidator" type="log4net.Appender.FileAppender,log4net"> <param name="File" value="logs\\allscripts.sql" /> <param name="AppendToFile" value="true" /> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%message%newline" /> </layout> </appender> ... <logger name="SQLRunnerLib.Runners.Runner"> <level value="DEBUG" /> <appender-ref ref="ScriptConsolidator" /> </logger> ... </log4net> ... </configuration>

需要注意的几个方面是:

  • 文件附加器模式非常简单,它打印消息和回车。
  • 记录器名称与将使用记录器的类的完全限定类名匹配。
  • 记录器级别设置为DEBUG,记录器使用之前定义的附加器。

只需要两行代码就可以创建合并的脚本文件。在SQL Runner中,Runner类在调用ExecuteSQL方法时执行脚本。

需要创建一个调用工厂方法GetLogger的ILog的本地实例。传递Runner类的完全限定类名来获取记录器:

public sealed class Runner : IRunner { #region Private Instances ... private readonly ILog _logger = LogManager.GetLogger(typeof(Runner)); ... #endregion }

然后,需要做的只是在执行脚本之前调用记录器:

public sealed class Runner : IRunner { ... private void ExecuteSQL(FileInfo aFile) { if (IsCancelled) return; try { OnProgressMsgCreated("Executing {0} script", aFile.Name); using (StreamReader aStream = new StreamReader(aFile.OpenRead())) { try { string strSQL = aStream.ReadToEnd(); aStream.Close(); strSQL = ReplacePlaceholders(strSQL, aFile.Name); _logger.Debug(strSQL); ... } catch (Exception e) { ... } } } catch (Exception e) { ... } } ... }

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485