功能需求说明
- 记录错误
在网站开发中、发布后肯定会出现很多错误,有大有小,不但不能将这些错误提示给使用人员(优化用户体验),还需要通过日志功能将这些异常记录下来。开发人员可以通过日志迅速发现问题,进而修复问题。 - 记录访问、操作信息
在网站运行中需要对访问者的访问记录、操作进行记录。
功能实现
以前就是使用自己开发一个简单的日志类,进行记录。但是因为个人能力的不够,在使用的过程中出现了很多问题。于是在网上看看比较好的开源日志插件,最终选择使用Nlog这个。
- 关于Nlog的安装使用
这个是上我感觉这个是比较清楚的一个Nlog教程。 - 难点
- 记录系统异常时需要记录异常的具体信息,在Nlog中使用Layout布局非常方便,使用Nlog的内置参数可以很清楚的记录错误的信息,这个是Nlog内置参数表。这个我用来记录系统异常的Config中Layout配置。主要是将异常记录到文本中,将用户的操作和访问记录上传到数据库中.
INSERT INTO Logs VALUES(@Level,@AuthorizationID,@Dates,@LogKinds,@PermissionID,@OpContent,@PermissionID,
@OpRes,@IpAddress,@PageNameID);
异常是记录到程序根目录的file.txt文件中的
- 记录用户访问、操作历史时需要使用到自定义的参数,这个我在数据库中用来记录用户访问、操作历史的表LogRec
字段名称 | 字段类型 | 字段说明 |
---|---|---|
RecId | int | 记录的主键 |
Level | nvarchar(20) | 日志级别 |
AuthorizationID | guid | 进行操作的授权ID |
Dates | datetime | 产生的时间 |
LogKinds | nvarchar(20) | 操作类型 |
PermissionID | int | 进行操作的ID |
OpContent | nvarchar(200) | 操作的具体内容 |
OpRes | bit | 操作的结果 |
IpAddress | varchar(20) | 访客的IP地址 |
PageNameID | int | 具体的网址页面ID |
Nlog配置与系统异常是一致的,只是这里要注意我使用了自定义参数
- 程序中调用
首先定义了一个Logs基础类
public class Logs
{
public enum Levels
{
Debug, Trace, Error, Fatal, Info
}
public int RecId { get; set; }
public LogLevel Level { get; set; }
public Guid AuthorizationID { get; set; }
public DateTime Dates { get; set; }
public string LogKinds { get; set; }
public int PermissionID { get; set; }
public string OpContent { get; set; }
public bool OpRes { get; set; }
public string IpAddress { get; set; }
public int PageNameID { get; set; }
public Logs(User user,string logkinds, Levels logLevel,string opContent,bool opRes,int permissionID)
{
AuthorizationID = user.AuthorizationID;
IpAddress = user.LoginIp;
PageNameID = user.PageNameID;
Dates = DateTime.Now;
LogKinds = logkinds;
OpContent = opContent;
OpRes = opRes;
PermissionID = permissionID;
switch(logLevel)
{
case Levels.Debug:
{
Level = LogLevel.Debug;
break;
}
case Levels.Trace:
{
Level = LogLevel.Trace;
break;
}
case Levels.Error:
{
Level = LogLevel.Error;
break;
}
case Levels.Fatal:
{
Level = LogLevel.Fatal;
break;
}
case Levels.Info:
{
Level = LogLevel.Info;
break;
}
default:
{
Level = LogLevel.Info;
break;
}
}
}
}
再定义了一个Logger使用类
public class Logger
{
NLog.Logger _logger;
private Logger(NLog.Logger logger)
{
_logger = logger;
}
public Logger(string name) : this(LogManager.GetLogger(name))
{
}
public static Logger Default { get; private set; }
static Logger()
{
Default = new Logger(NLog.LogManager.GetCurrentClassLogger());
}
#region Debug
public void Debug(string msg, params object[] args)
{
_logger.Debug(msg, args);
}
public void Debug(string msg, Exception err)
{
_logger.Debug(err, msg);
}
#endregion
#region Info
public void Info(string msg, params object[] args)
{
_logger.Info(msg, args);
}
///
/// 记录系统异常
///
///
///
public void Info(string msg, Exception err)
{
_logger.Error(err, msg);
}
#endregion
#region Warn
public void Warn(string msg, params object[] args)
{
_logger.Warn(msg, args);
}
public void Warn(string msg, Exception err)
{
_logger.Warn(err, msg);
}
#endregion
#region Trace
public void Trace(string msg, params object[] args)
{
_logger.Trace(msg, args);
}
public void Trace(string msg, Exception err)
{
_logger.Trace(err, msg);
}
#endregion
#region Error
public void Error(string msg, params object[] args)
{
_logger.Error(msg, args);
}
public void Error(string msg, Exception err)
{
_logger.Error(err, msg);
}
#endregion
#region Fatal
public void Fatal(string msg, params object[] args)
{
_logger.Fatal(msg, args);
}
public void Fatal(string msg, Exception err)
{
_logger.Fatal(err, msg);
}
#endregion
#region Custom
///
/// 记录用户操作、访问记录
///
///
public void Process(Logs log)
{
var ei = new MyLogEventInfo(log.Level, _logger.Name, log.LogKinds);
ei.TimeStamp = log.Dates;
ei.Properties["Action"] = log.IpAddress;
ei.Properties["Amount"] = log.OpContent;
_logger.Log(log.Level, ei);
}
#endregion
///
/// Flush any pending log messages (in case of asynchronous targets).
///
/// Maximum time to allow for the flush. Any messages after that time will be discarded.
public void Flush(int? timeoutMilliseconds = null)
{
if (timeoutMilliseconds != null)
NLog.LogManager.Flush(timeoutMilliseconds.Value);
NLog.LogManager.Flush();
}
}
public class MyLogEventInfo : LogEventInfo
{
public MyLogEventInfo() { }
public MyLogEventInfo(LogLevel level, string loggerName, string message) : base(level, loggerName, message)
{ }
public override string ToString()
{
//Message format
//Log Event: Logger='XXX' Level=Info Message='XXX' SequenceID=5
return FormattedMessage;
}
}
在程序中调用的时候,如果需要记录异常
try
{
//执行代码
}
catch (Exception e1)
{
//进行异常记录
Logger.Default.Error("用户登录校验", e1);
}
如果要记录用户的访问记录
Logs logs = new Logs(user, "新增", Logs.Levels.Info, "新增标签记录"+results, true, 100001);
Logger.Default.Process(logs);
至此基本的日志功能就搭建好了,因为目前网站处于基础的开发阶段,后面要对日志进行更细致的分类记录,到时候再和大家探讨下!就酱了