.net 日志系统解析

一.   写在前面

日志系统对于任何项目都是必不可少的,无论对于测试阶段的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);
 }
 }

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

(0)

相关推荐

  • .NET 日志系统设计思路及实现代码

    日志很明显是帮助大家定位到问题的一个很重要的手段,本来是想直接使用的NLog 来做系统的日志工具,哎伤不起,一变态非要说这个有很多不可控制的因素,这里我给大家讲一下我是怎么实现日志模块的,欢迎拍砖 总体架构图 •    在这里我把日子的等级分为 跟踪,BUG 和错误 3种  定义枚举如下 复制代码 代码如下: /// <summary>    /// 日志等级    /// </summary>    public enum Loglevel    {        Track=1

  • .net 日志系统解析

    一.   写在前面 日志系统对于任何项目都是必不可少的,无论对于测试阶段的debug,性能测试,执行时间,操作记录还是线上的问题排查,访问记录等,日志系统都扮演着重要的角色.本篇分享的目的是能帮助需要的人快速搭建自己的LogSystem.,仅供参考. 先上个图呗,自认为页面还算清爽吧: 我的LogSystem使用Log4net入库的方式,网上特别多的分享,但是能完整运行下来的真是很少,所以现在需要和以后用得上的小伙伴抓紧收藏咯. 二.  Log4Net自定义内容入库 Log4Net存日志的方式,

  • mysql日志系统的简单使用教程

    前言 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一. 在任何一种数据库中,都会有各种各样的日志,记录着数据库工作的方方面面,以帮助数据库管理员追踪数据库曾 经发生过的各种事件. 在 MySQL 中,有 4 种不同的日志,分别是

  • jdk-logging log4j logback日志系统实现机制原理介绍

    目录 1 需要解决的疑惑 2 jdk自带的logging 2.1 使用案例 2.2 简单过程分析: 3 log4j1 3.1 使用案例 3.1.1 需要的jar包 3.1.2 使用方式 3.2 获取Logger的原理 3.3 主要对象总结 4 log4j2 4.1 背景介绍 4.2 log4j2的使用案例 4.2.1 需要的jar包 4.2.2 使用方式 4.3 使用过程简单分析 4.4 主要对象总结 5 logback 5.1 使用案例 5.1.1 需要的jar包 5.1.2 使用方式 5.3

  • Android 日志系统Logger源代码详细介绍

    我们知道,在Android系统中,提供了一个轻量级的日志系统,这个日志系统是以驱动程序的形式实现在内核空间的,而在用户空间分别提供了Java接口和C/C++接口来使用这个日志系统,取决于你编写的是Android应用程序还是系统组件.在前面的文章浅谈Android系统开发中LOG的使用中,已经简要地介绍了在Android应用程序开发中Log的使用方法,在这一篇文章中,我们将更进一步地分析Logger驱动程序的源代码,使得我们对Android日志系统有一个深刻的认识. 既然Android 日志系统是

  • DNS 系统解析过程概述

    DNS(Domain Name Servive,域名服务)是Internet/Intranet中最基础也是非常重要的一项服务,提供了网络访问中域名到IP地址的自动转换.我们知道,Inetrnet上的主机成千上万,并且还在随时不断增加,不可能由一个或几个DNS服务器能够实现这样的解析过程,传统主机表(hosts)方式更无法胜任,事实上DNS依靠一个分布式数据库系统对网络中主机域名进行解析,并及时地将新主机的信息传播给网络中的其它相关部分,因而给网络维护及扩充带来了极大的方便.          -

  • 浅谈Slf4j与其他日志系统兼容的使用方法

    java生产的各种框架(如spring等)里各个框架会使用不同的日志体系,多个不同日志在一个jvm里混搭会出现一定问题 ,这里梳理一下java体系里常见的日志框架,以SFL4j为中心介绍下跟各个日志框架的关系,介绍下生产环境如何打理各种日志框架. 1. 接口简介 在java的体系里,主要有slf4j和common-logging两种日志体系接口.实现的框架有很多,主流的诸如logback.log4j等. 当然,虽然都是接口,但两者也可以通过桥接包实现相互的日志代理输出. common-loggi

  • Android的日志系统分层与logcat使用

    android的日志系统有典型的android层次结构.本文指出路径,分析层次但不分析代码,这里还介绍logcat的使用和log_bg服务. 日志系统分层 1.先从驱动开始 linux-3.10/drivers/staging/android/logger.c linux-3.10/drivers/staging/android/logger.h logger_init创建4个日志设备文件/dev/main./dev/events./dev/radio./dev/system. 分析代码的话跟踪

  • Spring Boot Logback配置日志过程解析

    这篇文章主要介绍了Spring Boot Logback配置日志过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 出于性能等原因,Logback 目前是springboot应用日志的标配: 当然有时候在生产环境中也会考虑和三方中间件采用统一处理方式. 配置时考虑点 支持日志路径,日志level等配置 日志控制配置通过application.yml下发 按天生成日志,当天的日志>50MB回滚 最多保存10天日志 生成的日志中Pattern自

  • Spring Boot2配置服务器访问日志过程解析

    这篇文章主要介绍了Spring Boot2配置服务器访问日志过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Tomcat控制台中看到的日志是服务器的日志,而服务器访问日志则是记录服务处理的请求信息. 开发环境:IntelliJ IDEA 2019.2.2 Spring Boot版本:2.1.8 1.新建一个名称为demo的Spring Boot项目. 2.application.yml 添加配置 server: tomcat: base

  • php高性能日志系统 seaslog 的安装与使用方法分析

    本文实例讲述了php高性能日志系统 seaslog 的安装与使用方法.分享给大家供大家参考,具体如下: 一.什么是日志系统 一般用于记录系统运行时的信息,一般分为三类:系统日志,应用程序日志,安全日志.日志功能不能影响用户的正常使用. 二.为什么需要日志功能 1.了解系统运行情况     2.记录用户操作信息     3.收集数据 三.为什么选seaslog 1.高性能(使用C语言)     2.无需配置     3.功能完善,使用简单 四.安装seaslog 下载seaslog,根据自已的系统

随机推荐