将Control的日志输出到同一个文件

本文介绍如何通过修改LoadRunner的globals.h文件实现日志记录功能的定制,包括打开、关闭日志文件及在action中记录具体信息的方法。特别强调了使用追加模式('a')而非覆盖模式('w')的重要性。

进入 %LR安装目录%/LoadRunner/include , 修改globals.h文件, 增加:

    char *filename = "d://logfile.txt"; long file_stream;

    file_open(char *file_name){

           if ((file_stream = fopen(file_name, "a")) == NULL ) {

                 lr_error_message("Cannot open %s", file_name); 

                  lr_output_message("open file %s","error"); 

                  return -1;       

           }

     }

    file_close(char *file_name)

   {

         if (fclose(file_stream))

              lr_error_message("Error closing file %s", filename);         

        return 0;

    } 

在vuser_init的头上增加: file_open(filename);

在action中增加: fprintf(file_stream, "%s,BMSSCMBN,MOBILENO/n",ctime(&t1));

在vuser_end的尾上增加: file_close(filename);

 这样即使在Control中启动多个Vuser来执行,所有的日志也会全部输出到d盘下的logfile.txt.

 注意: if ((file_stream = fopen(file_name, "a"))  中第二个参数需要写成"a",如果写成"w"的话,则不会在logfile.txt

中保存所有虚拟用户执行时输出的日志. 仅仅会保存最后一个执行的虚拟用户的日志信息.

<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) ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值