当前位置: 移动技术网 > IT编程>开发语言>.net > .net 日志系统解析

.net 日志系统解析

2017年12月12日  | 移动技术网IT编程  | 我要评论
一.   写在前面 日志系统对于任何项目都是必不可少的,无论对于测试阶段的debug,性能测试,执行时间,操作记录还是线上的问题排查,访问记录等,日志

一.   写在前面

日志系统对于任何项目都是必不可少的,无论对于测试阶段的debug,性能测试,执行时间,操作记录还是线上的问题排查,访问记录等,日志系统都扮演着重要的角色。本篇分享的目的是能帮助需要的人快速搭建自己的logsystem.,仅供参考。 先上个图呗,自认为页面还算清爽吧:

我的logsystem使用log4net入库的方式,网上特别多的分享,但是能完整运行下来的真是很少,所以现在需要和以后用得上的小伙伴抓紧收藏咯。

二.  log4net自定义内容入库

log4net存日志的方式,给人的感觉实在是不实用,it行业不都求一个自动化吗?废话不说了,先上log4net入库系统的代码。

logsystem数据库结构,我的建议是一个项目一个表。

在log组件中,你需要这样几个类。下面分别给出代码:

logcontent.cs,这里定义了log实体,在实体化实体的时候,通过给构造函数传参创建好这个对象。注释很详细了

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,定义了日志级别,和写入方法

[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

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

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连接。注释已经很详细了

<?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查一下就算了,代码和条件拼接如下

 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);
 }
 }

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持移动技术网!

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网