在使用log4net写Web服务器端日志的时候,通常需要一些自定义的参数,比如请求的url,method,以及用户名等等,而log4net中默认的Log接口只提供了很少的参数。
    在网上找的其他的解决方案,都是要重写很多地方,而且经常都是不全,让人很难理解,我反正是看不懂。。。
    对俺们这些整天玩黑科技的人来说,自然要用一些不那么正常的方式来解决问题。

在这里,黑科技的意思是指绕过API或者直接修改API,其中带有一定的危险性的代码。

简单研究了一下log4net的源码(使用ILSpy反编译,野路子必备神器),发现,ILog接口的实现是log4net.Core.LogImpl,LogImpl中的Log实际方法使用了一个ILogger类型的属性Logger,这个ILogger的实现是在log4net.Repository.Hierarchy.Logger中。

在Logger类中,有一个方法,是Log,这个Log方法有两个版本,一个有三个参数,包含日志的多种参数,另一个,则是重点,它有一个参数,log4net.Core.LoggingEvent类型的参数。这里就到了关键点了。LoggingEvent中,有一个Properties属性,这个属性的内部包含了一个Hashtable。而直接使用this[key]索引器中的设置可以添加其他Key的元素。

接下来就是如何将这些预存到Properties中的数据取出来了。

log4net的基本配置:

 <configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<configSections>
<log4net>
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value="1"/>
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<connectionString value="data source=.;initial catalog=LogDatabase;persist security info=True;user id=sa;password=******;App=Application.Logger"/>
<commandText value="INSERT INTO Log ([Date],[Level],[Url],[UserName],[Method],[Message],[Exception]) VALUES (@log_date, @log_level, @url,@username, @method, @message, @exception)"/>
<parameter>
<parameterName value="@log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout"/>
</parameter>
<parameter>
<parameterName value="@log_level"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level"/>
</layout>
</parameter>
<parameter>
<parameterName value="@url"/>
<dbType value="String"/>
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Url}"/>
</layout>
</parameter>
<parameter>
<parameterName value="@username"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{UserName}"/>
</layout>
</parameter>
<parameter>
<parameterName value="@method"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Method}"/>
</layout>
</parameter>
<parameter>
<parameterName value="@message"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message"/>
</layout>
</parameter>
<parameter>
<parameterName value="@exception"/>
<dbType value="String"/>
<size value="2000"/>
<layout type="log4net.Layout.ExceptionLayout"/>
</parameter>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="ADONetAppender"/>
</root>
</log4net>
</configuration>

这里的%property{Method}会将Method这个Key中的数据赋值到这里。

数据库的数据表定义为:

 CREATE TABLE [dbo].[Log]
(
[Id] INT NOT NULL PRIMARY KEY Identity,
[Date] DATETIME NULL,
[Level] VARCHAR(50) NULL,
[Url] VARCHAR(255) NULL,
[UserName] VARCHAR(50) NULL,
[Method] VARCHAR(50) NULL,
[Message] VARCHAR(4000) NULL,
[Exception] VARCHAR(2000) NULL,
)

接下来就是程序中的代码了,在这里,我就不实现那么些类了,就写了一个WebLog静态类。

 using log4net;
using log4net.Core;
using System; namespace UI.Web.Log
{
public static class WebLogger
{
static ILog log = LogManager.GetLogger(typeof(WebLogger)); static void Log(string url, string userName, string method, string message, Level level, Exception exception = null)
{
if (level == null)
level = Level.Debug;
var loggingEvent = new LoggingEvent(typeof(WebLogger), log.Logger.Repository, "WebLogger", level, message, exception);
loggingEvent.Properties["Url"] = url;
loggingEvent.Properties["UserName"] = userName;
loggingEvent.Properties["Method"] = method;
log.Logger.Log(loggingEvent);
} public static void Debug(string url, string userName, string method, string message, Exception exception = null)
{
Log(url, userName, method, message, Level.Debug, exception);
} public static void Info(string url, string userName, string method, string message, Exception exception = null)
{
Log(url, userName, method, message, Level.Info, exception);
} public static void Warn(string url, string userName, string method, string message, Exception exception)
{
Log(url, userName, method, message, Level.Warn, exception);
} public static void Error(string url, string userName, string method, string message, Exception exception)
{
Log(url, userName, method, message, Level.Error, exception);
} public static void Fatal(string url, string userName, string method, string message, Exception exception)
{
Log(url, userName, method, message, Level.Fatal, exception);
}
}
}

在这里,就是将数据添加到loggingEvent对象中。

这样,就可以将自定义的数据填充到数据库中了。

使用log4net写自定义日志的更多相关文章

  1. Log4net 写文件日志与数据库日志

    一.数据库日志表结构 CREATE TABLE [dbo].[WebLog_Msg]( [LogID] [int] IDENTITY(1,1) NOT NULL, [Date] [datetime]  ...

  2. log4net写txt日志

    1.配置: <configSections>节点下添加: <section name="log4net" type="log4net.Config.Lo ...

  3. YII2 自定义日志路径

    YII 提供的日志写入方法: 1.Yii::getLogger()->log($message, $level, $category = 'application') 2.Yii::trace( ...

  4. log4net 自定义日志级别记录多个日志

    程序中原来只记录一个日志,现在我要写一个用户操作日志,需要与原来的日志分开,在config文件中一阵折腾无果(要么写不全,要么写重了,反正没办法完美分离,要么与现存代码没办法完美兼容),差点放弃准备自 ...

  5. 转:NLog 自定义日志内容,写日志到数据库;修改Nlog.config不起作用的原因

    转:http://www.cnblogs.com/tider1999/p/4308440.html NLog的安装请百度,我安装的是3.2.NLog可以向文件,数据库,邮件等写日志,想了解请百度,这里 ...

  6. (二)使用log4net写入数据库自定义日志

    1.配置项目环境 1.1 本文只显示需要修改配置的操作,初次引入log4net环境的请参考上文. 1.2 安装mysql-connector-net.msi环境,下载地址.并手动生成数据库日志信息表. ...

  7. 验证码在后台的编写,并实现点击验证码图片时时发生更新 C# 项目发布到IIS后不能用log4net写日志

    验证码在后台的编写,并实现点击验证码图片时时发生更新   验证码在软件中的地位越来越重要,有效防止这种问题对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试:下面就是实现验证码的基本步骤: ...

  8. 怎么在.NetCore3.0 中使用Log4net 写日志 及读取配置文件的信息

    1:安装Log4Net的 NuGet 包: 我们通常之需要安装这一个包即可,其他的主包会自动被添加进来: insatll-package  Microsoft.Extensions.Logging.L ...

  9. 使用Log4Net完成异常日志处理

    1.在MVC的Modal文件夹建一个异常处理过滤器 public class MyExceptionAttribute:HandleErrorAttribute { public static Que ...

随机推荐

  1. JDBC 异常特殊原因 (数据库只读解决办法)

    JDBC 异常特殊原因   有时候并不是因为程序写的有问题  ,是因为  数据库只读 在sqlserver2005中附加数据库时,附加的数据库会变成只读的,只能进行查询操作. 解决方法: 1 打开Sq ...

  2. ios学习资料(一)

    IT社区: http://www.cnblogs.com/ http://www.csdn.net/ http://www.51cto.com/ http://www.cocoachina.com/ ...

  3. CAS单点登录原理以及debug跟踪登录流程

    CAS 原理和协议 基础模式 基础模式 SSO 访问流程主要有以下步骤: 1. 访问服务: SSO 客户端发送请求访问应用系统提供的服务资源. 2. 定向认证: SSO 客户端会重定向用户请求到 SS ...

  4. [Search Engine] Compression in Inverted Index

    最近在学一些搜索引擎的内容,感觉挺费劲,所以就用博客当做自己的笔记,遇到一些需要整理的部分,就在这里整理一下. 今天的内容是对inverted index进行压缩.核心思想,用我自己的话来总结,就是“ ...

  5. 如何禁止C++默认生成成员函数

    前言: 前几天在一次笔试过程中被问到c++如何设计禁止调用默认构造函数,当时简单的想法是直接将默认构造函数声明为private即可,这样的话对象的确不能直接调用.之后查阅了<Effective ...

  6. FTP两种工作模式:主动模式(Active FTP)和被动模式(Passive FTP)

    在主动模式下,FTP客户端随机开启一个大于1024的端口N向服务器的21号端口发起连接,然后开放N+1号端口进行监听,并向服务器发出PORT N+1命令.服务器接收到命令后,会用其本地的FTP数据端口 ...

  7. 递归:汉诺塔 - 零基础入门学习Python024

    递归:汉诺塔 让编程改变世界 Change the world by program 似乎谈到递归算法就要拿汉诺塔来举例,没办法,因为小甲鱼小时候太笨了,这个游戏老是玩不过关,好不容易在自学编程的时候 ...

  8. rsyslog VS syslog-ng,日志记录哪家强?

    还有慢慢摸索,NG的MYSQL配置,我始终没搞好. RSYSLOG则比较容易. 另外,也可以每个RSYSLOG直接入库,不需要经过LOG SERVER..如果有一个大内网的话... 配合LOGANAL ...

  9. python中的继承原则

     继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子进程继承了父进程的所有公有实例变量和方法.继承实现了代码的重用.重用已经存在的数据和行为,减少代码的重新编写,python在类名 ...

  10. Android图形合成和显示系统---基于高通MSM8k MDP4平台

    介绍了Android SurfaceFlinger层次以下的图形合成和显示系统,主要基于高通MSM8k MDP4x平台. 做为Android Display专题.SurfaceFlinger的详细介绍 ...