欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.net 日志系统解析

程序员文章站 2022-04-10 08:26:15
一.   写在前面 日志系统对于任何项目都是必不可少的,无论对于测试阶段的debug,性能测试,执行时间,操作记录还是线上的问题排查,访问记录等,日志...

一.   写在前面

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

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

.net 日志系统解析

.net 日志系统解析

二.  log4net自定义内容入库

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

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

.net 日志系统解析

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

.net 日志系统解析

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哟。

.net 日志系统解析

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>

这样一来,你的配置就完成了,你可以直接测试插入的情况:

.net 日志系统解析

三.   把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);
 }
 }

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