也用 Log4Net 之将日志记录到数据库的后台实现 (二)

  大家下午好,昨天讲了配置,今天我们讲讲后台实现,在完成了后台实现后,我们才能真正意义上的解决把自定义属性字段值录入到数据库中。

  在开写之前我先着重强调一下,“日志”的概念非常广泛,有错误日志、操作日志、访问日志、事件日志等等。我们并不提倡把所有的日志都记录到数据库,因为这样做没有必要。同时如果日志数据表与业务表同在一个数据库的话,频繁的记录日志的操作会影响性能(Log4Net提供了缓存机制,可以在缓存日志数据达到设定值,比如200条时,Log4Net会批量将数据录入到数据库中。即便是这么好的机制,我还是建议大家一定要分清情况,一般错误日志和事件日志我们采用文件形式记录,相应的操作日志我们可以采用数据库记录)。

  “通用日志记录系统” 的重点是通用。能适应各种要求,比如要提供丰富的日志记录形式(如:文件、数据库等等),以及适应不同的业务需求,比如A业务希望记录A1,A2,A3字段,B业务希望记录B1,B2,B3字段。同时还要做到灵活性,能适应业务变更。Log4Net正是这样的一种开源框架,说了这么多,我想表述的是:数据库记录日志的方式并不是唯一的和最好的,大家一定在酌情而定。

  好了,言归正传,我们现在开始讲后台的处理代码:

  (1)、日志对象,就是在存放日志的载体:

public class LogMessage
{
    public int UserID { get; set; }
}

  

  在项目中 LogMessage 充当日志对象,大家一定很奇怪,为什么我的只有一个属性UserID。原因是我在测试自定义属性能不能记录到日志数据库中,所以弄太多的属性也没必要。

  Log4Net在将日志记录到数据库时会提供一些缺省的属性,他们分别是:

[Id] [int] IDENTITY (1, 1) NOT NULL,       

[Date] [datetime]  NULL,        --异常记录时间

[Thread] [varchar] (255)  NULL, --线程ID(数字)

[Level] [varchar] (50)  NULL,   --日志级别(FALAT,ERROR,WARN,INFO,DEBUG)

[Logger] [varchar] (255)  NULL,  --记录的类

[Message] [varchar] (4000) NULL,   --消息

  这些缺省值我们最好在每个日志表里都加上,我测试的时候自行把 Message给删除了,结果怎么也记录不进去日志。所以我建议大家把这几个都带了。字段名字你可以自己改,比如,我就把Date改成了RecordTime,但是在配置文件中,RecordTime字段对应的值依然是@log_date,忘记了的同学回上一篇中去看配置去。

  

  (2)、CustomLayout 类

  CustomLayout 类继承至 log4net.Layout.PatternLayout

  关于Layout大家应该不陌生,“Layout 组件用于向用户显示最后经过格式化的输出信息。输出信息可以以多种格式显示,主要依赖于我们采用的Layout组件类型。可以是线性的或一个XML文件。Layout组件和一个Appender组件一起工作。API帮助手册中有关于不同Layout组件的列表。一个Appender对象,只能对应一个Layout对象。要实现你自己的Layout类,你需要从log4net.Layout.LayoutSkeleton类继承,它实现了ILayout接口。”

  因为我们要使用自定义属性UserID,所以我们要实现自己的Layout类,我们来看代码:

public class CustomLayout : log4net.Layout.PatternLayout
{
   public CustomLayout()
   {
        this.AddConverter("UserID", typeof(UserIDPatternConverter));
   }
}

  typeof(UserIDPatternConverter)语句中的UserIDPatternConverter实现了格式化的输出信息。

internal sealed class UserIDPatternConverter : PatternLayoutConverter
{
    override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        LogMessage logMessage = loggingEvent.MessageObject as LogMessage;

        if (logMessage != null)
             writer.Write(logMessage.UserID);
    }
}

  (3)、对Log4Net的简单封装

   public class LogHelper
    {
        public LogHelper()
        {

        }

        public static string LoggerName = string.Empty;

        private static LogMessage message = null;

        private static ILog _log;

        public static ILog log
        {
            get
            {
                string path = @"C:\Log4Net.config";
                log4net.Config.XmlConfigurator.Configure(new FileInfo(path));

                if (_log == null)
                {
                    //从配置文件中读取Logger对象
                    //WebLogger 里面的配置信息是用来将日志录入到数据库的
                    //做为扩展 做判断来确定日志的记录形式,数据库也好,txt文档也好,控制台程序也好。
                    _log = log4net.LogManager.GetLogger(LoggerName); //log4net.LogManager.GetLogger("WebLogger");
                }
                else
                {
                    if (_log.Logger.Name != LoggerName)
                    {
                        _log = log4net.LogManager.GetLogger(LoggerName);
                    }
                }

                return _log;
            }
        }

        /// <summary>
        /// 调试
        /// </summary>
        public static void debug()
        {
            if (log.IsDebugEnabled)
            {
                log.Debug(message);
            }
        }

        /// <summary>
        /// 错误
        /// </summary>
        public static void error()
        {
            if (log.IsErrorEnabled)
            {
                log.Error(message);
            }
        }

        /// <summary>
        /// 严重错误
        /// </summary>
        public static void fatal()
        {
            if (log.IsFatalEnabled)
            {
                log.Fatal(message);
            }
        }

        /// <summary>
        /// 记录一般日志
        /// </summary>
        public static void info( )
        {
            if (log.IsInfoEnabled)
            {
                //log.Info("Jerry");
                log.Info(message);
            }
        }

        /// <summary>
        /// 记录警告
        /// </summary>
        public static void warn()
        {
            if (log.IsWarnEnabled)
            {
                log.Warn(message);
            }
        }

        /// <summary>
        /// 需要写日志的地方调用此方法
        /// </summary>
        /// <param name="level">自定义级别</param>
        public static void SaveMessage(LogMessage logMessage,int level)
        {
            message = logMessage;

            switch (level)
            {
                case 1:
                    info();
                    break;

                case 2:
                    warn();
                    break;

                case 3:
                    error();
                    break;

                case 4:
                    fatal();
                    break;

                default: break;
            }
        }

    }

  Log4Net根据不同的日志级别提供了不同的记录方法,对了,这里所说的日志级别就是对应的 Level 字段,我们来看一下 Log4Net的日志级别:

  这是我从别的网站上找到的图,用来说明一下级别。好了,到此为此,我们就已经把 Log4Net 底层这好了,注意,你可以把上页的这些类都统一写到一个类库中。这样做的好处是,当其它项目要用到日志记录功能的时候,直接引用你类库的 dll 就可以了,是不是很方便。同时这样做也实现了对Log4Net的简单封装,让其它项目组的人更易使用。

  重点强调一下,记得在这个类库中引用Log4Net.dll。毕竟我们是要用Log4Net来实现日志记录的,别写了半天都没引用,那就要出问题了。

  (4)、好了,让我们在Web展示层中调用他吧! Default.aspx

protected void Page_Load(object sender, EventArgs e)
{
    LogHelper.LoggerName = "WebLogger";
    LogMessage logMessage = new LogMessage();

    logMessage.UserID = 123456;
    LogHelper.SaveMessage(logMessage,1);
}

  因为我们在配置文件中设定了缓存数,<bufferSize value="10"/> 所以你刷新十下,这时候数据就进入到数据库了。不过聪明的做法是,将bufferSize 的value值改为1

  (5)、数据库中的信息

  (6)、对不起,刚才自己看的时候发现没有建表的Sql语句,现在补上。

USE [LogSys]
GO

/****** Object:  Table [dbo].[Log]    Script Date: 08/29/2012 14:56:11 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Log](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [LevelName] [varchar](50) NULL,
    [UserID] [int] NULL,
    [Message] [varchar](4000) NULL,
    [Exception] [varchar](2000) NULL,
    [RecordTime] [varchar](50) NULL,
 CONSTRAINT [PK_Log_1] PRIMARY KEY CLUSTERED
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

  好了,就写到这里,我是百灵,祝大家天天好心情,身体健康。

时间: 2024-08-13 00:37:24

也用 Log4Net 之将日志记录到数据库的后台实现 (二)的相关文章

Log4Net 之将日志记录到数据库的后台实现 (二)

原文:Log4Net 之将日志记录到数据库的后台实现 (二) 大家下午好,昨天讲了配置,今天我们讲讲后台实现,在完成了后台实现后,我们才能真正意义上的解决把自定义属性字段值录入到数据库中. 在开写之前我先着重强调一下,"日志"的概念非常广泛,有错误日志.操作日志.访问日志.事件日志等等.我们并不提倡把所有的日志都记录到数据库,因为这样做没有必要.同时如果日志数据表与业务表同在一个数据库的话,频繁的记录日志的操作会影响性能(Log4Net提供了缓存机制,可以在缓存日志数据达到设定值,比如

也用 Log4Net 之将日志记录到数据库的配置 (一)

也用 Log4Net  之将日志记录到数据库的配置 (一) 前段时间我一直想做一个通用一点的日志记录系统,可以便于不同的业务组调用进行日志记录及分析.本来打算着自己下手写一个,后面发现各业务组可能会需要不同的记录方式,比如利用数据库来记录,用txt的文件形式来记录,当然,这些都是最常用的记录方式.而且不同的业务组都希望有自己的记录数据表,不希望和其他业务组的数据混在一起.于是我先前设想的架构方式也就付之一炬了,因为不够灵活,而且实现难度大.周期长.恰在此时想起了之前做项目的时候用的 Log4Ne

Log4Net 之将日志记录到数据库的配置 (一)

前段时间我一直想做一个通用一点的日志记录系统,可以便于不同的业务组调用进行日志记录及分析.本来打算着自己下手写一个,后面发现各业务组可能会需要不同的记录方式,比如利用数据库来记录,用txt的文件形式来记录,当然,这些都是最常用的记录方式.而且不同的业务组都希望有自己的记录数据表,不希望和其他业务组的数据混在一起.于是我先前设想的架构方式也就付之一炬了,因为不够灵活,而且实现难度大.周期长.恰在此时想起了之前做项目的时候用的 Log4Net 的开源日志框架,于是又从新Google了一下,发现,真棒

log4j 将日志记录到数据库

需要以下jar包: ---log4j commons-loggin-1.1.1.jar log4j-1.2.16.jar ---mysql mysql-connector-java-5.1.15-bin.jar ---log4j.properties配置内容 log4j.rootLogger=INFO,DATABASE #JDBC Appender log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender log4j.appender.

Yii2 将日志记录到数据库中

Yii2默认日志记录到文件中,通过配置log组件来重新将日志保存到数据库中 打开config目录下console.php文件,修改log配置 'log' => [ 'targets' => [ [ 'class' => 'yii\log\DbTarget', 'levels' => ['error', 'warning'], ], ], ], 打开cmd 命令行,进入Yii根目录,开始创建数据库 yii migrate [email protected]/log/migration

使用log4net无法将日志记录插入mysql数据库解决办法

写在前面 今天没事研究了下,将日志文件写入mysql数据库,因为新公司用的数据库也是mysql,项目中需要将日志信息写入数据库,没办法,就研究了下.在使用过程中遇到一个很蛋疼的问题.最后解决了,郁闷了半天.这里做一下记录,以免再犯. 之前写个这方面的文章,关于配置信息,可参考我的这篇文章:Log4Net日志记录两种方式 解决办法 问题就出在我直接将log4net写入数据库的配置文件log4net.config直接复制过来在项目中使用了,当然是修改了连接字符串,提供程序等与mysql相关的配置.配

asp.net Web项目中使用Log4Net进行错误日志记录

使用log4net可以很方便地为应用添加日志功能.应用Log4net,开发者可以很精确地控制日志信息的输出,减少了多余信息,提高了日志记录性能.同时,通过外部配置文件,用户可以不用重新编译程序就能改变应用的日志行为,使得用户可以根据情况灵活地选择要记录的信息. 那么我们如何在Web项目中使用Log4Net呢? 一.基本配置 1.下载Log4Net,地址如下:http://logging.apache.org/log4net/download_log4net.cgi,如下图所示: 2.下载到本地后

redis队列结合log4net实现异常日志记录

查看了一些关于mvc异常日志记录的文章,发现使用redis+log4net的最多,这里简单总结了使用这种方式实现日志记录的过程.直接上步骤: 第一步:配置redis服务器 参考redis的配置和在.net中的使用 第二步:添加自己的异常过滤器(Models文件夹添加一个MyExceptionAttribute类) 1 public class MyExceptionAttribute : HandleErrorAttribute 2 { 3 //----所有用户出现异常,向同一个静态队列添加数据

log4j教程 12、日志记录到数据库

log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 bufferSize 设置缓冲区的大小.默认大小为1 driver 设置驱动程序类为指定的字符串.如果没有指定驱动程序类,默认为sun.jdbc.odbc.JdbcOdbcDriver layout 设置要使用的布局.默认布局是org.apache.log4j.PatternLayout password