先谈谈简单的模块,日志。在系统中日志模块是必须的,什么系统日志,操作日志,调试日志。这里用的是log4net

对log4net还不熟悉的小伙伴们赶快去搜索基础教程哦, 我这里就不温故了。

那么有人要问了,log4net确实很强大,而且我们也会用。还要单独写一篇文章来介绍,有必要吗?

我简单的举两个场景:

1:log4net写入DB 还需要在 log4net中配置数据库连接字符串,   我想log4net 和 我的 connectionStrings 用1个配置不行吗?

2:log4net写入参数扩展问题,我配置文件想写入ip地址,那我代码还要定义一个ip的参数。 那我再扩展,还需要再定义,这改动量太大了,能不能只传一个实体类,让log4net自己去映射那?这样我就可以写一些通用的方法,好多项目都可以直接拿过来用,代码修改量也少了点。

有人觉得这都不是问题,高手请跳过。

我这里将日志模块单独封装了一个HY.Log,截图如下:

aaarticlea/png;base64,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" alt="" />

看图有点乱,下面我给大家捋一捋(念lv  念成lu的去面壁思过  ):

第一步:实现自定义参数

我们要在PatternConverter文件夹中定义一些可扩展参数,这样就可以在log4net配置文件中随心使用了,哪截图中我实现了获取客户端ip、获取服务器端ip

或许服务器mac地址。

就拿ClientIpPatternConverter.cs来说需要继承log4net下  log4net.Layout.Pattern.PatternLayoutConverter类,来实现扩展。

using System.IO;
using log4net.Core;
using log4net.Layout.Pattern; namespace HY.Log.PatternConverter
{
/// <summary>
/// B/S 客户端地址扩展
/// </summary>
internal class ClientIpPatternConverter : PatternLayoutConverter
{
protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
writer.Write(HY.Utilities.IPHelper.GetRemoteIPAddress());
}
}
}

接着在分别实现 MAC、服务端IP、 以及其它你任何想扩展的参数。

ObjectPatternConverter.cs 这个类就比较特殊了。这个自定义参数其实是让你传入一个实体类,然后通过反射技术,让log4net通过配置文件的 配置自动映射要传入的值。

上面的类 是针对特定的通用功能扩展,这个类只需要定义一个即可。

using System.IO;
using System.Reflection;
using log4net.Core;
using log4net.Layout.Pattern; namespace HY.Log.PatternConverter
{
internal class ObjectPatternConverter : PatternLayoutConverter
{
protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
if (Option != null)
{
// Write the value for the specified key
WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
}
else
{
// Write all the key value pairs
WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
}
} /// <summary>
/// 通过反射获取传入的日志对象的某个属性的值
/// </summary>
/// <param name="property"></param>
/// <param name="loggingEvent"></param>
/// <returns></returns>
private object LookupProperty(string property, LoggingEvent loggingEvent)
{
object propertyValue = string.Empty;
PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
if (propertyInfo != null)
propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
return propertyValue;
}
}
}

第二步:实现log4net自定义布局,将自定义参数进行注册

 CustomLayout.cs

using HY.Log.PatternConverter;
using log4net.Layout; namespace HY.Log
{
/// <summary>
/// 定义log日志布局的参数信息
/// </summary>
public class CustomLayout : PatternLayout
{
/// <summary>
/// 构造函数
/// </summary>
public CustomLayout()
{
#region 内部自定义
AddConverter("ServerIP", typeof(ServerIpPatternConverter));
AddConverter("ClientIP", typeof(ClientIpPatternConverter));
AddConverter("MAC", typeof(MacPatternConverter));
#endregion #region 支持开发人员自定义
AddConverter("Object", typeof(ObjectPatternConverter));
#endregion
}
}
}

代码将自定义的参数以 key value 的形式进行注册, 以后我们再log4net进行配置的时候 就要记住这些关键字了, 这都是你自己定义的。

你敢在代码中实现  AddConverter("XXOO", typeof(XXOOPatternConverter));  吗?

第三步:定义自己框架的Log接口并实现它

没啥可说的,看代码吧。

LogMessage.cs   这个类其实就是写了一个传入的的自定义参数的实体类,你可以自己写。不过最好是继承这个类进行扩展。

using System;

namespace HY.Log
{
/// <summary>
/// 用于记录日志信息
/// </summary>
[Serializable]
public class LogMessage
{
/// <summary>
/// 日志信息
/// </summary>
public string Message { get; set; } }
}

ILog.cs

using System;

namespace HY.Log
{
public interface ILog
{
/// <summary>
/// 写入Debug日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
void Debug(string message, Exception exception = null); /// <summary>
/// 写入Debug日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
void Debug(object messageEntity, Exception exception = null); /// <summary>
/// 写入Info日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
void Info(string message, Exception exception = null); /// <summary>
/// 写入Info日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
void Info(object messageEntity, Exception exception = null); /// <summary>
/// 写入Warn日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
void Warn(string message, Exception exception = null); /// <summary>
/// 写入Warn日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
void Warn(object messageEntity, Exception exception = null); /// <summary>
/// 写入Error日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
void Error(string message, Exception exception = null); /// <summary>
/// 写入Error日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
void Error(object messageEntity, Exception exception = null); /// <summary>
/// 写入Fatal日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
void Fatal(string message, Exception exception = null); /// <summary>
/// 写入Fatal日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
void Fatal(object messageEntity, Exception exception = null); }
}

NormalLog.cs

using System;
using System.Collections.Generic; namespace HY.Log
{
public class NormalLog : ILog
{
#region private
private static Dictionary<string, log4net.ILog> listILog = new Dictionary<string, log4net.ILog>(); //Log对象集合
private log4net.ILog iLog; //当前日志对象的实例
#endregion #region 构造函数 /// <summary>
/// 构造函数,传入Log4NET 的ILog对象
/// </summary>
/// <param name="logger"></param>
public NormalLog(log4net.ILog logger)
{
string LoggerName = logger.Logger.Name; //logger 配置节名称
if (!listILog.ContainsKey(LoggerName))
{
lock (listILog)
{
if (!listILog.ContainsKey(LoggerName))
{
listILog.Add(LoggerName, logger);
}
else
{
listILog[LoggerName] = logger;
}
}
}
else if (listILog[LoggerName] == null)
{
listILog[LoggerName] = logger;
}
iLog = listILog[LoggerName];
} public NormalLog(string loggerName)
{
log4net.ILog logger = log4net.LogManager.GetLogger(loggerName);
string LoggerName = logger.Logger.Name; //logger 配置节名称
if (!listILog.ContainsKey(LoggerName))
{
listILog.Add(LoggerName, logger);
}
else if (listILog[LoggerName] == null)
{
listILog[LoggerName] = logger;
}
iLog = listILog[LoggerName];
} #endregion #region 写入日志 /// <summary>
/// 写入Debug日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
public void Debug(string message, Exception exception = null)
{
LogMessage messageEntity = new LogMessage
{
Message = message
};
Debug(messageEntity, exception);
} /// <summary>
/// 写入Debug日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
public void Debug(object messageEntity, Exception exception = null)
{
if (iLog.IsDebugEnabled)
{
if (exception != null)
{
iLog.Debug(messageEntity, exception);
}
else
{
iLog.Debug(messageEntity);
}
}
} /// <summary>
/// 写入Info日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
public void Info(string message, Exception exception = null)
{
LogMessage messageEntity = new LogMessage
{
Message = message
};
Info(messageEntity, exception);
} /// <summary>
/// 写入Info日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
public void Info(object messageEntity, Exception exception = null)
{
if (iLog.IsInfoEnabled)
{
if (exception != null)
{
iLog.Info(messageEntity, exception);
}
else
{
iLog.Info(messageEntity);
}
}
} /// <summary>
/// 写入Warn日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
public void Warn(string message, Exception exception = null)
{
LogMessage messageEntity = new LogMessage
{
Message = message
};
Warn(messageEntity, exception);
} /// <summary>
/// 写入Warn日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
public void Warn(object messageEntity, Exception exception = null)
{
if (iLog.IsWarnEnabled)
{
if (exception != null)
{
iLog.Warn(messageEntity, exception);
}
else
{
iLog.Warn(messageEntity);
}
}
} /// <summary>
/// 写入Error日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
public void Error(string message, Exception exception = null)
{
LogMessage messageEntity = new LogMessage
{
Message = message
};
Error(messageEntity, exception);
} /// <summary>
/// 写入Error日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
public void Error(object messageEntity, Exception exception = null)
{
if (iLog.IsErrorEnabled)
{
if (exception != null)
{
iLog.Error(messageEntity, exception);
}
else
{
iLog.Error(messageEntity);
}
}
} /// <summary>
/// 写入Fatal日志,
/// </summary>
/// <param name="message">日志信息,占位符为 %Object{Message}</param>
public void Fatal(string message, Exception exception = null)
{
LogMessage messageEntity = new LogMessage
{
Message = message
};
Fatal(messageEntity, exception);
} /// <summary>
/// 写入Fatal日志
/// </summary>
/// <param name="messageEntity">日志实体信息, 占位符为 %Object{实体类的属性名称}</param>
public void Fatal(object messageEntity, Exception exception = null)
{
if (iLog.IsFatalEnabled)
{
if (exception != null)
{
iLog.Fatal(messageEntity, exception);
}
else
{
iLog.Fatal(messageEntity);
}
}
}
#endregion }
}

第四步:写一下log模块的支持方法(这里有实现log4net配置和连接字符串共用一个配置的方法)

LogManager.cs

这个类定义的了log4net模块的初始化,数据库连接设置……

using System;
using System.IO;
using log4net.Appender;
using log4net.Config;
using log4net.Repository.Hierarchy; namespace HY.Log
{
public class LogManager
{ /// <summary>
/// 设置DB连接字符串
/// </summary>
/// <param name="conString">连接字符串</param>
/// <param name="loggerName">loggerName</param>
/// <param name="appenderName">appenderName</param>
public static void ConfigConnection(string conString, string loggerName, string appenderName = "ADONetAppender")
{
try
{
Hierarchy h = log4net.LogManager.GetRepository() as Hierarchy;
if (h != null)
{
AdoNetAppender adoAppender = (AdoNetAppender)h.GetLogger(loggerName,
h.LoggerFactory).GetAppender(appenderName);
if (adoAppender != null)
{
adoAppender.ConnectionString = conString;
adoAppender.ActivateOptions();
}
} }
catch (NullReferenceException) { }
} /// <summary>
/// 初始化HY.Log, Log配置文件需要写到 Web.config OR App.config
/// </summary>
public static void Init()
{
XmlConfigurator.Configure();
} /// <summary>
/// 初始化HY.Log,
/// </summary>
/// <param name="configFileName">制定Log配置文件的文件绝对路径</param>
public static void Init(string configFileName)
{
XmlConfigurator.Configure(new FileInfo(configFileName));
} /// <summary>
/// 检索Logger名称返回日志处理接口
/// </summary>
/// <param name="name">Logger名称</param>
/// <returns>日志接口</returns>
public static ILog GetLogger(string name)
{
var log4Logger = log4net.LogManager.GetLogger(name);
return new NormalLog(log4Logger);
} }
}

第五步:如何使用HY.Log.DLL

上面的代码大家看到了,已经可以成功编译一个dll 文件了。

先来编辑一个log4net配置文件

<?xml version="1.0"?>
<configuration>
<!--Log4net Begin-->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<!--Log4net Begin,程序运行异常记录--> <logger name="LogInfoDB">
<level value="ALL" />
<appender-ref ref="ADONetAppender" />
</logger>
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value="" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--<connectionString value="Data Source=127.0.0.1;Database=test;uid=sa;pwd=test;Max Pool Size=300;Connect Timeout=15;" />-->
<commandText value="INSERT INTO HY_Log ([LogType],[ModelName],[Message],[Exception],[IP],[Log_Date],[UserID]) VALUES (@LogType,@ModelName, @Message, @Exception, @IP,@Log_Date,@UserID)" />
<parameter>
<parameterName value="@LogType" />
<dbType value="String" />
<size value="" />
<layout type="HY.Log.CustomLayout">
<conversionPattern value="%Object{LogType}" />
</layout>
</parameter>
<parameter>
<parameterName value="@ModelName" />
<dbType value="String" />
<size value="" />
<layout type="HY.Log.CustomLayout">
<conversionPattern value="%Object{ModelName}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Message" />
<dbType value="String" />
<size value="" />
<layout type="HY.Log.CustomLayout">
<conversionPattern value="%Object{Message}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Exception" />
<dbType value="String" />
<size value="" />
<layout type="HY.Log.CustomLayout">
<conversionPattern value="%Object{Exception}" />
</layout>
</parameter>
<parameter>
<parameterName value="@IP" />
<dbType value="String" />
<size value="" />
<layout type="HY.Log.CustomLayout">
<conversionPattern value="%ClientIP" />
</layout>
</parameter>
<parameter>
<parameterName value="@Log_Date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@UserID" />
<dbType value="String" />
<size value="" />
<layout type="HY.Log.CustomLayout">
<conversionPattern value="%Object{UserID}" />
</layout>
</parameter>
</appender> </log4net>
<!--Log4net End-->
</configuration> <!--%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
%n(new line):换行
%d(datetime):输出当前语句运行的时刻
%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
%t(thread id):当前语句所在的线程ID
%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
%c(class):当前日志对象的名称,例如:
%f(file):输出语句所在的文件名。
%l(line):输出语句所在的行号。-->

上面的配置文件是一个写入DB的配置

请注意如下配置节:

<layout type="HY.Log.CustomLayout">
<conversionPattern value="%Object{Exception}" />
<conversionPattern value="%Object{LogType}" />
<conversionPattern value="%ClientIP" />
这便是采用了自定义配置。 创建HY.ILog对象
public static ILog ilog = null; HY.Log.LogManager.Init(HttpContext.Current.Server.MapPath(@"~/Config/log4net.config"));//加载配置文件
HY.Log.LogManager.ConfigConnection(ConfigurationManager.ConnectionStrings["Connection"].ToString(), "LogInfoDB");//修改连接字符串
ilog = LogManager.GetLogger("LogInfoText");     //获取Ilog对象 这里可以采用单例模式。代码就不贴了, 自定义实体类:
 [Serializable]
public class LogEntity
{
/// <summary>
/// 日志类型
/// </summary>
public LogType LogType { get; set; } /// <summary>
/// 模块名称
/// </summary>
public string ModelName { get; set; } /// <summary>
/// 信息
/// </summary>
public new string Message { get; set; } /// <summary>
/// 异常信息
/// </summary>
public string Exception { get; set; } public string UserID { get; set; }
 LogEntity loginfo = new LogEntity();
loginfo.ModelName = "ModelName";
           loginfo.Message = "Message";
           loginfo.Exception = "Exception";
           loginfo.UserID = "UserID";
           loginfo.LogType = "LogType.Business";
ilog.Error(loginfo,ex);
 
 到这里就已经完了。  关于使用的代码比较粗糙,这块就需要根据你程序的具体需求来实现了。这里点到为止。  因为后续我们将会采用AutoFac来注入。 将在后续的文章介绍。

各位如果有更好的建立请给我留言, 请各位不吝赐教。
 

相关文章:

搭建一套自己实用的.net架构(1)【概述】

搭建一套自己实用的.net架构(2)【日志模块-log4net】

搭建一套自己实用的.net架构(3)【ORM-Dapper+DapperExtensions】

搭建一套自己实用的.net架构(4)【CodeBuilder-RazorEngine】

原文链接:http://www.cnblogs.com/hy59005271/p/4736885.html

搭建一套自己实用的.net架构(2)【日志模块-log4net】的更多相关文章

  1. 搭建一套自己实用的.net架构(3)续 【ORM Dapper+DapperExtensions+Lambda】

    前言 继之前发的帖子[ORM-Dapper+DapperExtensions],对Dapper的扩展代码也进行了改进,同时加入Dapper 对Lambda表达式的支持. 由于之前缺乏对Lambda的知 ...

  2. 搭建一套自己实用的.net架构(3)【ORM-Dapper+DapperExtensions】

    现在成熟的ORM比比皆是,这里只介绍Dapper的使用(最起码我在使用它,已经运用到项目中,小伙伴们反馈还可以). 优点: 1.开源.轻量.小巧.上手容易. 2.支持的数据库还蛮多的, Mysql,S ...

  3. 搭建一套自己实用的.net架构(4)【CodeBuilder-RazorEngine】

    工欲善其事必先利其器,  下面来说说代码生成器. 现在代码生成器品种繁多各式各样, 什么codesmith.T4. 动软也算.那么每款代码生成器都有自己模板解析引擎. 现在比较流行的 NVelocit ...

  4. 搭建一套自己实用的.net架构(1)【概述】

    入园很久,一直默默的潜水,近来得空想写点什么. 思前想后,那就把自己平时没事干自己摘抄.引用.瞎写的一些东西写出来.帮助自己巩固一下,顺便请高手们指点一二. 我本人很懒 ,一些代码就是直接复制别人的劳 ...

  5. 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】

    https://blog.csdn.net/linzhefeng89/article/details/78752658 基于springboot+bootstrap+mysql+redis搭建一套完整 ...

  6. 手把手0基础项目实战(一)——教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)...

    原文:手把手0基础项目实战(一)--教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)... 本文你将学到什么? 本文将以原理+实战的方式,首先对& ...

  7. 搭建一套ASP.NET Core+Nacos+Spring Cloud Gateway项目

    前言     伴随着随着微服务概念的不断盛行,与之对应的各种解决方案也层出不穷.这毕竟是一个信息大爆发的时代,各种编程语言大行其道,各有各的优势.但是有一点未曾改变,那就是他们服务的方式,工作的时候各 ...

  8. Spring MVC+ Spring + Mybatis从零开始搭建一个精美且实用的管理后台

    点击进入<SSM搭建精美实用的管理系统>达人课页面 SSM 框架即 SpringMVC+Spring+Mybatis,相信各位朋友在投递简历时已直观感受到它的重要性,JavaWeb 相关工 ...

  9. 从原理到代码:大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社

    从原理到代码:大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社 PPT链接: https://pan.baidu.com/s/1i5Jrr1N 视频链接: https: ...

随机推荐

  1. WCF自寄宿

    WCF很早就出现了,然而我感受到能够让新手重点去学习WCF而不是WebService是最近两年.我相信大部分人初步了解WCF的时候会很痛苦,尤其是生成代理类,以及配置的问题.我本人其实比较讨厌配置编程 ...

  2. angular使用post、get向后台传参的问题

    一.问题的来源 我们都知道向后台传参可以使用get.put,其形式就类似于name=jyy&id=001.但是在ng中我却发现使用$http post进行异步传输的过程中后台是接收不到数据的. ...

  3. 码农干货系列【20】--add gtTime to Promise.js

    使用场景 在一些时候,希望一件task不能太快完成,需要大于多少时间才可以执行,就可以使用Promise的gtTime方法. 使用方式 Promise.gtTime(f1(), 5000).then( ...

  4. sharePoint 2016 弃用和删除的功能

    前言 sharepoint 2016版本正式发布,但是相比较2013版本,还是删除或者准备删除一些功能,我们需要了解一下哪些功能已经被删除掉或者在下一个版本中移除,因为这些可能影响我们现有系统是否能够 ...

  5. 自定义加载loading view动画组件的使用。

    在github上找的一个有点酷炫的loading动画https://github.com/Fichardu/CircleProgress 我写写使用步骤 自定义view(CircleProgress  ...

  6. 【转】如何使App从后台返回前台时,显示指定界面

    用户操作App至任意界面,然后按home键切到后台,然后再从后台返回前台后,如何将App显示到指定界面? 对于这个需求,具体来说分2种情况: 指定界面是一种盖在整个App上的效果.例如: 有道云笔记的 ...

  7. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  8. CSS3制作动画的三个属性

    CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation:我们一起学习完了Transform和Transition,让我们对元素实现了一些基本的动画效果,这 ...

  9. React Native之FlexBox介绍和使用

    # 前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会 ...

  10. UITextFeild的用法

    一. 修改占位字符串的 颜色: =======方法一 ====================================== #import "ViewController.h&quo ...