本文记录通过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. dsu on tree详解

    这个算法还是挺人性化的,没有什么难度 就是可能看起来有点晕什么的. 大体 思想是 利用重链刨分来优化子树内部的查询. 考虑一个问题要对每个子树都要询问一次.我们暴力显然是\(n^2\)的. 考虑一下优 ...

  2. mysqld_multi多实例部署

    mysql多实例部署 目录 mysql多实例部署 下载软件 配置用户和组并解压二进制程序至/usr/local下 创建实例数据存放的目录 初始化各实例 配置配置文件/etc/my.cnf 启动各实例 ...

  3. Netty(一):server启动流程解析

    netty作为一个被广泛应用的通信框架,有必要我们多了解一点. 实际上netty的几个重要的技术亮点: 1. reactor的线程模型; 2. 安全有效的nio非阻塞io模型应用; 3. pipeli ...

  4. Python 图像处理 OpenCV (16):图像直方图

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  5. python5.3二进制文件的读写

    fh=open(r"C:\1.png","rb")#转换成二进制数据data=fh.read()#对二进制数据进行读取 fh1=open(r"C:\2 ...

  6. Linux学习笔记之linux软件包安装以及源的替换

    先是软件源的替换,在刚安装的Ubuntu中会配有原先的软件源,所以如果要替换时,可在网上找与自己ubuntu相对应的软件源,比如我的ubuntu版本为12.04,所以我得找到相对应能够适用Ubuntu ...

  7. troubleshoot之:用control+break解决线程死锁问题

    目录 简介 死锁的代码 control+break命令 Full thread dump 死锁检测 Heap信息 总结 简介 如果我们在程序中遇到线程死锁的时候,该怎么去解决呢? 本文将会从一个实际的 ...

  8. Redis服务之Redis5集群相关命令说明

    上一篇博客主要聊了下redis.trib.rb这个工具来管理redis3/4 cluster 中的节点,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13456 ...

  9. three.js 着色器材质之纹理

    今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击博客原文. 这里我们分别引入三个纹理,分别是地球的表面纹理,对应的海拔灰度图,和云朵的纹理.使用表面纹理还 ...

  10. C#LeetCode刷题,走进Google,走近人生

    概述 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/1015 访问. 本系列博文将会向大家展示我在LeetCode上的刷 ...