Damit mehrere Agenten gleichzeitig Oberflaechen testen koennen, bekommt jedes Projekt eine feste Displaynummer (Vorgabe Richard): :99 PolyTrader, :98 Predictalytics, :97 ClawdDotNet, :96 IBKRTrader, :95 und absteigend fuer kuenftige Projekte. Zwei Prozesse auf demselben Display sehen die Fenster des jeweils anderen - Klicks landen im falschen Programm, Aufnahmen zeigen fremde Anwendungen. Beim Durcharbeiten fielen zwei weitere Kollisionspunkte auf, die zum Parallelbetrieb dazugehoeren und mit aufgenommen wurden: - Screenshot- und Logdateien in /tmp brauchen ein Projektpraefix. /tmp/v_1.png ueberschreiben sich parallel laufende Projekte gegenseitig. - "xvfb-run -a" darf NICHT mehr verwendet werden: Das -a sucht sich selbst ein freies Display und beginnt dabei bei :99 - ausgerechnet PolyTraders Nummer. Stattdessen "xvfb-run -n <nummer>". Die Warnung ist nicht theoretisch: Auf der VM lag ein verwaister X98-Socket, entstanden durch genau so einen "xvfb-run -a"-Aufruf beim smoke-ui-Test, als :99 belegt war. Er blockierte Predictalytics' reservierte Nummer, ohne dass ein Prozess lief. Entfernt, und die Anleitung erklaert jetzt, wie man verwaiste Sockets erkennt (ls /tmp/.X11-unix/ gegen pgrep -a Xvfb lesen) und aufraeumt. Weiter ergaenzt: - pkill nie ohne Displaynummer - "pkill Xvfb" erschlaegt die Sitzungen aller anderen Projekte. - DISPLAY in jedem Skript setzen, sonst landet man auf :0, dem echten Desktop. - Die Skriptvorlage hat jetzt einen Kopf mit PROJEKT/DISP/FENSTER; das ist alles, was sich je Projekt unterscheidet. Praktisch gegengetestet. - Aufraeumabschnitt und Belegungsliste um Displays und Verzeichnisse erweitert. Nebenbei aufgefallen: Das PolyTrader-Publish lag unter ~/pt-test statt ~/polytrader-test und verletzte damit die eigene Verzeichniskonvention. Umbenannt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
93 lines
5.2 KiB
XML
93 lines
5.2 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:PolyTrader.App.Avalonia.ViewModels"
|
|
x:Class="PolyTrader.App.Avalonia.Views.TerminalWindow">
|
|
|
|
<!--
|
|
Terminal- und Log-Ansicht.
|
|
Live-Tab: farbige Log-Zeilen, abschaltbarer Autoscroll, Level-Filter.
|
|
Log-Viewer-Tab: die JSONL-Tagesdateien, filterbar nach Datum, Level, CID und Volltext.
|
|
|
|
Die Live-Ausgabe ist ein virtualisiertes ItemsControl über eine begrenzte Zeilenliste
|
|
statt einer RichTextBox. Damit entfällt das Auto-Clear der WinForms-Fassung, das bei
|
|
Erreichen der RAM-Grenze den gesamten Verlauf verwarf: es werden nur noch die ältesten
|
|
Zeilen verdrängt, der sichtbare Verlauf bleibt erhalten.
|
|
-->
|
|
<DockPanel>
|
|
<TabControl>
|
|
|
|
<TabItem Header="Live">
|
|
<DockPanel>
|
|
<Border Classes="toolbar" DockPanel.Dock="Top">
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Button Name="btnAutoscroll" Content="Stop Autoscroll" />
|
|
<Button Name="btnClear" Content="Terminal leeren" />
|
|
<Button Name="btnCopyAll" Content="Alles kopieren" />
|
|
<TextBlock Text="Level:" VerticalAlignment="Center" />
|
|
<ComboBox Name="cbLogLevel" MinWidth="150" />
|
|
<TextBlock Name="lblLiveStatus" VerticalAlignment="Center" Foreground="{DynamicResource AppMutedTextBrush}" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Border Background="#1E1E1E">
|
|
<ScrollViewer Name="logScroll">
|
|
<ScrollViewer.ContextMenu>
|
|
<ContextMenu>
|
|
<MenuItem Header="Kopieren" Click="OnContextMenuCopyClick" />
|
|
<MenuItem Header="Alles auswählen" Click="OnContextMenuSelectAllClick" />
|
|
</ContextMenu>
|
|
</ScrollViewer.ContextMenu>
|
|
<ItemsControl Name="logLines" Margin="8">
|
|
<ItemsControl.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<VirtualizingStackPanel />
|
|
</ItemsPanelTemplate>
|
|
</ItemsControl.ItemsPanel>
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:LogLine">
|
|
<SelectableTextBlock Text="{Binding Text}"
|
|
Foreground="{Binding Brush}"
|
|
FontFamily="Consolas,Menlo,DejaVu Sans Mono,monospace"
|
|
FontSize="12"
|
|
TextWrapping="Wrap" />
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
</ScrollViewer>
|
|
</Border>
|
|
</DockPanel>
|
|
</TabItem>
|
|
|
|
<TabItem Header="Log Viewer">
|
|
<DockPanel>
|
|
<Border Classes="toolbar" DockPanel.Dock="Top">
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<TextBlock Text="Datum:" VerticalAlignment="Center" />
|
|
<CalendarDatePicker Name="dtViewerDate" MinWidth="150" />
|
|
<TextBlock Text="Level:" VerticalAlignment="Center" />
|
|
<ComboBox Name="cbViewerLevel" MinWidth="130" />
|
|
<TextBlock Text="CID:" VerticalAlignment="Center" />
|
|
<TextBox Name="tbViewerCid" MinWidth="150" />
|
|
<TextBlock Text="Text:" VerticalAlignment="Center" />
|
|
<TextBox Name="tbViewerText" MinWidth="220" />
|
|
<Button Name="btnViewerLoad" Content="Laden" />
|
|
<TextBlock Name="lblViewerStatus" VerticalAlignment="Center" Foreground="{DynamicResource AppMutedTextBrush}" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<DataGrid Name="gridLogs" x:DataType="vm:LogViewerRow">
|
|
<DataGrid.Columns>
|
|
<DataGridTextColumn Header="Zeit" Width="Auto" Binding="{Binding Time}" />
|
|
<DataGridTextColumn Header="Level" Width="Auto" Binding="{Binding Level}" />
|
|
<DataGridTextColumn Header="CID" Width="Auto" Binding="{Binding Cid}" />
|
|
<DataGridTextColumn Header="Nachricht" Width="*" MinWidth="180" Binding="{Binding Message}" />
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
</DockPanel>
|
|
</TabItem>
|
|
|
|
</TabControl>
|
|
</DockPanel>
|
|
|
|
</UserControl>
|