本章我们继续ILogger的开发
ILogger.cs
1 public interface ILogger 2 { 3 void Info(object message); 4 void Info(object message, Exception e); 5 void Debug(object message); 6 void Debug(object message, Exception e); 7 void Warn(object message); 8 void Warn(object message, Exception e); 9 void Error(object message); 10 void Error(object message, Exception e); 11 void Fatal(object message); 12 void Fatal(object message, Exception e); 13 }
日志服务的实现
这里我们引用的是log4net组件,我们来看看具体实现
LoggerBase.cs
1 public class LoggerBase : ILogger 2 { 3 private ILog logger; 4 5 public LoggerBase() 6 { 7 logger = LogManager.GetLogger("log4netlogger"); 8 } 9 10 public void Info(object message) 11 { 12 logger.Info(message); 13 } 14 15 public void Info(object message, Exception e) 16 { 17 logger.Info(message, e); 18 } 19 20 public void Debug(object message) 21 { 22 logger.Debug(message); 23 } 24 25 public void Debug(object message, Exception e) 26 { 27 logger.Debug(message, e); 28 } 29 30 public void Warn(object message) 31 { 32 logger.Warn(message); 33 } 34 35 public void Warn(object message, Exception e) 36 { 37 logger.Warn(message, e); 38 } 39 40 public void Error(object message) 41 { 42 logger.Error(message); 43 } 44 45 public void Error(object message, Exception e) 46 { 47 logger.Error(message, e); 48 } 49 50 public void Fatal(object message) 51 { 52 logger.Fatal(message); 53 } 54 55 public void Fatal(object message, Exception e) 56 { 57 logger.Fatal(message, e); 58 } 59 }
其实log4net可以直接在项目各层调用的,我们这里之所以还要创建一个接口,似乎有过度封装之嫌;
我这么做是有原因的,因为我不想只限于一种日志记录方式,如果以后还有其他组件,或者自己写日志组件
那都可以很方便的扩展了。
再看看log4net.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <configSections> 4 <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> 5 </configSections> 6 <appSettings> 7 </appSettings> 8 <log4net> 9 10 <!--定义日志的输出媒介,下面定义日志以五种方式输出。也可以下面的按照一种类型或其他类型输出。--> 11 <!--None,Fatal,ERROR,WARN,DEBUG,INFO,ALL--> 12 <root> 13 <level value="all"/> 14 15 <!--文件形式记录日志--> 16 <!--<appender-ref ref="LogFileAppender" />--> 17 18 <!--控制台控制显示日志--> 19 <!--<appender-ref ref="ConsoleAppender" />--> 20 21 <!--启用Access数据库记录日志--> 22 <!--<appender-ref ref="AdoNetAppender_Access" />--> 23 24 <!--SqlServer数据库记录日志--> 25 <!--<appender-ref ref="AdoNetAppenderSqlServer" />--> 26 </root> 27 28 <logger name="log4netlogger"> 29 <level value="all" /> 30 <appender-ref ref="AdoNetAppenderSqlServer" /> 31 </logger> 32 33 <!--定义输出到数据库中,这里举例输出到SqlServer数据库中--> 34 <appender name="AdoNetAppenderSqlServer" type="log4net.Appender.AdoNetAppender"> 35 <bufferSize value="1" /> 36 <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089" /> 37 <connectionString value="Data Source=JIANRONGLAN-PC\SQLEXPRESS;Initial Catalog=SystemBase;User ID=sa;Password=123456" /> 38 <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> 39 <filter type="log4net.Filter.LevelRangeFilter"> 40 <param name="LevelMin" value="INFO" /> 41 <param name="LevelMax" value="Fatal" /> 42 </filter> 43 <parameter> 44 <parameterName value="@log_date" /> 45 <dbType value="DateTime" /> 46 <layout type="log4net.Layout.RawTimeStampLayout" /> 47 </parameter> 48 <parameter> 49 <parameterName value="@thread" /> 50 <dbType value="String" /> 51 <size value="255" /> 52 <layout type="log4net.Layout.PatternLayout"> 53 <conversionPattern value="%thread" /> 54 </layout> 55 </parameter> 56 <parameter> 57 <parameterName value="@log_level" /> 58 <dbType value="String" /> 59 <size value="50" /> 60 <layout type="log4net.Layout.PatternLayout"> 61 <conversionPattern value="%level" /> 62 </layout> 63 </parameter> 64 <parameter> 65 <parameterName value="@logger" /> 66 <dbType value="String" /> 67 <size value="255" /> 68 <layout type="log4net.Layout.PatternLayout"> 69 <conversionPattern value="%logger" /> 70 </layout> 71 </parameter> 72 <parameter> 73 <parameterName value="@message" /> 74 <dbType value="String" /> 75 <size value="4000" /> 76 <layout type="log4net.Layout.PatternLayout"> 77 <conversionPattern value="%message" /> 78 </layout> 79 </parameter> 80 <parameter> 81 <parameterName value="@exception" /> 82 <dbType value="String" /> 83 <size value="4000" /> 84 <layout type="log4net.Layout.ExceptionLayout" /> 85 </parameter> 86 </appender> 87 88 </log4net> 89 </configuration>
基础设施层的实现
Logger.cs 代码跟上边的差不多,主要是要实现日志驱动的配置,或许有其他方法,但暂时这么写吧
1 public sealed class Logger 2 { 3 private readonly static ILogger loggerProvider; 4 5 static Logger() 6 { 7 loggerProvider = ProviderHelper.GetLoggerProvider(); 8 } 9 10 public static void Info(object message) 11 { 12 loggerProvider.Info(message); 13 } 14 15 public static void Info(object message, Exception e) 16 { 17 loggerProvider.Info(message, e); 18 } 19 20 public static void Debug(object message) 21 { 22 loggerProvider.Debug(message); 23 } 24 25 public static void Debug(object message, Exception e) 26 { 27 loggerProvider.Debug(message, e); 28 } 29 30 public static void Warn(object message) 31 { 32 loggerProvider.Warn(message); 33 } 34 35 public static void Warn(object message, Exception e) 36 { 37 loggerProvider.Warn(message, e); 38 } 39 40 public static void Error(object message) 41 { 42 loggerProvider.Error(message); 43 } 44 45 public static void Error(object message, Exception e) 46 { 47 loggerProvider.Error(message, e); 48 } 49 50 public static void Fatal(object message) 51 { 52 loggerProvider.Fatal(message); 53 } 54 55 public static void Fatal(object message, Exception e) 56 { 57 loggerProvider.Fatal(message, e); 58 } 59 }
我们新建测试看看效果
1 [TestClass] 2 public class LoggerTest 3 { 4 [TestMethod] 5 public void Info() 6 { 7 LjrFramework.Infrastructure.Logger.Info("sqlserver test message " + Guid.NewGuid().ToString()); 8 9 Assert.AreEqual(true, true); 10 } 11 }
查看数据库记录
自此日志功能完成了,比较简单
项目架构开发系列
- 项目架构开发:数据访问层之Cache
- 项目架构开发:数据访问层之Logger
- 项目架构开发:数据访问层之Repository
- 项目架构开发:数据访问层之Query
- 项目架构开发:数据访问层之UnitOfWork