Log4Net是个很方便的日志记录工具,起初我是用txt形式记录日志的,这种方式简单、直接,非常方便。

但考虑到将来可能会有大量的日志,或者说还需要做一些日志查询功能,那么txt形式显然就不合适了。

于是就要考虑用数据库来记录日志,鉴于我常用的数据库为MongoDB,而Log4Net默认是不支持MongoDB的,又不想为个日志再装新数据库,便开始寻找解决方法。

所幸我找到了这样一个开源项目—— log4mongo:https://github.com/log4mongo/log4mongo-net

不过它存在两个问题:

  1. 目前支持的MongoDB官方C#驱动版本为1.8.2,而目前的官方驱动已经更新到2.0+了,新版发生了一些变化,旧代码已经不能用了。
  2. 并不是以强类型存入数据库,而是自定义的BsonDocument,这在C#中查询和使用起来非常不方便。

这样只能自己动手改造一下了。

首先我将官方驱动版本升到了2.0.0.828,并且修正了原来跑不通的旧代码。

其次构建了Log、LocationInformation、ExceptionInformation三个实体类,来保存完整的日志信息,其中ExceptionInformation类可以嵌套保存任意多层级的内部异常:

image

image

image

然后我去掉了原先自定义记录的属性、格式的功能,因为我觉得大部分情况应该都是完整记录,没必要单独记录那么几个属性,有关容量或性能的顾虑大可不必,完全可以通过抬高纳入记录的日志等级、存入独立的数据库、以独立的服务器承载日志等方案来解决,而且最关键的是——完整记录查起来很方便、看起来很爽:

image

OK,如果你喜欢的话就下载此程序源码吧:

http://vdisk.weibo.com/s/t2jT2xwKgEC

使用时只要引用此项目,并在配置中添加MongoDBAppender作为appender使用即可,提供一个log4net.config配置文件示例:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
    <!--输出到文件-->
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
        <!--输出到什么目录-->
        <file value="Logs/" />
        <!--是否覆写到文件中-->
        <appendToFile value="true" />
        <!--创建文件的规则-->
        <rollingStyle value="Composite" />
        <datePattern value="yyyy/yyyy_MM/yyyy_MM_dd'.txt'"/>
        <!--切割最多文件数 -1表示不限制产生日志文件数-->
        <maxSizeRollBackups value="-1" />
        <!--单个日志文件最大的大小-->
        <maximumFileSize value="1MB" />
        <!--是否使用静态文件名-->
        <staticLogFileName value="false" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%-5level %date [%-5.5thread] %-40.40c - %message%newline" />
        </layout>
        <!--过滤器-->
        <!--<filter type="log4net.Filter.LevelRangeFilter">
            <LevelMin value="DEBUG"/>
            <LevelMax value="FATAL"/>
        </filter>-->
    </appender>
    <!--输出到MongoDB-->
    <appender name="MongoDBAppender" type="Log4Mongo.MongoDBAppender,Log4Mongo">
        <!--
    MongoDB database connection in the format:
    mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
    See http://www.mongodb.org/display/DOCS/Connections for connectionstring options
    If no database specified, default to "log4net"
    -->
        <connectionString value="mongodb://192.168.199.124/log4net" />
        <!--
    Name of connectionString defined in web/app.config connectionStrings group, the format is the same as connectionString value.
    Optional, If not provided will use connectionString value
    -->
        <!--<connectionStringName value="log4net" />-->
        <!--
    Name of the collection in database
    Optional, Defaults to "logs"
    -->
        <collectionName value="log" />

        <!--取消了针对field的支持,不要再使用field节点了-->
        <!--<field>
            <name value="timestamp" />
            <layout type="log4net.Layout.RawTimeStampLayout" />
        </field>
        <field>
            <name value="level" />
            <layout type="log4net.Layout.PatternLayout" value="%level" />
        </field>
        <field>
            <name value="thread" />
            <layout type="log4net.Layout.PatternLayout" value="%thread" />
        </field>
        <field>
            <name value="logger" />
            <layout type="log4net.Layout.PatternLayout" value="%logger" />
        </field>
        <field>
            <name value="message" />
            <layout type="log4net.Layout.PatternLayout" value="%message" />
        </field>
        <field>
            <name value="mycustomproperty" />
            <layout type="log4net.Layout.RawPropertyLayout">
                <key value="mycustomproperty" />
            </layout>
        </field>-->
    </appender>
    <root>
        <appender-ref ref="RollingFileAppender" />
        <level value="DEBUG" />
    </root>
    <logger name="DefaultLogger">
        <appender-ref ref="MongoDBAppender" />
        <level value="DEBUG" />
    </logger>
</log4net>

上面的配置下,调用DefaultLogger的话会记录日志到服务器192.168.199.124中的log4net数据库的log集合中(同时因为root节点的配置,还会再写入日志到文件中)。

分享或转载本博客站点内的所有原创内容时,都必须遵循此协议:

姓名标示-非商业性-相同方式分享 4.0 国际 (CC BY-NC-SA 4.0)

同时必须附加指向本文页面本博客首页的超链接。

除此之外的转载、分享方式都必须征得本博客作者的授权,否则将会诉诸法律。