Enterprise Library 2.0 -- Logging Application Block(补充)

Enterprise Library 2.0 -- Logging Application Block(补充)

在前面的文章中,有朋友提到我们在实际项目中往往是把一些事件的日志(比如异常)写入到数据库中,这样更方便查看和管理,而在前面的文章中我都是以写入到文本文件为例的,今天这篇文章就算是对前两篇的一个补充,主要来介绍如何将日志信息写入到数据库中,同时也很感谢那位朋友的建议,下面我们进入正题,分为以下几个步骤:

一、 根据Enterprise Library 2.0中将日志写入到数据库中的需要,我们在数据库中添加一张记录日志的表(RX_Log): --日志信息表

create table RX_Log
(
  id            int identity     not null,    --流水号
  EventId          int         null,      --事件ID
  Priority        int          null,      --优先级
  Category        varchar(1000)    null,      --类别
  Title          varchar(500)    null,      --日志标题
  Message          varchar(1000)    null,      --日志信息
  Machine          varchar(100)    null,      --主机名
  Timestamps        smalldatetime    null,      --记录时间
  Severity        varchar(100)    null,      --严重级别
  ApplicationDomain    varchar(1000)    null,      --应用程序名
  ProcessId        int          null,      --进程ID
  ProcessName        varchar(500)    null,      --进程名
  Win32ThreadId      int          null,      --线程ID
  ThreadName        varchar(500)    null,      --线程名
  ExtendedProperties    varchar(1000)    null,      --扩展信息

  primary key(id)
)

Logging Application Block 在写日志到数据库的过程中,还需要两个存储过程(注意:这也是和1.0的一点小区别,上一个版本只需要一个存储过程),分别为:

--建立存储过程

--写日志

create procedure usp_writelogtodatabase
(
  @EventId        int,
  @Priority        int,
  @Title          varchar(500),
  @Message        varchar(4000),
  @machineName      varchar(100),
  @Timestamp        smalldatetime,
  @Severity        varchar(100),
  @AppDomainName      varchar(1000),
  @ProcessId        int,
  @ProcessName      varchar(500),
  @Win32ThreadId      int,
  @ThreadName        varchar(500),
  @formattedmessage    varchar(4000),
  @LogId          int  out
)
as
begin

  insert into RX_Log
  (
    EventId,
    Priority,
    Title,
    Message,
    Machine,
    Timestamps,
    Severity,
    ApplicationDomain,
    ProcessId,
    ProcessName,
    Win32ThreadId,
    ThreadName,
    ExtendedProperties
  )
  values
  (
    @EventId,
    @Priority,
    @Title,
    @Message,
    @machineName,
    @Timestamp,
    @Severity,
    @AppDomainName,
    @ProcessId,
    @ProcessName,
    @Win32ThreadId,
    @ThreadName,
    @formattedmessage
  )

  set @LogId=@@identity

end

--设置日志类别

create procedure usp_addcategory
(
  @categoryName    varchar(1000),
  @logID        int
)
as
begin
  UPDATE RX_Log SET Category=@categoryName WHERE ID=@logID
end

上面的工作做好之后,我们在来配置我们的配置文件,首先我们需要添加一个DataBase的Trace Listener,如下图:

Enterprise Library 2.0 -- Logging Application Block(补充)

然后指定一些该Trace Listener的属性,包括AddCategoryStoreProcedure,DataBaseInstance,Formatter,Name,TraceOutputOptions以及WriteLogStoreProcedure。

Enterprise Library 2.0 -- Logging Application Block(补充)

其中AddCategoryStoredProcedure和WriteLogStoredProcedureName就是我们刚刚在数据库中建的存储过程,前者是设置日志类别,后者为向数据库中插入日志的存储过程。DataBaseInstance是我们在Data Access Application Block中建立的一个数据库实例,具体方法可以参考: 

Enterprise Library 2.0 -- Data Access Application Block,Formatter则是我们选择上篇文章中设置的SHY520 Formatter,具体的配置方法请参考:

Enterprise Library 2.0 -- Logging Application Block (上)

Enterprise Library 2.0 -- Logging Application Block (下)

其他选项我们先保持默认,接着我们需要添加一个Category,命名为DataBase

Enterprise Library 2.0 -- Logging Application Block(补充)

然后为这个Category添加一个Trace Listener,并设置其RefrencedTraceListener为我们刚刚建的Database Trace Listener,

Enterprise Library 2.0 -- Logging Application Block(补充)

这样就完成了我们的配置工作,此时你的配置文件中(Web.Config或App.Config)应该会包含下面的信息:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <configSections>
  <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
 </configSections>
 <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
  defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
  <listeners>
   <add databaseInstanceName="Connection String" writeLogStoredProcName="usp_writelogtodatabase"
    addCategoryStoredProcName="usp_addcategory" formatter="SHY520 Formatter"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
    traceOutputOptions="None" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
    name="Database Trace Listener" />
  </listeners>
  <formatters>
   <add template="Timestamp: {timestamp} Message: {message} Category: {category} Priority: {priority} EventId: {eventid} Severity: {severity} Title:{title} Machine: {machine} Application Domain: {appDomain} Process Id: {processId} Process Name: {processName} Win32 Thread Id: {win32ThreadId} Thread Name: {threadName} Extended Properties: {dictionary({key} - {value} )}"
    type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
    name="SHY520 Formatter" />
  </formatters>
  <logFilters>
   <add categoryFilterMode="AllowAllExceptDenied" type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
    name="Category Filter" />
  </logFilters>
  <categorySources>
   <add switchValue="All" name="DataBase">
    <listeners>
     <add name="Database Trace Listener" />
    </listeners>
   </add>
   <add switchValue="All" name="General">
    <listeners>
     <add name="SHY520 Listeners" />
    </listeners>
   </add>
  </categorySources>
  <specialSources>
   <allEvents switchValue="All" name="All Events" />
   <notProcessed switchValue="All" name="Unprocessed Category" />
   <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
     <add name="Formatted EventLog TraceListener" />
    </listeners>
   </errors>
  </specialSources>
 </loggingConfiguration>
 <dataConfiguration defaultDatabase="Connection String" />
 <connectionStrings>
  <add name="Connection String" connectionString="Database=EnterpriseLibrary;Server=shy;Integrated Security=SSPI;uid=sa;pwd=;"
   providerName="System.Data.SqlClient" />
 </connectionStrings>
</configuration>

上面的工作做完之后,我们就可以在应用程序中添加代码,用于将日志写入数据库了,如下:

[TestMethod]
public void LogToDataBase()
{
LogEntry log = new LogEntry();
//事件ID
log.EventId = 2000;
//日志优先级
log.Priority = 2;
log.Message = "Test Log Information To DataBase";

//日志类别
ICollection<string> coll = new List<string>();
//设置类别为DataBase,这就确定了你的日志是写入到数据库的
//因为DataBase这个类别中包含一个DataBase Trace Listener
coll.Add("DataBase");

log.Categories = coll;

//添加额外信息
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("name", "SHY520");
dic.Add("sex","男");
dic.Add("age", "22");

log.ExtendedProperties = dic;
//写入日志
Logger.Write(log);
}

运行这个测试方法,然后到数据库中看一下,此时上面的一条日志信息已经写入到数据库中了,关于利用Logging Application Block写日志到数据库中的方法就说到这里,如有遗漏,错误的地方,欢迎您指正!