diff options
| author | Victoria Plitt <Victoria.Plitt@twine-s.com> | 2020-01-27 16:56:22 +0200 |
|---|---|---|
| committer | Victoria Plitt <Victoria.Plitt@twine-s.com> | 2020-01-27 16:56:22 +0200 |
| commit | 2b9b4c5f44072fd1f06b24e181be0d5d482b463e (patch) | |
| tree | 0bb3fa51682509e79c4ab7625888d3d032c16448 /Software/Visual_Studio/Utilities/Tango.LogViewer.UI | |
| parent | d675e2f2a9b826422a296704cbb99d8fb32c85e0 (diff) | |
| download | Tango-2b9b4c5f44072fd1f06b24e181be0d5d482b463e.tar.gz Tango-2b9b4c5f44072fd1f06b24e181be0d5d482b463e.zip | |
Implement embedded logs in LogViewer
Related Work Items: #2430
Diffstat (limited to 'Software/Visual_Studio/Utilities/Tango.LogViewer.UI')
6 files changed, 293 insertions, 44 deletions
diff --git a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/ApplicationLogViewerParser.cs b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/ApplicationLogViewerParser.cs new file mode 100644 index 000000000..93d856b2e --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/ApplicationLogViewerParser.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; +using System.Text.RegularExpressions; +using System.IO; +using System.Globalization; + +namespace Tango.LogViewer.UI.LogViewerFileParser +{ + public class ApplicationLogViewerParser : ILogViewerParser + { + public ApplicationLogViewerParser() + { + + } + public void Parse(string file, DateTime datetime, ref List<LogItemBase> logItems) + { + String text = File.ReadAllText(file); + var logs = Regex.Split(text, @"(\[\d{2}:\d{2}:\d{2}.\d{2}\])"); + + for (int i = 1; i < logs.Length; i += 2) + { + try + { + DateTime date = DateTime.ParseExact(logs[i].Replace("[", "").Replace("]", ""), "HH:mm:ss.ff", CultureInfo.InvariantCulture); + String rest = logs[i + 1]; + + var entries = Regex.Split(rest, @"\[(.*?)\]"); + + MessageLogItem item = new MessageLogItem(); + item.TimeStamp = new DateTime(datetime.Year, datetime.Month, datetime.Day, date.Hour, date.Minute, date.Second, date.Millisecond); + item.Category = (LogCategory)Enum.Parse(typeof(LogCategory), entries[1]); + item.CallerFile = entries[3]; + item.CallerMethodName = entries[5]; + item.CallerLineNumber = int.Parse(entries[7]); + item.Message = new String(entries[8].Skip(2).ToArray()); + + logItems.Add(item); + } + catch (Exception ex) + { + //LogManager.Default.Log(ex, "Could not parse log line: " + logs[i]); + } + } + } + } +} diff --git a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/EmbeddedLogViewerParser.cs b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/EmbeddedLogViewerParser.cs new file mode 100644 index 000000000..1d0028f10 --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/EmbeddedLogViewerParser.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Tango.Integration.Logging; +using Tango.Logging; + +namespace Tango.LogViewer.UI.LogViewerFileParser +{ + public class EmbeddedLogViewerParser : ILogViewerParser + { + public EmbeddedLogViewerParser() + { + + + } + public void Parse(string file, DateTime datetime, ref List<LogItemBase> logItems) + { + String text = File.ReadAllText(file); + var logs = Regex.Split(text, @"(\[\d{2}:\d{2}:\d{2}.\d{2}\])"); + + for (int i = 1; i < logs.Length; i += 2) + { + try + { + DateTime date = DateTime.ParseExact(logs[i].Replace("[", "").Replace("]", ""), "HH:mm:ss.ff", CultureInfo.InvariantCulture); + String rest = logs[i + 1]; + + var entries = Regex.Split(rest, @"\[(.*?)\]"); + + LogItemBase item = new EmbeddedLogItem(new PMR.Debugging.StartDebugLogResponse() + { + Category = (PMR.Debugging.DebugLogCategory)Enum.Parse(typeof(PMR.Debugging.DebugLogCategory), entries[1]), + FileName = entries[3], + LineNumber = uint.Parse(entries[5]), + ModuleId = uint.Parse(entries[7]), + Filter = uint.Parse(entries[9]), + Message = new String(entries[10].Skip(2).ToArray()) + }); + item.TimeStamp = new DateTime(datetime.Year, datetime.Month, datetime.Day, date.Hour, date.Minute, date.Second, date.Millisecond); + + logItems.Add(item); + } + catch (Exception ex) + { + //LogManager.Default.Log(ex, "Could not parse log line: " + logs[i]); + } + } + } + } +} diff --git a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/ILogViewerParser.cs b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/ILogViewerParser.cs new file mode 100644 index 000000000..a0088a770 --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/LogViewerFileParser/ILogViewerParser.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.LogViewer.UI.LogViewerFileParser +{ + public interface ILogViewerParser + { + void Parse(string file, DateTime datetime, ref List<LogItemBase> logItems); + } +} diff --git a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/MainWindow.xaml index 9c1d6bf0b..d1492c513 100644 --- a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/MainWindow.xaml +++ b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/MainWindow.xaml @@ -12,6 +12,8 @@ Title="Tango Log Viewer" WindowState="Maximized" ShowTitleBar="True" ShowCloseButton="True" DataContext="{StaticResource MainViewVM}"> <Window.Resources> <converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter"></converters:EnumToDescriptionConverter> + <converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"/> </Window.Resources> <Grid> <Grid.RowDefinitions> @@ -77,8 +79,8 @@ </Grid.ColumnDefinitions> <TextBox FontSize="14" Grid.Row="0" FontFamily="Segoe UI">Log</TextBox> <TextBox FontSize="14" Grid.Row="0" Grid.Column="2" Margin="10 0 0 0" FontFamily="Segoe UI">Message</TextBox> - <Border Grid.Column="0" Grid.Row="1" BorderThickness="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="#B9B9B9" Margin="0 0 10 0"> - <DataGrid x:Name="grid" Background="Transparent" RenderOptions.EdgeMode="Aliased" RenderOptions.BitmapScalingMode="LowQuality" MaxWidth="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=ActualWidth}" AutoGenerateColumns="False" SelectionMode="Single" ItemsSource="{Binding LogsViewSource}" SelectedItem="{Binding SelectedLog}" RowHeight="40" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="True" IsReadOnly="True"> + <Border Visibility="{Binding IsEmbeddedLog, Converter={StaticResource BooleanToVisibilityInverseConverter}}" Grid.Column="0" Grid.Row="1" BorderThickness="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="#B9B9B9" Margin="0 0 10 0"> + <DataGrid x:Name="ActionGrid" Background="Transparent" RenderOptions.EdgeMode="Aliased" RenderOptions.BitmapScalingMode="LowQuality" MaxWidth="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=ActualWidth}" AutoGenerateColumns="False" SelectionMode="Single" ItemsSource="{Binding LogsViewSource}" SelectedItem="{Binding SelectedLog}" RowHeight="40" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="True" IsReadOnly="True"> <DataGrid.RowStyle> <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}"> <Setter Property="VerticalContentAlignment" Value="Center"/> @@ -90,6 +92,7 @@ </Trigger> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="#2196f3" /> </Trigger> <Trigger Property="IsFocused" Value="True"> <Setter Property="Background" Value="Transparent"></Setter> @@ -123,9 +126,19 @@ </Setter.Value> </Setter> <Style.Triggers> - <Trigger Property="IsSelected" Value="True"> + <Trigger Property="DataGridCell.IsSelected" Value="True"> <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="#2196f3" /> </Trigger> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsFocused" Value="False" /> + <Condition Property="DataGridCell.IsSelected" Value="True" /> + </MultiTrigger.Conditions> + <MultiTrigger.Setters> + <Setter Property="Foreground" Value="#2196f3" /> + </MultiTrigger.Setters> + </MultiTrigger> </Style.Triggers> </Style> @@ -159,10 +172,10 @@ <Setter Property="Icon" Value="Bug"></Setter> <Setter Property="Foreground" Value="LightGray"></Setter> </DataTrigger> - <DataTrigger Binding="{Binding CallerMethodName}" Value="OnStartup"> + <!--<DataTrigger Binding="{Binding CallerMethodName}" Value="OnStartup"> <Setter Property="Icon" Value="ClockOutline"></Setter> <Setter Property="Foreground" Value="White"></Setter> - </DataTrigger> + </DataTrigger>--> </Style.Triggers> </Style> </fa:ImageAwesome.Style> @@ -188,6 +201,125 @@ </DataGrid.Columns> </DataGrid> </Border> + <Border Visibility="{Binding IsEmbeddedLog, Converter={StaticResource BoolToVisibilityConverter}}" Grid.Column="0" Grid.Row="1" BorderThickness="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="#B9B9B9" Margin="0 0 10 0"> + <DataGrid x:Name="embededGrid" Background="Transparent" RenderOptions.EdgeMode="Aliased" RenderOptions.BitmapScalingMode="LowQuality" MaxWidth="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=ActualWidth}" AutoGenerateColumns="False" SelectionMode="Single" ItemsSource="{Binding LogsViewSource}" SelectedItem="{Binding SelectedLog}" RowHeight="40" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="True" IsReadOnly="True"> + <DataGrid.RowStyle> + <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}"> + <Setter Property="VerticalContentAlignment" Value="Center"/> + <Style.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="#2196f3" /> + <Setter Property="Cursor" Value="Hand"></Setter> + </Trigger> + <Trigger Property="DataGridCell.IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="#2196f3" /> + </Trigger> + <Trigger Property="IsFocused" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + </Trigger> + + <DataTrigger Binding="{Binding LogObject}" Value="External Bridge"> + <Setter Property="Foreground" Value="#28A805" /> + </DataTrigger> + </Style.Triggers> + </Style> + </DataGrid.RowStyle> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"/> + <Setter Property="VerticalAlignment" Value="Center"/> + <Setter Property="TextBlock.VerticalAlignment" Value="Center" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type DataGridCell}"> + <Grid Background="{TemplateBinding Background}"> + <ContentPresenter VerticalAlignment="Bottom" /> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + <Style.Triggers> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="#2196f3" /> + </Trigger> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsFocused" Value="False" /> + <Condition Property="DataGridCell.IsSelected" Value="True" /> + </MultiTrigger.Conditions> + <MultiTrigger.Setters> + <Setter Property="Foreground" Value="#2196f3" /> + </MultiTrigger.Setters> + </MultiTrigger> + </Style.Triggers> + + + </Style> + </DataGrid.CellStyle> + <DataGrid.Columns> + <DataGridTemplateColumn Header="ICON"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <fa:ImageAwesome Width="16" Height="16" Margin="0 0 0 0" VerticalAlignment="Top"> + <fa:ImageAwesome.Style> + <Style TargetType="fa:ImageAwesome"> + <Setter Property="Icon" Value="ExclamationTriangle"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Category}" Value="Info"> + <Setter Property="Icon" Value="Info"></Setter> + <Setter Property="Foreground" Value="LightBlue"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Warning"> + <Setter Property="Icon" Value="ExclamationTriangle"></Setter> + <Setter Property="Foreground" Value="DarkOrange"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Error"> + <Setter Property="Icon" Value="ExclamationCircle"></Setter> + <Setter Property="Foreground" Value="Red"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Critical"> + <Setter Property="Icon" Value="Bell"></Setter> + <Setter Property="Foreground" Value="Red"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Debug"> + <Setter Property="Icon" Value="Bug"></Setter> + <Setter Property="Foreground" Value="LightGray"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding CallerMethodName}" Value="OnStartup"> + <Setter Property="Icon" Value="ClockOutline"></Setter> + <Setter Property="Foreground" Value="White"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </fa:ImageAwesome.Style> + </fa:ImageAwesome> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTextColumn Header="DATE TIME" Binding="{Binding TimeStamp,StringFormat='MM/dd/yyyy HH:mm:ss.ff'}" /> + <DataGridTextColumn Header="FILE" Binding="{Binding DebugLogResponse.FileName}" /> + <DataGridTextColumn Header="LINE" Binding="{Binding DebugLogResponse.LineNumber}" /> + <DataGridTextColumn Header="MODULE" Binding="{Binding DebugLogResponse.ModuleId}" /> + <DataGridTextColumn Header="FILTER" Binding="{Binding DebugLogResponse.Filter}" /> + <DataGridTemplateColumn Header="MESSAGE" Width="1*" > + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Grid VerticalAlignment="Center" Margin="0 5 0 5"> + <Border Height="Auto" BorderThickness="0" > + <TextBlock Text="{Binding MessagePlusRepeated}" TextTrimming="CharacterEllipsis" VerticalAlignment="Center" ></TextBlock> + </Border> + </Grid> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + </DataGrid.Columns> + </DataGrid> + </Border> <Border Margin="10 0 0 0" Grid.Column="2" Grid.Row="1" BorderThickness="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="#B9B9B9"> <TextBox BorderThickness="0" Text="{Binding Message}" IsReadOnly="True" AcceptsReturn="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" TextWrapping="NoWrap"/> </Border> diff --git a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/Tango.LogViewer.UI.csproj b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/Tango.LogViewer.UI.csproj index 6d6eb4e69..76be4e85e 100644 --- a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/Tango.LogViewer.UI.csproj +++ b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/Tango.LogViewer.UI.csproj @@ -73,6 +73,9 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </ApplicationDefinition> + <Compile Include="LogViewerFileParser\ApplicationLogViewerParser.cs" /> + <Compile Include="LogViewerFileParser\EmbeddedLogViewerParser.cs" /> + <Compile Include="LogViewerFileParser\ILogViewerParser.cs" /> <Compile Include="LogViewerManager.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Page Include="MainWindow.xaml"> @@ -124,10 +127,18 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.Integration\Tango.Integration.csproj"> + <Project>{4206AC58-3B57-4699-8835-90BF6DB01A61}</Project> + <Name>Tango.Integration</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.Logging\Tango.Logging.csproj"> <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> <Name>Tango.Logging</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj"> + <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.SharedUI\Tango.SharedUI.csproj"> <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project> <Name>Tango.SharedUI</Name> diff --git a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/ViewModels/MainViewVM.cs index 5f4b77fc3..cb4a8d49e 100644 --- a/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/Utilities/Tango.LogViewer.UI/ViewModels/MainViewVM.cs @@ -13,13 +13,13 @@ using System.ComponentModel; using System.Windows.Data; using System.Diagnostics; using System.IO; -using System.Text.RegularExpressions; -using System.Globalization; +using Tango.LogViewer.UI.LogViewerFileParser; namespace Tango.LogViewer.UI.ViewModels { public class MainViewVM: ViewModel { + private ILogViewerParser _parser; #region Properties public SelectedObjectCollection<LogCategory> SelectedLogCategories { get; set; } @@ -128,7 +128,17 @@ namespace Tango.LogViewer.UI.ViewModels set{ _message = value; RaisePropertyChangedAuto(); } } + private bool _isEmbeddedLog; + public bool IsEmbeddedLog + { + get { return _isEmbeddedLog; } + set { _isEmbeddedLog = value; + RaisePropertyChangedAuto(); + } + } + + #endregion public RelayCommand OpeFileLogCommand { get; set; } @@ -151,7 +161,7 @@ namespace Tango.LogViewer.UI.ViewModels LogCategory.Critical, LogCategory.Debug, }); - + IsEmbeddedLog = false; ClearFilters(); OpeFileLogCommand = new RelayCommand(OpenLogFile); SelectedLogCategories.SynchedSource.CollectionChanged += (_, __) => @@ -224,6 +234,16 @@ namespace Tango.LogViewer.UI.ViewModels List<LogFile> logFiles = new List<LogFile>(); string fileName = Path.GetFileNameWithoutExtension(logFile.File); FileName = fileName; + IsEmbeddedLog = fileName.StartsWith("Embedded"); + if (IsEmbeddedLog) + { + _parser = new EmbeddedLogViewerParser(); + } + else + { + _parser = new ApplicationLogViewerParser(); + } + if (logFile.PartOfSet) { string extension = Path.GetExtension(logFile.File); @@ -239,51 +259,18 @@ namespace Tango.LogViewer.UI.ViewModels CountOfSet = fileEntries.Length; foreach (var file in fileEntries) { - Parse(file, logFile.DateTime, ref logItems); + _parser.Parse(file, logFile.DateTime, ref logItems); } } else { CountOfSet = 1; - Parse(logFile.File, logFile.DateTime, ref logItems); + _parser.Parse(logFile.File, logFile.DateTime, ref logItems); } return logItems; } - - /// <summary> - /// Parses the specified file. Return list of MessageLogItem objects. - /// </summary> - private void Parse(string file, DateTime datetime, ref List<LogItemBase> logItems) - { - String text = File.ReadAllText(file); - var logs = Regex.Split(text, @"(\[\d{2}:\d{2}:\d{2}.\d{2}\])"); - - for (int i = 1; i < logs.Length; i += 2) - { - try - { - DateTime date = DateTime.ParseExact(logs[i].Replace("[", "").Replace("]", ""), "HH:mm:ss.ff", CultureInfo.InvariantCulture); - String rest = logs[i + 1]; - - var entries = Regex.Split(rest, @"\[(.*?)\]"); - - MessageLogItem item = new MessageLogItem(); - item.TimeStamp = new DateTime(datetime.Year, datetime.Month, datetime.Day, date.Hour, date.Minute, date.Second, date.Millisecond); - item.Category = (LogCategory)Enum.Parse(typeof(LogCategory), entries[1]); - item.CallerFile = entries[3]; - item.CallerMethodName = entries[5]; - item.CallerLineNumber = int.Parse(entries[7]); - item.Message = new String(entries[8].Skip(2).ToArray()); - - logItems.Add(item); - } - catch (Exception ex) - { - LogManager.Default.Log(ex, "Could not parse log line: " + logs[i]); - } - } - } + #endregion #region Filtering |
