Browse Source

添加实时记录日志的功能

djs 5 months ago
parent
commit
5e34bc7ae2

+ 1 - 0
MeterVision/Config/CfginiItem.cs

@@ -131,6 +131,7 @@ namespace MeterVision.Config
             }
         }
 
+        public string RealLogPath => Path.Combine(Output, "real_log");
 
         private int _singlePageSize;
         public int SinglePageSize

+ 87 - 0
MeterVision/Dlg/ViewRealLogDlg.xaml

@@ -0,0 +1,87 @@
+<Window x:Class="MeterVision.Dlg.ViewRealLogDlg"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:MeterVision.Dlg"
+        mc:Ignorable="d"
+        Background="WhiteSmoke"
+        ShowInTaskbar="False"
+        WindowStartupLocation="CenterOwner"
+        ResizeMode="CanResizeWithGrip"
+        Title="查看实时记录的日志" Height="768" Width="1024">
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="*" />
+            <RowDefinition Height="40" />
+        </Grid.RowDefinitions>
+
+        <Grid Grid.Row="0" Margin="10">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="220" />
+                <ColumnDefinition Width="10" />
+                <ColumnDefinition Width="*" />
+            </Grid.ColumnDefinitions>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="30" />
+                <RowDefinition Height="*" />
+            </Grid.RowDefinitions>
+
+            <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding TotalRecords,StringFormat='已记录的实时日志列表({0})'}" VerticalAlignment="Center" FontSize="14px" />
+
+            <ListView Grid.Row="1" Grid.Column="0" x:Name="lvFileName" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
+                                  Foreground="#000000" FontSize="13px"
+                      SelectedItem="{Binding SelectedFileInfo,Mode=TwoWay}"
+                      SelectionChanged="LvFileName_SelectionChanged">
+                <ListView.ItemContainerStyle>
+                    <Style TargetType="ListViewItem">
+                        <!-- 设置行高 -->
+                        <Setter Property="Height" Value="30"/>
+                        <!-- 设置字体大小 -->
+                        <Setter Property="FontSize" Value="14"/>
+                        <Setter Property="BorderBrush" Value="#D3D3D3"/>
+                        <Setter Property="BorderThickness" Value="0,0,0,1"/>
+                    </Style>
+                </ListView.ItemContainerStyle>
+                <ListView.View>
+                    <GridView>
+                        <GridView.ColumnHeaderContainerStyle>
+                            <Style TargetType="GridViewColumnHeader">
+                                <Setter Property="FontSize" Value="14"/>
+                                <!-- 字体大小 -->
+                                <Setter Property="Height" Value="30"/>
+                                <!-- 高度 --><!--
+                                <Setter Property="Background" Value="LightGray"/>
+                                --><!-- 背景色 --><!--
+                                <Setter Property="Foreground" Value="Black"/>
+                                --><!-- 文字颜色 --><!--
+                                <Setter Property="HorizontalContentAlignment" Value="Center"/>
+                                --><!-- 居中对齐 -->
+                            </Style>
+                        </GridView.ColumnHeaderContainerStyle>
+                        <GridViewColumn Header="文件名称" Width="200"  DisplayMemberBinding="{Binding Name}" />
+                    </GridView>
+                </ListView.View>
+            </ListView>
+
+            <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding SelectedFileInfo.Name,StringFormat='文件名称: {0}'}" VerticalAlignment="Center" FontSize="14px" />
+            
+            <Border Grid.Row="1" Grid.Column ="2">
+                <RichTextBox Name="RichTxtContentBox" Grid.Column="1" IsReadOnly="True" 
+                                 VerticalScrollBarVisibility="Auto" 
+                                 FontSize="14px" BorderThickness="1"
+                                 Margin="0"/>
+            </Border>
+
+        </Grid>
+
+        <Border Grid.Row="1" Background="WhiteSmoke" BorderThickness="0 1 0 0" BorderBrush="#D3D3D3">
+            <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
+                <!--<Button Name="btnOK" Content="确定" HorizontalAlignment="Center" Margin="0 0 20 0"
+                    VerticalAlignment="Center" Width="80" Height="26" Click="BtnOK_Click" />-->
+                <Button Name="btnClose" Content="关闭" HorizontalAlignment="Center" 
+                    VerticalAlignment="Center" Width="80" Height="26" Click="BtnClose_Click" />
+            </StackPanel>
+        </Border>
+    </Grid>
+</Window>

+ 139 - 0
MeterVision/Dlg/ViewRealLogDlg.xaml.cs

@@ -0,0 +1,139 @@
+using MeterVision.Config;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace MeterVision.Dlg
+{
+    /// <summary>
+    /// ViewRealLogDlg.xaml 的交互逻辑
+    /// </summary>
+    public partial class ViewRealLogDlg : Window, INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        protected void OnPropertyChanged(string propertyName)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+
+        public ObservableCollection<FileInfo> FileList { get; set; } = new ObservableCollection<FileInfo>();
+
+        public int TotalRecords => FileList.Count;
+        //public string SelctedFileName { get; set; }
+
+        private FileInfo _selectedFileInfo;
+        public FileInfo SelectedFileInfo
+        {
+            get => _selectedFileInfo;
+            set
+            {
+                if(_selectedFileInfo != value)
+                {
+                    _selectedFileInfo = value;
+                    OnPropertyChanged(nameof(SelectedFileInfo));
+                    ShowRealLog(_selectedFileInfo);
+                }
+            }
+        }
+
+        public ViewRealLogDlg()
+        {
+            InitializeComponent();
+            lvFileName.ItemsSource = FileList;  //绑定到ListView数据源
+            LoadFiles();
+            
+            this.DataContext = this;
+        }
+
+        /// <summary>
+        /// 调用异步加载方法
+        /// </summary>
+        private async void LoadFiles()
+        {
+            List<FileInfo> files = await LoadTxtFilesAsync();
+            FileList.Clear();
+            foreach (var file in files)
+            {
+                FileList.Add(file);
+            }
+            OnPropertyChanged(nameof(TotalRecords));
+        }
+
+        public async Task<List<FileInfo>> LoadTxtFilesAsync()
+        {
+            string directoryPath = CfginiItem.GetConfigItem().RealLogPath;
+            return await Task.Run(() =>
+            {
+                if (!Directory.Exists(directoryPath))
+                    return new List<FileInfo>();
+
+                return new DirectoryInfo(directoryPath)
+                    .GetFiles("*.txt", SearchOption.TopDirectoryOnly) // 获取所有 .txt 文件
+                    .Where(f => f.Length > 0) // 过滤掉大小为 0 的文件
+                    .OrderByDescending(f => f.LastWriteTime) // 按修改时间排序
+                    .Take(100)
+                    .ToList();
+            });
+        }
+
+
+        //显示日志
+        private void ShowRealLog(FileInfo fileInfo)
+        {
+            RichTxtContentBox.Document.Blocks.Clear();
+            RichTxtContentBox.UpdateLayout();
+            RichTxtContentBox.ScrollToHome();
+
+            if (fileInfo == null) return;
+
+            string filePath = fileInfo.FullName;
+            try
+            {
+                if (File.Exists(filePath))
+                {
+                    string content = File.ReadAllText(filePath);
+
+                    // 创建段落并将日志内容添加到段落
+                    Paragraph logParagraph = new Paragraph(new Run(content));
+
+                    // 将日志段落添加到 RichTextBox 的文档中
+                    RichTxtContentBox.Document.Blocks.Add(logParagraph);
+                }
+                else
+                {
+                    MessageBox.Show("日志文件未找到!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+                }
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"加载日志文件时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+        }
+
+        private void LvFileName_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+
+        }
+
+        private void BtnClose_Click(object sender, RoutedEventArgs e)
+        {
+            this.Close();
+        }
+
+        //--------------------------------------------------------------------------------
+    }
+}

+ 29 - 0
MeterVision/FreeAi/FaRun.cs

@@ -23,12 +23,35 @@ namespace MeterVision.FreeAi
         //private FaLog faLog;   //设备运行日志类
 
         public static bool SendAiLogEnable = false;
+        
 
         private StringBuilder mRunLog = new StringBuilder();
 
         public event EventHandler<AiRealLogEventArgs> OnAiRealLogInfo;
 
         private UdpSender udpSender;
+
+        private static RealLogger realLogger;
+
+        //public static bool RecordRealLogEnable = false;     //实时日志记录
+        private static bool _recordRealLogEnable = false;
+        public static  bool RecordRealLogEnable
+        {
+            get => _recordRealLogEnable;
+            set
+            {
+                if(_recordRealLogEnable != value)
+                {
+                    _recordRealLogEnable = value;
+                }
+                if (!_recordRealLogEnable && realLogger != null)
+                {
+                    realLogger.Close();
+                }
+            }
+        }
+
+
         //ai输出的日志回调函数
         private void PrintfCallbackMethod(string message)
         {
@@ -42,6 +65,12 @@ namespace MeterVision.FreeAi
                 udpSender.SendLog(message);
             }
 
+            if (FaRun.RecordRealLogEnable)
+            {
+                realLogger = RealLogger.GetInstance();
+                realLogger.Log(message);
+            }
+
             //faLog.Append_aiLog(message);
             mRunLog.Append(message);
             //发送消息给主程序控件

+ 117 - 0
MeterVision/Helper/RealLogger.cs

@@ -0,0 +1,117 @@
+using MeterVision.Config;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MeterVision.Helper
+{
+    public sealed class RealLogger
+    {
+        private static readonly object _lock = new object();
+        private static RealLogger _instance;
+        private readonly string _logFilePath;
+
+        /// <summary>
+        /// 获取单例实例
+        /// </summary>
+        public static RealLogger GetInstance()
+        {
+            if (_instance == null)
+            {
+                lock (_lock)
+                {
+                    if (_instance == null)
+                    {
+                        _instance = new RealLogger();
+                    }
+                }
+            }
+            return _instance;
+        }
+
+        private RealLogger()
+        {
+            // 日志文件路径
+            //_logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "app.log");
+            _logFilePath = CfginiItem.GetConfigItem().RealLogPath;
+            if (!Directory.Exists(_logFilePath))
+            {
+                Directory.CreateDirectory(_logFilePath);
+            }
+            _logFilePath = Path.Combine(_logFilePath, ThisApp.GetNowTime_yyyyMMddHHmmss() + ".txt");
+
+            // 确保日志文件存在
+            if (!File.Exists(_logFilePath))
+            {
+                File.Create(_logFilePath).Close();
+            }
+        }
+
+        /// <summary>
+        /// 追加日志内容,并写入文件
+        /// </summary>
+        public void Log(string message)
+        {
+            //string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}";
+            string logEntry = message;
+
+            // 控制台输出
+            Console.WriteLine(logEntry);
+
+            // 写入文件(追加模式)
+            lock (_lock)
+            {
+                using (StreamWriter writer = new StreamWriter(_logFilePath, true, Encoding.UTF8))
+                {
+                    writer.WriteLine(logEntry);
+                    writer.Flush();
+                }
+            }
+        }
+
+        /// <summary>
+        /// 追加日志(异步版本)
+        /// </summary>
+        //public async void LogAsync(string message)
+        //{
+        //    string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}";
+
+        //    // 控制台输出
+        //    Console.WriteLine(logEntry);
+
+        //    // 异步写入文件(追加模式)
+        //    lock (_lock)
+        //    {
+        //        using (StreamWriter writer = new StreamWriter(_logFilePath, true, Encoding.UTF8))
+        //        {
+        //            writer.WriteLine(logEntry);
+        //            writer.Flush();
+        //        }
+        //    }
+        //}
+
+        /// <summary>
+        /// 读取日志内容
+        /// </summary>
+        public string ReadLogs()
+        {
+            lock (_lock)
+            {
+                return File.ReadAllText(_logFilePath);
+            }
+        }
+
+        public void Close()
+        {
+            lock (_lock)
+            {
+                _instance = null;
+            }
+        }
+        //--------------------------------------------------
+    }
+    //------------------------------------------------------
+}

+ 15 - 4
MeterVision/MainWindow.xaml

@@ -11,7 +11,7 @@
         AllowDrop="False"
         PreviewMouseDown="Window_PreviewMouseDown"
         PreviewKeyDown="Window_PreviewKeyDown"
-        Title="读表器AI模型测试验证工具" Height="600" Width="1111">
+        Title="读表器AI模型测试验证工具" Height="768" Width="1366">
     <Window.Resources>
     </Window.Resources>
     <Grid>
@@ -163,13 +163,24 @@
 
                 <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                     <TextBlock Width="1" Background="#686868" Margin="5 5 5 5" Visibility="Visible" />
-                    <CheckBox x:Name="chkRealSendAILog" Content="实时发送AI日志" FontSize="14px"
+                    <CheckBox x:Name="chkRealRecordAILog" Content="实时记录AI日志" FontSize="14px"
+                              VerticalAlignment="Center" 
+                              Unchecked="ChkRealRecordAILog_Unchecked"
+                              Checked="ChkRealRecordAILog_Checked"/>
+                    <!-- "#5A89FF"图标用的蓝色 -->
+                    <Button x:Name="btnViewRealLog" Content="查看" Background="Transparent" BorderThickness="0"
+                            Click="BtnViewRealLog_Click"
+                               Foreground="Blue" FontSize="14px" VerticalAlignment="Center" Margin="5 0 0 0" />
+                </StackPanel>
+
+                <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+                    <TextBlock Width="1" Background="#686868" Margin="5 5 5 5" Visibility="Visible" />
+                    <CheckBox x:Name="chkRealSendAILog" Content="UDP实时发送AI日志" FontSize="14px"
                               VerticalAlignment="Center" 
                               Unchecked="ChkRealSendAILog_Unchecked"
                               Checked="ChkRealSendAILog_Checked"/>
                 </StackPanel>
-
-
+               
             </WrapPanel>
         </Border>
 

+ 20 - 0
MeterVision/MainWindow.xaml.cs

@@ -440,6 +440,26 @@ namespace MeterVision
             FaRun.SendAiLogEnable = false;
         }
 
+        private void ChkRealRecordAILog_Checked(object sender, RoutedEventArgs e)
+        {
+            FaRun.RecordRealLogEnable = true;
+        }
+
+        private void ChkRealRecordAILog_Unchecked(object sender, RoutedEventArgs e)
+        {
+            FaRun.RecordRealLogEnable = false;
+        }
+
+        private void BtnViewRealLog_Click(object sender, RoutedEventArgs e)
+        {
+            ViewRealLogDlg dialog = new ViewRealLogDlg()
+            {
+                Owner = this,
+                WindowStartupLocation = WindowStartupLocation.CenterOwner
+            };
+            dialog.ShowDialog();
+        }
+
         //----------------------------------------------------------
     }
 }

+ 8 - 0
MeterVision/MeterVision.csproj

@@ -197,6 +197,9 @@
     <Compile Include="Dlg\RegisterDlg.xaml.cs">
       <DependentUpon>RegisterDlg.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Dlg\ViewRealLogDlg.xaml.cs">
+      <DependentUpon>ViewRealLogDlg.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Dlg\WaitImportDlg.xaml.cs">
       <DependentUpon>WaitImportDlg.xaml</DependentUpon>
     </Compile>
@@ -213,6 +216,7 @@
     <Compile Include="FreeAi\FaRun.cs" />
     <Compile Include="FreeAi\FreeAiLog.cs" />
     <Compile Include="FreeAi\MySafeHandle .cs" />
+    <Compile Include="Helper\RealLogger.cs" />
     <Compile Include="Helper\UdpLoggerSender.cs" />
     <Compile Include="Helper\UdpSender.cs" />
     <Compile Include="ImageViewerWindow.xaml.cs">
@@ -387,6 +391,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Dlg\ViewRealLogDlg.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Dlg\WaitImportDlg.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>