一. 写在前面
日志系统对于任何项目都是必不可少的,无论对于测试阶段的debug,性能测试,执行时间,操作记录还是线上的问题排查,访问记录等,日志系统都扮演着重要的角色。本篇分享的目的是能帮助需要的人快速搭建自己的LogSystem.,仅供参考。 先上个图呗,自认为页面还算清爽吧:
我的LogSystem使用Log4net入库的方式,网上特别多的分享,但是能完整运行下来的真是很少,所以现在需要和以后用得上的小伙伴抓紧收藏咯。
二. Log4Net自定义内容入库
Log4Net存日志的方式,给人的感觉实在是不实用,IT行业不都求一个自动化吗?废话不说了,先上Log4net入库系统的代码。
LogSystem数据库结构,我的建议是一个项目一个表。
在Log组件中,你需要这样几个类。下面分别给出代码:
LogContent.cs,这里定义了Log实体,在实体化实体的时候,通过给构造函数传参创建好这个对象。注释很详细了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
using System;
namespace LogComponent
{
public class LogContent
{
public LogContent( string logLevel, string logMsg, string logModule, string description, string userName)
{
LogLevel = logLevel;
UserName = userName;
Description = description;
LogMsg = logMsg;
LogModule = logModule;
}
/// <summary>
/// 日志级别
/// </summary>
public string LogLevel { get ; set ; }
/// <summary>
/// 日志消息
/// </summary>
public string LogMsg { get ; set ; }
/// <summary>
/// 系统登陆用户
/// </summary>
public string UserName { get ; set ; }
/// <summary>
/// 日志描述信息
/// </summary>
public string Description { get ; set ; }
/// <summary>
/// 记录时间
/// </summary>
public DateTime LogDate { get ; set ; }
/// <summary>
/// 模块名称
/// </summary>
public string LogModule { get ; set ; }
}
}
|
LogHelper.cs,定义了日志级别,和写入方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
[assembly: log4net.Config.XmlConfigurator(Watch = true ,ConfigFile = "log4net.config" )]
namespace LogComponent
{
public class LogHelper
{
static log4net.ILog log = log4net.LogManager.GetLogger( "myLogger" );
/// <summary>
/// 异常日志
/// </summary>
/// <param name="logMsg">日志信息</param>
/// <param name="logModule">代码模块</param>
/// <param name="description">其他描述</param>
/// <param name="userName">用户名</param>
public static void LogError( string logMsg, string logModule, string description = "" , string userName = "" )
{
log.Error( new LogContent( "Error" , SubLogString(logMsg), logModule, SubLogString(description), userName));
}
public static void LogInfo( string logMsg, string logModule, string description = "" , string userName = "" )
{
log.Info( new LogContent( "Info" , SubLogString(logMsg), logModule, SubLogString(description), userName));
}
public static void LogWarn( string logMsg, string logModule, string description = "" , string userName = "" )
{
log.Warn( new LogContent( "Warn" , SubLogString(logMsg), logModule, SubLogString(description), userName));
}
public static void LogDebug( string logMsg, string logModule, string description = "" , string userName = "" )
{
log.Debug( new LogContent( "Debug" , SubLogString(logMsg), logModule, SubLogString(description), userName));
}
private static string SubLogString( string str)
{
if (str.Length > 1500)
{
return str.Substring(0, 1500);
}
return str;
}
}
}
|
MessagePartternConverter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
using log4net.Core;
using log4net.Layout.Pattern;
using System.IO;
using System.Reflection;
namespace LogComponent
{
class MessagePatternConverter : 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>
/// <returns></returns>
private object LookupProperty( string property, log4net.Core.LoggingEvent loggingEvent)
{
object propertyValue = string .Empty;
PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
if (propertyInfo != null )
propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null );
return propertyValue;
}
}
}
|
MyLayout.cs
1
2
3
4
5
6
7
8
9
10
11
|
using log4net.Layout;
namespace LogComponent
{
class MyLayout : PatternLayout
{
public MyLayout()
{
this .AddConverter( "property" , typeof (MessagePatternConverter));
}
}
}
|
其实看到这里,最重要的并不是代码了,核心部分Log4net都帮我们写好了,关键在于你的配置,下面是log4net.config的内容。拿到你的web项目里是一样用的。但是不要忘了在你的项目中引用nuget:log4net哟。
log4net.config如下:在其中主要配置了log入库的参数和sql语句,当然还有sql连接。注释已经很详细了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
<? xml version = "1.0" encoding = "utf-8" ?>
< configuration >
< configSections >
< section name = "log4net" type = "log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</ configSections >
< log4net >
< root >
< level value = "Debug" />
< appender-ref ref = "ADONetAppender" />
</ root >
< logger name = "myLogger" >
< level value = "Debug" />
< appender-ref ref = "ADONetAppender" />
</ logger >
< appender name = "ADONetAppender" type = "log4net.Appender.ADONetAppender,log4net" >
<!--BufferSize为缓冲区大小,只有日志记录超value条才会一块写入到数据库-->
< bufferSize value = "1" />
<!--或写为<param name="BufferSize" value="1" />-->
<!--引用-->
< connectionType value = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--连接数据库字符串-->
< connectionString value = "Data Source=115.29.54.31;Initial Catalog=LogSystem;uid=sa;pwd=sa.;MultipleActiveResultSets=True" />
<!--插入到表Log-->
< commandText value = "INSERT INTO HdPubLog ([LogDate],[LogMsg],[UserName],[Description],[LogLevel],[LogModule]) VALUES (@log_date,@LogMsg,@UserName,@Description,@LogLevel,@LogModule)" />
< parameter >
< parameterName value = "@log_date" />
< dbType value = "DateTime" />
< layout type = "log4net.Layout.RawTimeStampLayout" />
<!--获取log4net中提供的日志时间RawTimeStampLayout为默认的时间输出格式-->
</ parameter >
< parameter >
< parameterName value = "@LogMsg" />
< dbType value = "String" />
< size value = "1510" />
< layout type = "LogComponent.MyLayout, LogComponent" >
< param name = "ConversionPattern" value = "%property{LogMsg}" />
</ layout >
</ parameter >
< parameter >
< parameterName value = "@UserName" />
< dbType value = "String" />
< size value = "50" />
< layout type = "LogComponent.MyLayout, LogComponent" >
< param name = "ConversionPattern" value = "%property{UserName}" />
</ layout >
</ parameter >
< parameter >
< parameterName value = "@Description" />
< dbType value = "String" />
< size value = "1510" />
< layout type = "LogComponent.MyLayout, LogComponent" >
< param name = "ConversionPattern" value = "%property{Description}" />
</ layout >
</ parameter >
< parameter >
< parameterName value = "@LogLevel" />
< dbType value = "String" />
< size value = "50" />
< layout type = "LogComponent.MyLayout, LogComponent" >
< param name = "ConversionPattern" value = "%property{LogLevel}" />
</ layout >
</ parameter >
< parameter >
< parameterName value = "@LogModule" />
< dbType value = "String" />
< size value = "50" />
< layout type = "LogComponent.MyLayout, LogComponent" >
< param name = "ConversionPattern" value = "%property{LogModule}" />
</ layout >
</ parameter >
</ appender >
</ log4net >
</ configuration >
|
这样一来,你的配置就完成了,你可以直接测试插入的情况:
三. 把Log信息可视化
我的UI使用的是Datatables.js,弹出框是layer,日期组件好像是layDate,下拉框是修改样式后的select2。UI代码是我自己的一个框架里的,内容太多就不贴出来了,你只需要和以前一样,把数据从库里查出来,绑定给任意你喜欢的数据表格上。由于单页面的日志系统没有什么复杂操作,就用个sqlHelper查一下就算了,代码和条件拼接如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
public class xxxDal
{
private SqlHelper _sqlHelper = new SqlHelper();
/// <summary>
/// 获取xxx的日志
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<LogModel> GetxxxLog(SM_LogModel model)
{
StringBuilder sql = new StringBuilder();
List<SqlParameter> sqlParameters = new List<SqlParameter>();
StringBuilder sqlWhere = new StringBuilder();
if (! string .IsNullOrWhiteSpace(model.LogStartTime))
{
sqlParameters.Add( new SqlParameter( "@LogStartTime" , model.LogStartTime));
sqlWhere.Append( @" AND h.LogDate > @LogStartTime" );
}
if (! string .IsNullOrWhiteSpace(model.LogEndTime))
{
sqlParameters.Add( new SqlParameter( "@LogEndTime" , model.LogEndTime));
sqlWhere.Append( @" AND h.LogDate < @LogEndTime" );
}
if (! string .IsNullOrWhiteSpace(model.LogLevel))
{
sqlParameters.Add( new SqlParameter( "@LogLevel" , model.LogLevel));
sqlWhere.Append( @" AND h.LogLevel = @LogLevel" );
}
if (! string .IsNullOrWhiteSpace(model.LogModule))
{
sqlParameters.Add( new SqlParameter( "@LogModule" , model.LogModule));
sqlWhere.Append( @" AND h.LogModule = @LogModule" );
}
sql.AppendFormat( @"
WITH t AS ( SELECT ROW_NUMBER() OVER ( ORDER BY id DESC ) AS IndexNum ,
[Id] ,
CONVERT(VARCHAR, [LogDate], 21) AS [LogDate] ,
[UserName] ,
SUBSTRING([Description], 0, 150) AS [Description] ,
SUBSTRING([LogMsg], 0, 200) AS [LogMsg] ,
[LogLevel] ,
[LogModule]
FROM [LogSystem].[dbo].[xxxLog] h
WHERE 1 = 1
{0}
)
SELECT *
FROM t
WHERE IndexNum > @startIndex
AND indexnum < @endIndex" , sqlWhere);
sqlParameters.Add( new SqlParameter( "@startIndex" , model.Start));
sqlParameters.Add( new SqlParameter( "@endIndex" , model.Start + model.Length));
DataTable dt = _sqlHelper.ExecuteDataTable(sql.ToString(), sqlParameters.ToArray());
return DataTableTools<LogModel>.DataTableToList(dt);
}
public int GetxxxLogTotalCount(SM_LogModel model)
{
StringBuilder sql = new StringBuilder(); List<SqlParameter> sqlParameters = new List<SqlParameter>();
sql.Append( @"
SELECT COUNT(*)
FROM [HdPubLog] h where 1=1 " );
if (! string .IsNullOrWhiteSpace(model.LogStartTime))
{
sqlParameters.Add( new SqlParameter( "@LogStartTime" , model.LogStartTime));
sql.Append( @" AND h.LogDate > @LogStartTime" );
}
if (! string .IsNullOrWhiteSpace(model.LogEndTime))
{
sqlParameters.Add( new SqlParameter( "@LogEndTime" , model.LogEndTime));
sql.Append( @" AND h.LogDate < @LogEndTime" );
}
if (! string .IsNullOrWhiteSpace(model.LogLevel))
{
sqlParameters.Add( new SqlParameter( "@LogLevel" , model.LogLevel));
sql.Append( @" AND h.LogLevel = @LogLevel" );
}
if (! string .IsNullOrWhiteSpace(model.LogModule))
{
sqlParameters.Add( new SqlParameter( "@LogModule" , model.LogModule));
sql.Append( @" AND h.LogModule = @LogModule" );
}
return _sqlHelper.ExecuteScalar< int >(sql.ToString(), sqlParameters.ToArray());
}
[HttpPost]
public LogModel GetxxxxSignelLog( int id)
{
string sql = @"
SELECT [Id] ,
CONVERT(VARCHAR(30), [LogDate], 21) AS [LogDate] ,
[UserName] ,
[Description] ,
[LogMsg] ,
[LogLevel] ,
[LogModule] ,
[Id] IndexNum
FROM [LogSystem].[dbo].[xxxxLog] h
WHERE h.id = @Id" ;
var row = _sqlHelper.ExecuteDataRow(sql, new SqlParameter( "@Id" , id));
return DataTableTools<LogModel>.DataRowToModel(row);
}
}
|
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持服务器之家!
原文链接:http://www.cnblogs.com/tdws/p/6298124.html