前几篇文章谈了谈开发框架,从今天开始公开一些项目的具体内容。
今天先从最底层的日志项目开始。这个项目目前还很轻,因为暂时只用log4net来记录日志。不久将会扩展其他方法,考虑扩展性,我决定将他单独提出来作为一个项目,来进行维护。以便以后更新的时候更新轻量级dll就可以了。
更新有风险,升级须谨慎。
对设计模式有兴趣的初学者可以看看这个小项目,相信对理解单件,适配器,工厂会有帮助。
LogAdapter项目说明
一、项目功能
提供上层对多种日志记录工具的统一调用。适配器项目。
ILogAdapter允许被外部继承,但应优先扩展在本项目内。
目前只有log4net的适配器,以后可以扩展以数据库,消息队列,邮件等多种形式。
二、类库说明
1. ILogAdapter 接口,声明日志项目必须实现的方法。
2. ILogAdapterFactory 工厂,获取日志工具的适配器实例
a) public static ILogAdapter GetLogInstance(LogType type) 返回适配器的实例
3. Log4NetAdapter Log4Net.Dll的适配器 继承自ILogAdapter
适用该日志需要在Web.Config中配置相应的节点。
单件
a) void WirteLog(string logInfo, string logName) 记录日志 Info级
b) void WirteLog(string logInfo, Exception ex, string logName) 记录日志 Fatal级
c) void WirteLog(string logInfo, Exception ex, string logName, WirteType logType) 记录日志 自定义级别
4. 文件LogEnum.cs 枚举类,包含日志级别及工厂产生的适配器类型
项目用例:
ILogAdapter log = ILogAdapterFactory.GetLogInstance(LogType);
log.WirteLog(loginfo,ex,logname,WirteType);
付代码如下。该项目需要引用log4net.dll。思路是工厂维护的单件适配器组。
由两种enum,一种是控制日志工具,一种是控制日志级别。
由于目前只用到了log4net,所以只有一个适配器。以后会考虑入库及email方式的日志。
btw,我不喜欢反射,反射消耗资源太严重,我宁愿封装细粒度的项目来更新dll。
作为底层项目,一定要控制好访问权限。访问修饰符都是很有必要斟酌的。
在以后的项目介绍中如果是微项目我将直接把代码贴上来,如果项目比较胖,我会放上rar。
Code
using System;
using System.Collections.Generic;
using System.Text;
namespace LogAdapter
{
public interface ILogAdapter
{
void WirteLog(string logInfo, string logName);
void WirteLog(string logInfo, Exception ex, string logName);
void WirteLog(string logInfo, Exception ex, string logName, WirteType logType);
}
}
Code
/*
ILogAdapter log = ILogAdapterFactory.GetLogInstance(LogType);
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace LogAdapter
{
public static class ILogAdapterFactory
{
public static ILogAdapter GetLogInstance(LogType type)
{
ILogAdapter iLog = null;
switch (type)
{
case LogType.Log4Net:
default:
iLog = Log4NetAdapter.log;
break;
}
return iLog;
}
}
}
Code
/*
ILogAdapter log = ILogAdapterFactory.GetLogInstance(LogType);
log.WirteLog(loginfo,ex,logname,WirteType);
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace LogAdapter
{
/// <summary>
/// 以DOMConfigurator加载配置的Log4Net
/// </summary>
internal sealed class Log4NetAdapter : ILogAdapter
{
private Log4NetAdapter()
{
log4net.Config.DOMConfigurator.Configure();
}
public void WirteLog(string logInfo, Exception ex, string logName, WirteType logType)
{
StringBuilder logMsg = new StringBuilder();
//记录时间
logMsg.Append("\r\nLogTime:");
logMsg.Append(DateTime.Now.ToString());
logMsg.Append("\r\nLogIP:");
logMsg.Append(Tools4Log.GetIP());
logMsg.Append("\r\n");
//传入的记录内容
logMsg.Append(logInfo);
//记录异常的重要信息
if (ex != null)
{
logMsg.Append("\tExceptionMessage:");
logMsg.Append("\r\n\t");
if (ex.InnerException != null)
{
logMsg.Append(ex.InnerException.ToString());
}
logMsg.Append("\r\n\t");
logMsg.Append(ex.Message);
logMsg.Append("\r\n\t");
logMsg.Append(ex.StackTrace);
logMsg.Append("\r\n");
}
logMsg.Append("\r\n-------------------------------------------------------\r\n\r\n");
try
{
log4net.ILog ilog = log4net.LogManager.GetLogger(logName);
switch (logType)
{
case WirteType.Fatal:
ilog.Fatal(logMsg.ToString());
break;
case WirteType.Error:
ilog.Error(logMsg.ToString());
break;
case WirteType.Warn:
ilog.Warn(logMsg.ToString());
break;
case WirteType.Info:
ilog.Info(logMsg.ToString());
break;
case WirteType.Debug:
ilog.Debug(logMsg.ToString());
break;
}
}
catch
{
//记录日志都出错了还能有什么办法呢
}
}
/// <summary>
/// Info级
/// </summary>
/// <param name="logInfo"></param>
/// <param name="logName"></param>
public void WirteLog(string logInfo, string logName)
{
WirteLog(logInfo, null, logName, WirteType.Info);
}
/// <summary>
/// Fatal级
/// </summary>
/// <param name="logInfo"></param>
/// <param name="ex"></param>
/// <param name="logName"></param>
public void WirteLog(string logInfo, Exception ex, string logName)
{
WirteLog(logInfo, ex, logName, WirteType.Fatal);
}
public readonly static Log4NetAdapter log = new Log4NetAdapter();
}
}
Code
using System;
using System.Collections.Generic;
using System.Text;
namespace LogAdapter
{
public enum WirteType
{
Fatal,
Error,
Warn,
Info,
Debug
}
public enum LogType
{
Log4Net
}
}
Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace LogAdapter
{
internal static class Tools4Log
{
/// <summary>
/// 获得当前页面客户端的IP
/// </summary>
/// <returns>当前页面客户端的IP</returns>
public static string GetIP()
{
string result = String.Empty;
if (HttpContext.Current != null)
{
result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (String.IsNullOrEmpty(result))
{
result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
if (String.IsNullOrEmpty(result))
{
result = HttpContext.Current.Request.UserHostAddress;
}
}
return result;
}
}
}
PS:今年过年真他M不爽。我记住了,空头支票。(牢骚)
PS2:我爱开源。(*^_^*)