本文记录通过log4net将日志信息记录到SQLServer数据库中。

1、新建控制台应用程序 Log4NetDemo;

2、通过NuGet安装Log4Net (项目版本2.0.8);

3、项目根目录下添加 log4net.config 配置文件;

<?xml version="1.0"?>
<configuration>
<!--声明一个名为“log4net”的自定义配置节-->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections> <!--log4net配置信息-->
<log4net>
<logger name="WebLogger">
<level value="INFO"/><!--定义在这个级别之上的日志才会被记录-->
<appender-ref ref="ADONetAppender" /><!--定义日志对象使用的Appender对象-->
</logger> <!--Appenders用来定义日志的输出方式 -->
<!--name = “AdoNetAppender” sql数据库-->
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<!--缓冲区大小为10,缓存10条记录同时写入数据库,避免每次都去请求数据库连接写数据-->
<bufferSize value=""/>
<!-- SQL数据源 ,本地安装SQL客户端-->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<!-- SQL连接字符串,修改为自己的-->
<connectionString value="Data Source=ali.xsd.com;Initial Catalog=test;Integrated Security=false;User ID=admin;Password=123456;" />
<!-- 数据库插入-->
<commandText value="INSERT INTO AppOpLog ([ThreadId],[Level],[Message],[Exception],[LogTime],[UserPhone],[IP],[ControllerName],[ActionName],[ActionParam],[Url],[HttpHeader],[HttpMethod],[UserAgent],[StartTime],[EndTime],[RunTime])
VALUES ( @thread,@log_level, @message, @exception,@log_date, @UserPhone,@IP,@ControllerName,@ActionName,@ActionParam,@Url,@HttpHeader,@HttpMethod,@UserAgent,@StartTime,@EndTime,@RunTime)"/>
<!--线程号-->
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%t" />
</layout>
</parameter>
<!--日志记录时间,RawTimeStampLayout 为默认的时间输出格式-->
<parameter>
<parameterName value="@log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout"/>
</parameter>
<!--日志等级-->
<parameter>
<parameterName value="@log_level"/>
<dbType value="String"/>
<size value=""/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level"/>
</layout>
</parameter>
<!--异常 ExceptionLayout 默认的异常输出格式-->
<parameter>
<parameterName value="@exception"/>
<dbType value="String"/>
<size value=""/>
<layout type="log4net.Layout.ExceptionLayout"/>
</parameter> <parameter>
<parameterName value="@message"/>
<dbType value="String"/>
<size value=""/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message"/>
</layout>
</parameter> <!--自定义成员-->
<parameter>
<parameterName value="@UserPhone" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%UserPhone" />
</layout>
</parameter>
<parameter>
<parameterName value="@IP" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%IP" />
</layout>
</parameter>
<parameter>
<parameterName value="@StartTime" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%StartTime" />
</layout>
</parameter>
<parameter>
<parameterName value="@EndTime" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%EndTime" />
</layout>
</parameter>
<parameter>
<parameterName value="@RunTime" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%RunTime" />
</layout>
</parameter>
<parameter>
<parameterName value="@ControllerName" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%ControllerName" />
</layout>
</parameter>
<parameter>
<parameterName value="@ActionName" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%ActionName" />
</layout>
</parameter>
<parameter>
<parameterName value="@ActionParam" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%ActionParam" />
</layout>
</parameter>
<parameter>
<parameterName value="@Url" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%Url" />
</layout>
</parameter>
<parameter>
<parameterName value="@HttpMethod" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%HttpMethod" />
</layout>
</parameter>
<parameter>
<parameterName value="@HttpHeader" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%HttpHeader" />
</layout>
</parameter>
<parameter>
<parameterName value="@UserAgent" />
<dbType value="String" />
<layout type="Log4NetDemo.CustomLayout">
<conversionPattern value="%UserAgent" />
</layout>
</parameter> </appender>
</log4net> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

4、日志记录中添加自定义字段

public class CustomLayout : log4net.Layout.PatternLayout
{
public CustomLayout()
{
this.AddConverter("UserPhone", typeof(UserPhonePatternConverter));
this.AddConverter("IP", typeof(IPPatternConverter));
this.AddConverter("ControllerName", typeof(ControllerNamePatternConverter));
this.AddConverter("ActionName", typeof(ActionNamePatternConverter));
this.AddConverter("ActionParam", typeof(ActionParamPatternConverter));
this.AddConverter("Url", typeof(UrlPatternConverter));
this.AddConverter("HttpHeader", typeof(HttpHeaderPatternConverter));
this.AddConverter("HttpMethod", typeof(HttpMethodPatternConverter));
this.AddConverter("UserAgent", typeof(UserAgentPatternConverter));
this.AddConverter("StartTime", typeof(StartTimePatternConverter));
this.AddConverter("EndTime", typeof(EndTimePatternConverter));
this.AddConverter("RunTime", typeof(RunTimePatternConverter));
}
} internal sealed class UserPhonePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.UserPhone);
}
} internal sealed class IPPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.IP);
}
} internal sealed class ControllerNamePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.ControllerName);
}
} internal sealed class ActionNamePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.ActionName);
}
} internal sealed class ActionParamPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.ActionParam);
}
} internal sealed class UrlPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.Url);
}
} internal sealed class HttpHeaderPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.HttpHeader);
}
} internal sealed class HttpMethodPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.HttpMethod);
}
} internal sealed class UserAgentPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.UserAgent);
}
} internal sealed class StartTimePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.StartTime);
}
} internal sealed class EndTimePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.EndTime);
}
} internal sealed class RunTimePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog; if (logMessage != null)
writer.Write(logMessage.RunTime);
}
}
5、程序启动时读取配置文件,控制台程序在Main方法中添加
//注册 log4net,注意这里的路径为绝对路径
log4net.Config.XmlConfigurator.Configure(
new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\\log4net.config")
);
6、记录日志,定义LogHelper.cs
public class LogHelper
{
public static string LoggerName = "DbLogger"; private static ILog log = LogManager.GetLogger(LoggerName); /// <summary>
/// 记录一般日志
/// </summary>
public static void LogInfo(AppOpLog opLog)
{
if (log.IsInfoEnabled)
{
log.Info(opLog);
}
} /// <summary>
/// 记录错误
/// </summary>
public static void LogError(AppOpLog opLog, Exception ex)
{
if (log.IsErrorEnabled)
{
log.Error(opLog, ex);
}
} /// <summary>
/// 记录严重错误
/// </summary>
public static void LogFatal(AppOpLog opLog, Exception ex)
{
if (log.IsFatalEnabled)
{
log.Fatal(opLog, ex);
}
} /// <summary>
/// 记录警告
/// </summary>
public static void LogWarn(AppOpLog opLog)
{
if (log.IsWarnEnabled)
{
log.Warn(opLog);
}
}
}

7、在程序中调用

static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure(
new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\\log4net.config")
); AppOpLog opLog = new AppOpLog();
opLog.IP = "192.124.0.0";
opLog.ActionName = "action";
opLog.ControllerName = "controller";
opLog.ActionParam = "param";
opLog.Url = "url";
opLog.HttpHeader = "header";
opLog.HttpMethod = "get";
opLog.UserAgent = "useragent";
opLog.StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
opLog.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
opLog.RunTime = (Convert.ToDateTime(opLog.EndTime) - Convert.ToDateTime(opLog.StartTime)).TotalSeconds.ToString(); LogHelper.LogError(opLog,new Exception("error"));//调用 Console.ReadKey();
}

8、结果

注意:控制台程序调试的时候需要将 log4net.config属性设为始终复制;

附sql脚本

CREATE TABLE [dbo].[AppOpLog](
[IntId] [int] IDENTITY(,) NOT NULL,
[UserCharId] [varchar]() NULL,
[UserPhone] [varchar]() NULL,
[LogTime] [datetime] NOT NULL,
[IP] [varchar]() NOT NULL,
[ControllerName] [varchar]() NOT NULL,
[ActionName] [varchar]() NOT NULL,
[ActionParam] [varchar](max) NOT NULL,
[Url] [varchar](max) NOT NULL,
[HttpHeader] [varchar](max) NULL,
[HttpMethod] [varchar]() NULL,
[UserAgent] [varchar]() NULL,
[StartTime] [datetime] NOT NULL,
[EndTime] [datetime] NOT NULL,
[RunTime] [varchar]() NOT NULL,
[Level] [varchar]() NOT NULL,
[ThreadId] [int] NOT NULL,
[Message] [varchar](max) NULL,
[Exception] [varchar](max) NULL,
[CreateTime] [datetime] NULL
)

AppOpLog.cs

public class AppOpLog
{
public string IP { get; set; }
public string ControllerName { get; set; }
public string ActionName { get; set; }
public string ActionParam { get; set; }
public string Url { get; set; }
public string HttpHeader { get; set; }
public string HttpMethod { get; set; }
public string UserAgent { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public string RunTime { get; set; }
}

log4net调试:当log4net日志插入失败时,在Web.Config配置文件里添加可以查看错误情况,这里注意对应的目录下要有写文件的权限

<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>

测试Demo地址:https://github.com/zhrong92/Log4NetDemo

 
 

基于Log4Net记录日志到SQLServer(自定义字段)的更多相关文章

  1. log4net记录日志到数据库自定义字段

    假设数据库中有如下自定义字段:   1.根据自定义字段定义日志信息对象     public class MessageLog     {           /// <summary> ...

  2. log4net 记录日志到sqlserver

    参考:http://blog.csdn.net/niuyongjie/article/details/5777625 demo

  3. log4net自定义字段写入SqlServer数据库 ASP.net

    首先申明,本示例经过本作者亲自试验通过,可以运行 第一步 编写log4net配置文件 此处为Log.xml,该文件放在与Web.config平级的位置 <?xml version="1 ...

  4. Log4net 使用之 自定义字段

    Log4net 是.Net下一个非常优秀的开源日志记录组件.Log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介. 由于业务需要,计划为日志增加2个字段,除了 ...

  5. Log4net 自定义字段到数据库(二)

    这种方法比第一种方法麻烦些 Log4Net.config <?xml version="1.0" encoding="utf-8" ?> <c ...

  6. Log4net 自定义字段到数据库

    今天要求做个log4net自定义字段到数据库,在网上找了好多例子,都运行不成功.最后找了个国外的,很简单的就解决了. log4net它已经定义的字段有 <commandText value=&q ...

  7. Log4net 自定义字段 写入Oracle 使用ODP.NET Managed驱动

    一.环境说明: 开发工具:vs2010   ,数据库:oracle 11g ,版本:log4net的目前最新版本1.2.13.0    :  Oracle.ManagedDataAccess.dll ...

  8. 基于Log4Net本地日志服务简单实现

    背景 项目开发中,我们或多或少会使用诸如NLog,Log4Net,Kafka+ELK等等日志套件: 基于关注点分离原则,业务开发的时候不应该关注日志具体实现:并且后续能方便切换其他日志套件: 这里先实 ...

  9. 使用log4net记录日志到数据库(含有自定义属性)

    记录日志是管理系统中对用户行为的一种监控与审核,asp.net中记录日志的方式有很多种,这里我只介绍一下最近用到的log4net,关于他的具体介绍网上有很多,我讲一下他的用法. 第一步:在配置文件中的 ...

随机推荐

  1. intel:spectre&Meltdown侧信道攻击(一)

    只要平时对安全领域感兴趣的读者肯定都听过spectre&Meltdown侧信道攻击,今天简单介绍一下这种攻击的原理( https://www.bilibili.com/video/av1814 ...

  2. windows:驱动模块隐藏

    windwos下想要搞点事,权限当然是越大越好:驱动模块天生在0环,和操作提供平级,大家互相是兄弟,所以很多外挂.木马.病毒都会使用驱动达到自己的目的.那么问题来了:PCHUNTER这种工具能查到系统 ...

  3. python 操作元组 列表===python中三大宝刀(字典已经再上一遍 说过)

    字典俗称,世界有多大就能装多大 列表俗称,你们决定 元组俗称,可远观而不可亵玩焉 列表的相关操作a=['1','2','3','5','6','7']# print(a[0])# print(a[0: ...

  4. c++ 模板类的 友元函数

    #pragma once #include <iostream> template <class T> class stack { template <class Ty& ...

  5. 解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)...

    在IDEA中将xxxMapper.xml文件创建在(src/main/java)目录中,运行报错:org.apache.ibatis.binding.BindingException: Invalid ...

  6. 理解HTTP的POST和PUT的区别

    1.HTTP Methods HTTP Methods GET POST PUT HEAD DELETE PATCH OPTIONS GET is used to request data from ...

  7. CSS页面布局与网格(上)

    1.布局规划 1.1 网格 网格系统是设计师在切分布局时作为参照的一组行和列. 1.2 布局辅助类 类名用于为布局添加样式.为了让样式可以重用,让类名表达其意图. .column { /* 一般列的样 ...

  8. java_数组的定义与操作

    数组定义和访问 数组概念 数组概念: 数组就是存储多个数据的容器,数组的长度固定,多个数据的数据类型要一致. 数组的定义 方式一 数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度 ...

  9. Java 开发者的编程噩梦,为什么你的代码总有 bug🐛?

    文章已经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所需要掌握的核心知识,欢迎Star和指教. 欢迎关注我的公众号,文章每周更新. 很多 Java 初学者在 ...

  10. csapp第九章笔记-虚拟内存

    目录 物理与虚拟寻址 地址空间 虚拟内存作为缓存的工具 虚拟内存作为内存管理的工具 虚拟内存作为内存保护的工具 地址翻译 使用TLB(翻译后备缓冲器)加速地址翻译 多级页表 物理与虚拟寻址 计算机系统 ...