c# log4net 日志输出到 本地文件 textbox listview DEMO

本文介绍log4net的日志记录配置方法,包括直接在app.config中配置及使用独立的log4net.config文件。此外,还展示了如何实现自定义的日志输出,如TextBox和ListView。

网上很多配置log4net的方法,但是排行靠前的 根本就没有说明清除,导致浪费了两个小时来搞清楚如何配置,真是无语,特写此文,给那些刚接触log4net的朋友



1,参考链接

http://blog.sina.com.cn/s/blog_642e41c201014pml.html


此方法是直接将配置文件配置在app.config

 <configSections>
    <!--在配置选项中加入log4net的引用-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net>
    <appender  name="LogFile" type="log4net.Appender.RollingFileAppender,log4net" >
      <param name="File" value="../../logs/log.txt" /> <!--定义用文件来保存日志,生成的文件log.txt放在logs目录中,logs文件夹和应用程序生成的bin文件夹在同一目录下。-->
      <param name="AppendToFile" value="false" />
      <param name="RollingStyle" value="Date" />
      <param name="DatePattern" value="yyyy.MM.dd" />
      <param name="StaticLogFileName" value="true" />
      <layout type="log4net.Layout.PatternLayout,log4net">
        <!--定义输出风格-->
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
        <param name="Header" value="
----------------------header--------------------------
" />
        <param name="Footer" value="
----------------------footer--------------------------
" />
      </layout>
    </appender>
    <appender>
      <!--一个配置文件可以有很多appender,一个appender节就相当于一个日志输出介质或方法。-->
    </appender>
    <logger name="logApp">
      <!--定义logger对象的名字为logApp,以方便在代码中使用logger-->
        <!--配置项可以不配置-->
        <level value="ALL" />
        <!--定义输出的信息等级为所有其中包括Fatal.Error.Warn.Info.Debug-->
      </logger>
      <root>
        <!--定义日志输出的方式和等级-->
        <level value="INFO" />
        <appender-ref ref="LogFile" /><!--选择了文件输出,注意粗体部分对应的名称-->
      </root>
    </log4net>

第二种方式就是单独将配置文件配置在log4net.config中,网上大多数都是这种方法,但是却没有说明关键的一步

参考链接

http://www.cnblogs.com/zfanlong1314/p/3662679.html

1. 新建一个配置文件,log4net.config配置方法同成web.config或app.config一致;
2.如果windows应用程序请把配置文件设为:复制到输出目录 修改方法:在log4net.config上右击-->属性--->把"复制到输出目录" 值改为true;
3.在要用到log4的地方命名空间上边加上:[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
4,vb.net是在AssemblyInfo.vb(ide上看不到,需要在文件夹搜索到)上添加
<Assembly: log4net.Config.XmlConfigurator(ConfigFile:="log/log4net.config", Watch:=True)> 


3,自定义textbox日志输出

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net.Appender;
using System.Windows.Forms;
using log4net.Core;
using log4net.Layout;

namespace log4myself
{
    /// <summary>
    /// Usage:
    ///     log4net.Config.BasicConfigurator.Configure();
    ///     var logPattern = "%date [%thread] %-5level %logger !%M - %message%newline";
    ///     var logAppender = new TextBoxBaseAppender()
    ///     {
    ///         TextBox = this.textBox2,
    ///         Layout = new PatternLayout(logPattern)
    ///     };
    ///     
    ///     ((log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetLoggerRepository()).Root.AddAppender(logAppender);
    /// </summary>
    public class TextBoxBaseAppender : AppenderSkeleton
    {
        public TextBoxBase TextBox { get; set; }

        public TextBoxBaseAppender()
        {
        }

        protected override void Append(LoggingEvent loggingEvent)
        {
            if (this.TextBox == null)
            {
                return;
            }

            if (!this.TextBox.IsHandleCreated)
            {
                return;
            }

            if (this.TextBox.IsDisposed)
            {
                return;
            }

            var patternLayout = this.Layout as PatternLayout;

            var str = string.Empty;
            if (patternLayout != null)
            {
                str = patternLayout.Format(loggingEvent);

                if (loggingEvent.ExceptionObject != null)
                {
                    str += loggingEvent.ExceptionObject.ToString() + Environment.NewLine;
                }
            }
            else
            {
                str = loggingEvent.LoggerName + "-" + loggingEvent.RenderedMessage + Environment.NewLine;
            }

            if (!this.TextBox.InvokeRequired)
            {
                printf(str);
            }
            else
            {
                this.TextBox.BeginInvoke((MethodInvoker)delegate
                {
                    if (!this.TextBox.IsHandleCreated)
                    {
                        return;
                    }

                    if (this.TextBox.IsDisposed)
                    {
                        return;
                    }
                    printf(str);
                });
            }
        }

        private void printf(string str)
        {
            //若是超过10行 则清楚
            if (TextBox.Lines.Length > 50)
            {
                TextBox.Clear();
            }
            this.TextBox.AppendText(str);
        }
    }
}

form中的代码为

            //读取配置文件的信息
            log1 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            
            //设置textbox打印日志
            var logPattern = "%d{yyyy-MM-dd HH:mm:ss} --%-5p-- %m%n";
            var textBox_logAppender = new TextBoxBaseAppender()
            {
                TextBox = this.textBox1,//注释后 就只有文件log
                Layout = new PatternLayout(logPattern)
            };
            //相当于root标签下的   <appender-ref ref="LogFile" />
            log4net.Config.BasicConfigurator.Configure(textBox_logAppender);


listview代码为

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net.Appender;
using System.Windows.Forms;
using log4net.Core;
using log4net.Layout;

namespace log4myself
{
    public class ListViewBaseAppender : AppenderSkeleton
    {
        public ListView listView { get; set; }

        public ListViewBaseAppender()
        {
        }

        protected override void Append(LoggingEvent loggingEvent)
        {
            if (this.listView == null)
            {
                return;
            }

            if (!this.listView.IsHandleCreated)
            {
                return;
            }

            if (this.listView.IsDisposed)
            {
                return;
            }

            var patternLayout = this.Layout as PatternLayout;

            var str = string.Empty;
            if (patternLayout != null)
            {
                str = patternLayout.Format(loggingEvent);

                if (loggingEvent.ExceptionObject != null)
                {
                    str += loggingEvent.ExceptionObject.ToString() + Environment.NewLine;
                }
            }
            else
            {
                str = loggingEvent.LoggerName + "-" + loggingEvent.RenderedMessage + Environment.NewLine;
            }

            if (!this.listView.InvokeRequired)
            {
                printf(str);
            }
            else
            {
                this.listView.BeginInvoke((MethodInvoker)delegate
                {
                    if (!this.listView.IsHandleCreated)
                    {
                        return;
                    }

                    if (this.listView.IsDisposed)
                    {
                        return;
                    }

                    printf(str);
                });
            }
        }

        private void printf(string str)
        {
            if (listView.Items.Count>50)
            {
                listView.Items.Clear();
            }

            ListViewItem item = new ListViewItem();
            item.Text = str.ToString(); 

            listView.BeginUpdate();
            listView.Items.Add(item);
            listView.Items[listView.Items.Count - 1].EnsureVisible();//滚动到最后  
            listView.EndUpdate();  
        }
    }
}


demo 下载 http://download.csdn.net/download/sc6231565/9791817

<think> 我们参考了引用资料中关于log4net同时输出到多个目的地的思路(特别是引用[2]和[3]中同时输出TextBox和文件的示例),以及引用[4]中配置文件的写法。结合之前自定义ListViewAppender的实现,我们可以采用以下方案: 目标:将log4net日志同时输出ListView和文件 方法:配置两个Appender,一个用于文件输出(如RollingFileAppender),另一个是我们自定义的ListViewAppender,并将它们都添加到root中。 具体步骤: 1. 配置文件输出(引用[4]的配置方式) 在App.config中添加RollingFileAppender,用于输出日志到文件。 2. 自定义ListViewAppender(之前已实现) 继续使用之前创建的ListViewAppender,但需要稍微调整以支持多列显示(时间、级别、消息等)。 3. 同时配置两个Appender 在log4net配置中同时引用文件Appender和ListViewAppender。 4. 在窗体初始化时设置ListViewAppender的TargetListView属性 详细实现: 步骤1:修改自定义ListViewAppender以支持多列 ```vbnet Public Class ListViewAppender Inherits AppenderSkeleton Public Property TargetListView As ListView Protected Overrides Sub Append(logEvent As LoggingEvent) If TargetListView Is Nothing Then Return ' 使用PatternLayout转换日志事件为字符串数组(对应多列) Dim message As String = If(Layout Is Nothing, logEvent.RenderedMessage, RenderLoggingEvent(logEvent)) ' 假设我们的PatternLayout格式为:%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %message%newline ' 但实际上我们不需要在这里分割,因为ListView需要多列,所以我们直接传递logEvent对象到UI线程 ' 使用委托更新UI,确保线程安全 If TargetListView.InvokeRequired Then TargetListView.Invoke(New Action(Of LoggingEvent)(AddressOf AddLogItem), logEvent) Else AddLogItem(logEvent) End If End Sub Private Sub AddLogItem(logEvent As LoggingEvent) ' 创建ListViewItem,并添加子项 Dim item As New ListViewItem(logEvent.TimeStamp.ToString("yyyy-MM-dd HH:mm:ss")) item.SubItems.Add(logEvent.Level.ToString()) item.SubItems.Add(logEvent.ThreadName) item.SubItems.Add(logEvent.RenderedMessage) ' 如果需要,还可以添加更多字段 ' 开始更新,避免闪烁 TargetListView.BeginUpdate() Try TargetListView.Items.Add(item) ' 自动滚动到最后 item.EnsureVisible() ' 限制日志数量,防止内存溢出 If TargetListView.Items.Count > 1000 Then TargetListView.Items.RemoveAt(0) End If Finally TargetListView.EndUpdate() End Try End Sub End Class ``` 步骤2:修改App.config配置文件 ```xml <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> </configSections> <log4net> <!-- 定义输出到文件 --> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="logs\log.txt" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="5" /> <maximumFileSize value="10MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %message%newline" /> </layout> </appender> <!-- 定义输出ListView --> <appender name="ListViewAppender" type="YourNamespace.ListViewAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %message%newline" /> </layout> </appender> <root> <level value="ALL" /> <appender-ref ref="RollingFileAppender" /> <appender-ref ref="ListViewAppender" /> </root> </log4net> </configuration> ``` 步骤3:在窗体中初始化log4net并关联ListViewAppender ```vbnet Imports log4net Imports log4net.Repository Public Class LogViewerForm Private Sub LogViewerForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 初始化log4net配置 XmlConfigurator.Configure() ' 获取日志仓库 Dim repo As ILoggerRepository = LogManager.GetRepository() Dim appenders = repo.GetAppenders() ' 查找自定义的ListViewAppender并设置目标ListView For Each appender In appenders If TypeOf appender Is ListViewAppender Then DirectCast(appender, ListViewAppender).TargetListView = ListView1 End If Next End Sub End Class ``` 步骤4:记录日志(使用方式不变) ```vbnet Dim log As ILog = LogManager.GetLogger(GetType(LogViewerForm)) log.Info("测试同时输出到文件和ListView") ``` 注意事项: 1. 配置文件中的`YourNamespace`需要替换为实际的项目命名空间。 2. ListView需要设置View属性为Details,并添加对应的列(时间、级别、线程、消息等)。 这样,日志就会同时输出到文件和ListView中。我们参考了引用[2][3]中同时配置多个Appender的思路,以及引用[4]中文件输出的配置方法。 --- §§相关问题§§ 1. 如何设置log4net同时输出到控制台、文件和ListView? 2. 如何按日志级别过滤ListView显示日志? 3. 如何实现log4net日志文件的分割和归档? </think> ### 将 log4net 日志同时输出ListView 和文件的实现方法 以下是完整的 VB.NET 实现方案,结合自定义 ListView Appender 和文件 Appender: #### 1. 创建自定义 ListView Appender ```vbnet Imports log4net.Appender Imports log4net.Core Public Class ListViewAppender Inherits AppenderSkeleton Public Property TargetListView As ListView Public Property MaxItems As Integer = 500 ' 最大日志条数限制 Protected Overrides Sub Append(logEvent As LoggingEvent) If TargetListView Is Nothing Then Return ' 格式化日志 Dim timestamp = logEvent.TimeStamp.ToString("HH:mm:ss.fff") Dim level = logEvent.Level.ToString() Dim message = logEvent.RenderedMessage ' 线程安全更新 UI If TargetListView.InvokeRequired Then TargetListView.Invoke(New Action(Of String, String, String)(AddressOf AddLogItem), timestamp, level, message) Else AddLogItem(timestamp, level, message) End If End Sub Private Sub AddLogItem(timestamp As String, level As String, message As String) TargetListView.BeginUpdate() ' 提高性能 Try ' 添加日志项 Dim item As New ListViewItem(timestamp) item.SubItems.Add(level) item.SubItems.Add(message) TargetListView.Items.Add(item) ' 自动滚动到最新 item.EnsureVisible() ' 限制最大日志数量 If TargetListView.Items.Count > MaxItems Then TargetListView.Items.RemoveAt(0) End If Finally TargetListView.EndUpdate() End Try End Sub End Class ``` #### 2. 配置 App.config (关键配置) ```xml <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> </configSections> <log4net> <!-- 文件输出 Appender --> <appender name="FileAppender" type="log4net.Appender.RollingFileAppender"> <file value="Logs\log.txt" /> <appendToFile value="true" /> <rollingStyle value="Date" /> <datePattern value="yyyyMMdd" /> <maxSizeRollBackups value="30" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> </layout> </appender> <!-- ListView 输出 Appender --> <appender name="ListViewAppender" type="YourNamespace.ListViewAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date{HH:mm:ss.fff} [%level] %message" /> </layout> </appender> <root> <level value="ALL" /> <!-- 同时引用两个 Appender --> <appender-ref ref="FileAppender" /> <appender-ref ref="ListViewAppender" /> </root> </log4net> </configuration> ``` #### 3. 窗体初始化代码 ```vbnet Imports log4net Imports log4net.Config Public Class MainForm Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 配置 ListView 列 lstLogs.View = View.Details lstLogs.Columns.Add("时间", 120) lstLogs.Columns.Add("级别", 60) lstLogs.Columns.Add("消息", 400) ' 初始化 log4net XmlConfigurator.Configure() ' 关联 ListViewAppender Dim repo = LogManager.GetRepository() Dim appenders = repo.GetAppenders() For Each appender In appenders If TypeOf appender Is ListViewAppender Then DirectCast(appender, ListViewAppender).TargetListView = lstLogs End If Next ' 测试日志 Dim log = LogManager.GetLogger(GetType(MainForm)) log.Info("日志系统初始化完成") log.Warn("示例警告信息") log.Error("示例错误信息") End Sub End Class ``` #### 4. 日志使用示例 ```vbnet ' 在任何模块中记录日志 Dim log = LogManager.GetLogger(GetType(YourClass)) log.Debug("调试信息") log.Info("普通信息") log.Error("错误详情", ex) ' 支持异常记录 ``` ### 关键说明 1. **双 Appender 配置原理** log4net 支持同时配置多个 Appender,通过在 `<root>` 中引用多个 `<appender-ref>` 实现多路输出[^2][^3] 2. **性能优化技巧** - 使用 `BeginUpdate()`/`EndUpdate()` 减少 UI 刷新次数 - 设置 `MaxItems` 限制内存占用 - 异步日志处理(log4net 默认异步) 3. **格式化自定义** 修改 `<conversionPattern>` 可调整日志格式: ```xml <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss} | %-5level | %message" /> ``` 4. **日志级别控制** 在配置文件中调整级别可控制日志显示粒度: ```xml <level value="INFO" /> <!-- 只显示 INFO 及以上级别 --> ``` ### 注意事项 1. **线程安全** 所有 UI 操作必须通过 `Control.Invoke` 确保线程安全 2. **异常处理** 在 `Append()` 方法中添加 try-catch 块防止日志系统崩溃 3. **命名空间修正** `YourNamespace` 需替换为实际项目命名空间 4. **ListView 样式** 建议启用双缓冲减少闪烁: ```vbnet ' 在窗体构造函数中添加 SetStyle(ControlStyles.OptimizedDoubleBuffer, True) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值