<Feat>: Add universal NLog diagnostics and improve AppDiagnostic UI

Cause:

- Live diagnostics required logging from multiple applications without blocking TBF.
- Shared nlog.config files caused configuration conflicts.
- The original viewer lacked configurable colors and practical log controls.
- Inconsistent diagnostic deployment caused log transfer failures and locked shared DLLs during builds.

Solution:

1. Added universal diagnostic transport
   - Added AppDiagnostic.Logging with an NLog target and named-pipe communication.
   - Added background buffering and automatic reconnection.
   - Registered the diagnostic connector programmatically.

2. Separated diagnostic window lifecycle
   - Run AppDiagnostic as an independent process.
   - Activate the existing window on repeated launches.
   - Keep TBF running when the diagnostic window closes.

3. Corrected diagnostic deployment
   - Copy the complete diagnostic output into a dedicated AppDiagnostic subdirectory during build.
   - Overwrite existing deployment files to prevent inconsistent versions.
   - Validate and launch the executable from that subdirectory with an explicit working directory.

4. Improved the log viewer
   - Added configurable substring colors with a palette and live preview.
   - Added text, level and application filters.
   - Added line wrapping, clipboard actions and log export.
   - Added Pause/Resume, Refresh, Clear, auto-scroll and Always on top.
   - Added connection and log counters.
   - Persist color rules between sessions.

5. Removed legacy dependencies
   - Replaced LiveLogCache with structured diagnostic storage.
   - Removed AppDiagnostic dependencies on log4net and SharedComponents.

Validation:

- Confirmed successful log transfer when launching AppDiagnostic from TBF.
This commit is contained in:
2026-09-10 17:45:29 +02:00
parent 1c6f9af2bb
commit 8c77df207a
60 changed files with 2803 additions and 900 deletions
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<LangVersion>7.3</LangVersion>
<RootNamespace>AppDiagnostic.Logging</RootNamespace>
<AssemblyName>AppDiagnostic.Logging</AssemblyName>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<ProjectGuid>{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="5.2.2" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
</Project>
@@ -0,0 +1,41 @@
using NLog;
using NLog.Config;
using NLog.Layouts;
namespace AppDiagnostic.Logging
{
public static class AppDiagnosticConnector
{
private static readonly object syncRoot = new object();
public static void Register()
{
lock (syncRoot)
{
LoggingConfiguration configuration = LogManager.Configuration ?? new LoggingConfiguration();
NLog.Targets.Target existingTarget = configuration.FindTargetByName("appDiagnostic");
if (existingTarget != null)
{
return;
}
var target = new AppDiagnosticTarget
{
Name = "appDiagnostic",
PipeName = DiagnosticProtocol.DefaultPipeName,
QueueLimit = DiagnosticProtocol.DefaultQueueLimit,
ReconnectDelayMilliseconds = DiagnosticProtocol.DefaultReconnectDelayMilliseconds,
ConnectTimeoutMilliseconds = DiagnosticProtocol.DefaultConnectTimeoutMilliseconds,
Layout = new SimpleLayout("${message}")
};
configuration.AddTarget(target.Name, target);
configuration.AddRule(LogLevel.Trace, LogLevel.Fatal, target, "*");
LogManager.Configuration = configuration;
LogManager.ReconfigExistingLoggers();
}
}
}
}
@@ -0,0 +1,233 @@
using NLog;
using NLog.Targets;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
namespace AppDiagnostic.Logging
{
[Target("AppDiagnostic")]
public sealed class AppDiagnosticTarget : TargetWithLayout
{
private readonly object connectionLock = new object();
private readonly string applicationName;
private readonly int processId;
private BlockingCollection<DiagnosticLogEntry> queue;
private CancellationTokenSource cancellation;
private Task senderTask;
private NamedPipeClientStream pipeClient;
public AppDiagnosticTarget()
{
using (Process process = Process.GetCurrentProcess())
{
applicationName = process.ProcessName;
processId = process.Id;
}
PipeName = DiagnosticProtocol.DefaultPipeName;
QueueLimit = DiagnosticProtocol.DefaultQueueLimit;
ReconnectDelayMilliseconds =
DiagnosticProtocol.DefaultReconnectDelayMilliseconds;
ConnectTimeoutMilliseconds =
DiagnosticProtocol.DefaultConnectTimeoutMilliseconds;
}
public string PipeName { get; set; }
public int QueueLimit { get; set; }
public int ReconnectDelayMilliseconds { get; set; }
public int ConnectTimeoutMilliseconds { get; set; }
protected override void InitializeTarget()
{
base.InitializeTarget();
int queueLimit = QueueLimit > 0
? QueueLimit
: DiagnosticProtocol.DefaultQueueLimit;
queue = new BlockingCollection<DiagnosticLogEntry>(queueLimit);
cancellation = new CancellationTokenSource();
senderTask = Task.Factory.StartNew(
ProcessQueue,
cancellation.Token,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}
protected override void Write(LogEventInfo logEvent)
{
if (logEvent == null || queue == null || queue.IsAddingCompleted)
{
return;
}
var entry = new DiagnosticLogEntry
{
TimestampUtc = logEvent.TimeStamp.ToUniversalTime(),
MachineName = Environment.MachineName,
ApplicationName = applicationName,
ProcessId = processId,
LoggerName = logEvent.LoggerName ?? string.Empty,
Level = logEvent.Level?.Name ?? string.Empty,
Message = Layout != null
? Layout.Render(logEvent)
: logEvent.FormattedMessage,
Exception = logEvent.Exception?.ToString() ?? string.Empty
};
try
{
queue.TryAdd(entry);
}
catch (ObjectDisposedException)
{
// A concurrent NLog shutdown may dispose the queue.
}
catch (InvalidOperationException)
{
// A concurrent NLog shutdown may complete the queue.
}
}
protected override void CloseTarget()
{
BlockingCollection<DiagnosticLogEntry> currentQueue = queue;
CancellationTokenSource currentCancellation = cancellation;
if (currentQueue != null)
{
currentQueue.CompleteAdding();
}
if (currentCancellation != null)
{
currentCancellation.Cancel();
}
CloseConnection();
try
{
senderTask?.Wait(2000);
}
catch (AggregateException)
{
// Cancellation during application shutdown is expected.
}
currentQueue?.Dispose();
currentCancellation?.Dispose();
queue = null;
cancellation = null;
senderTask = null;
base.CloseTarget();
}
private void ProcessQueue()
{
CancellationToken token = cancellation.Token;
try
{
foreach (DiagnosticLogEntry entry in
queue.GetConsumingEnumerable(token))
{
SendWhenConnected(entry, token);
}
}
catch (OperationCanceledException)
{
// Target shutdown is expected to cancel the sender.
}
}
private void SendWhenConnected(
DiagnosticLogEntry entry,
CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
EnsureConnected();
DiagnosticMessageSerializer.WriteFramed(pipeClient, entry);
return;
}
catch (Exception exception) when (
exception is IOException ||
exception is TimeoutException ||
exception is InvalidOperationException)
{
CloseConnection();
int delay = ReconnectDelayMilliseconds > 0
? ReconnectDelayMilliseconds
: DiagnosticProtocol.DefaultReconnectDelayMilliseconds;
if (token.WaitHandle.WaitOne(delay))
{
return;
}
}
}
}
private void EnsureConnected()
{
lock (connectionLock)
{
if (pipeClient != null && pipeClient.IsConnected)
{
return;
}
CloseConnectionWithoutLock();
pipeClient = new NamedPipeClientStream(
".",
string.IsNullOrWhiteSpace(PipeName)
? DiagnosticProtocol.DefaultPipeName
: PipeName,
PipeDirection.Out,
PipeOptions.Asynchronous);
int timeout = ConnectTimeoutMilliseconds > 0
? ConnectTimeoutMilliseconds
: DiagnosticProtocol.DefaultConnectTimeoutMilliseconds;
pipeClient.Connect(timeout);
}
}
private void CloseConnection()
{
lock (connectionLock)
{
CloseConnectionWithoutLock();
}
}
private void CloseConnectionWithoutLock()
{
if (pipeClient == null)
{
return;
}
pipeClient.Dispose();
pipeClient = null;
}
}
}
@@ -0,0 +1,33 @@
using System;
using System.Runtime.Serialization;
namespace AppDiagnostic.Logging
{
[DataContract]
public sealed class DiagnosticLogEntry
{
[DataMember(Order = 1)]
public DateTime TimestampUtc { get; set; }
[DataMember(Order = 2)]
public string MachineName { get; set; }
[DataMember(Order = 3)]
public string ApplicationName { get; set; }
[DataMember(Order = 4)]
public int ProcessId { get; set; }
[DataMember(Order = 5)]
public string LoggerName { get; set; }
[DataMember(Order = 6)]
public string Level { get; set; }
[DataMember(Order = 7)]
public string Message { get; set; }
[DataMember(Order = 8)]
public string Exception { get; set; }
}
}
@@ -0,0 +1,113 @@
using System;
using System.IO;
using System.Runtime.Serialization.Json;
namespace AppDiagnostic.Logging
{
public static class DiagnosticMessageSerializer
{
private static readonly DataContractJsonSerializer Serializer =
new DataContractJsonSerializer(typeof(DiagnosticLogEntry));
private static readonly object SerializerLock = new object();
public static byte[] Serialize(DiagnosticLogEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
using (var stream = new MemoryStream())
{
lock (SerializerLock)
{
Serializer.WriteObject(stream, entry);
}
return stream.ToArray();
}
}
public static DiagnosticLogEntry Deserialize(byte[] payload)
{
if (payload == null)
{
throw new ArgumentNullException(nameof(payload));
}
if (payload.Length == 0 ||
payload.Length > DiagnosticProtocol.MaximumMessageSize)
{
throw new InvalidDataException("Invalid diagnostic message size.");
}
using (var stream = new MemoryStream(payload, false))
{
lock (SerializerLock)
{
return (DiagnosticLogEntry)Serializer.ReadObject(stream);
}
}
}
public static void WriteFramed(Stream stream, DiagnosticLogEntry entry)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
byte[] payload = Serialize(entry);
if (payload.Length > DiagnosticProtocol.MaximumMessageSize)
{
throw new InvalidDataException("Diagnostic message is too large.");
}
byte[] length = BitConverter.GetBytes(payload.Length);
stream.Write(length, 0, length.Length);
stream.Write(payload, 0, payload.Length);
stream.Flush();
}
public static DiagnosticLogEntry ReadFramed(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
byte[] lengthBuffer = ReadExactly(stream, sizeof(int));
int payloadLength = BitConverter.ToInt32(lengthBuffer, 0);
if (payloadLength <= 0 ||
payloadLength > DiagnosticProtocol.MaximumMessageSize)
{
throw new InvalidDataException("Invalid diagnostic message size.");
}
return Deserialize(ReadExactly(stream, payloadLength));
}
private static byte[] ReadExactly(Stream stream, int count)
{
byte[] buffer = new byte[count];
int offset = 0;
while (offset < count)
{
int bytesRead = stream.Read(buffer, offset, count - offset);
if (bytesRead == 0)
{
throw new EndOfStreamException();
}
offset += bytesRead;
}
return buffer;
}
}
}
@@ -0,0 +1,11 @@
namespace AppDiagnostic.Logging
{
public static class DiagnosticProtocol
{
public const string DefaultPipeName = "Sensus.AppDiagnostic.LogPipe";
public const int MaximumMessageSize = 1024 * 1024;
public const int DefaultQueueLimit = 10000;
public const int DefaultReconnectDelayMilliseconds = 500;
public const int DefaultConnectTimeoutMilliseconds = 250;
}
}
+37
View File
@@ -0,0 +1,37 @@
# AppDiagnostic.Logging
Reusable NLog target for sending structured diagnostic events from multiple
.NET Framework processes to `AppDiagnostic.exe` through a local named pipe.
## Producer integration
Reference this project from the producer application and add the extension and
target to its NLog configuration:
```xml
<extensions>
<add assembly="AppDiagnostic.Logging" />
</extensions>
<targets>
<target name="appDiagnostic"
xsi:type="AppDiagnostic"
layout="${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
</rules>
```
The target writes to a bounded background queue. Producer threads are not
blocked while the diagnostic viewer is unavailable. Queued messages are sent
after the viewer becomes available; new messages are discarded when the queue
limit is reached.
The receiver can read messages with:
```csharp
DiagnosticLogEntry entry =
DiagnosticMessageSerializer.ReadFramed(namedPipeServerStream);
```
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,65 @@
{
"format": 1,
"restore": {
"C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj": {}
},
"projects": {
"C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"projectName": "AppDiagnostic.Logging",
"projectPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"packagesPath": "C:\\Users\\MFRNIAK\\.nuget\\packages\\",
"outputPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\MFRNIAK\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net472"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.300"
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"dependencies": {
"NLog": {
"target": "Package",
"version": "[5.2.2, )"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.303\\RuntimeIdentifierGraph.json"
}
}
}
}
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\MFRNIAK\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\MFRNIAK\.nuget\packages\" />
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
</ItemGroup>
</Project>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1c6f9af2bb6c7dd588e6f0dab0a2836e409c1f93")]
[assembly: System.Reflection.AssemblyProductAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyTitleAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
328a35425ad6c5261737a98c855c6d7f7d872650a791c2ad21ac4020a96108d0
@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = AppDiagnostic.Logging
build_property.ProjectDir = C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =
@@ -0,0 +1 @@
551ba94934db30a277a1a9cec2dacbe03f8393107e5d0b2436695f9bd62bd569
@@ -0,0 +1,11 @@
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\AppDiagnostic.Logging.pdb
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\NLog.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.csproj.AssemblyReference.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.GeneratedMSBuildEditorConfig.editorconfig
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.AssemblyInfoInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.AssemblyInfo.cs
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.csproj.CoreCompileInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagn.CFEA7AC0.Up2Date
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.pdb
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+086bb55595ffea5be7adb163ca4c6489903ed67c")]
[assembly: System.Reflection.AssemblyProductAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyTitleAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
aad509aee7434678bd40a99ea120dafb7aa8b4f050f239aae2fbef41167a7201
@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = AppDiagnostic.Logging
build_property.ProjectDir = C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =
@@ -0,0 +1 @@
53dfa6175dfb762da95c667a45dfe918166697a8741b3f7c14601d1f62b1886d
@@ -0,0 +1,11 @@
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\AppDiagnostic.Logging.pdb
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\NLog.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.csproj.AssemblyReference.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.GeneratedMSBuildEditorConfig.editorconfig
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.AssemblyInfoInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.AssemblyInfo.cs
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.csproj.CoreCompileInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagn.CFEA7AC0.Up2Date
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.pdb
@@ -0,0 +1,119 @@
{
"version": 4,
"targets": {
"net472": {
"NLog/5.2.2": {
"type": "package",
"frameworkAssemblies": [
"System",
"System.Configuration",
"System.Core",
"System.IO.Compression",
"System.Xml"
],
"compile": {
"lib/net46/NLog.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/net46/NLog.dll": {
"related": ".xml"
}
}
}
}
},
"libraries": {
"NLog/5.2.2": {
"sha512": "r6Q9740g29gTwmTWlsgdIFm0mhNsfNZmbvWKX/Fxmi8X89ZrpUowHM2T2X1lP7RVpND+ef+XnfKL5g6Q1iNGXA==",
"type": "package",
"path": "nlog/5.2.2",
"files": [
".nupkg.metadata",
".signature.p7s",
"N.png",
"lib/net35/NLog.dll",
"lib/net35/NLog.xml",
"lib/net45/NLog.dll",
"lib/net45/NLog.xml",
"lib/net46/NLog.dll",
"lib/net46/NLog.xml",
"lib/netstandard1.3/NLog.dll",
"lib/netstandard1.3/NLog.xml",
"lib/netstandard1.5/NLog.dll",
"lib/netstandard1.5/NLog.xml",
"lib/netstandard2.0/NLog.dll",
"lib/netstandard2.0/NLog.xml",
"nlog.5.2.2.nupkg.sha512",
"nlog.nuspec"
]
}
},
"projectFileDependencyGroups": {
"net472": [
"NLog >= 5.2.2"
]
},
"packageFolders": {
"C:\\Users\\MFRNIAK\\.nuget\\packages\\": {},
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"projectName": "AppDiagnostic.Logging",
"projectPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"packagesPath": "C:\\Users\\MFRNIAK\\.nuget\\packages\\",
"outputPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\MFRNIAK\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net472"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.300"
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"dependencies": {
"NLog": {
"target": "Package",
"version": "[5.2.2, )"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.303\\RuntimeIdentifierGraph.json"
}
}
}
}
@@ -0,0 +1,10 @@
{
"version": 2,
"dgSpecHash": "ezwKOPZAAXU=",
"success": true,
"projectFilePath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"expectedPackageFiles": [
"C:\\Users\\MFRNIAK\\.nuget\\packages\\nlog\\5.2.2\\nlog.5.2.2.nupkg.sha512"
],
"logs": []
}
-13
View File
@@ -3,17 +3,4 @@
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<log4net>
<appender name="LogCacheAppender" type="Namespace.LogCacheAppender, AssemblyName">
<param name="Cache" value="YourCacheInstance" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogCacheAppender" />
</root>
</log4net>
</configuration>
+11 -12
View File
@@ -33,9 +33,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
@@ -51,12 +48,15 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BufferedListView.cs">
<SubType>Component</SubType>
<Compile Include="ColorRuleEditorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="DiagApi.cs" />
<Compile Include="LogAdapter.cs" />
<Compile Include="LogFilter.cs" />
<Compile Include="DiagnosticLogFormatter.cs" />
<Compile Include="DiagnosticLogStore.cs" />
<Compile Include="DiagnosticPipeServer.cs" />
<Compile Include="LogColorizer.cs" />
<Compile Include="LogColorRule.cs" />
<Compile Include="LogColorRuleRepository.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -78,7 +78,6 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -93,9 +92,9 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedComponents\SharedComponents.csproj">
<Project>{8f942729-f454-4c99-ba6c-746962065ae3}</Project>
<Name>SharedComponents</Name>
<ProjectReference Include="..\AppDiagnostic.Logging\AppDiagnostic.Logging.csproj">
<Project>{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}</Project>
<Name>AppDiagnostic.Logging</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
+319
View File
@@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace AppDiagnostic
{
public sealed class ColorRuleEditorForm : Form
{
private readonly List<LogColorRule> rules;
private readonly ListBox ruleList = new ListBox();
private readonly TextBox patternTextBox = new TextBox();
private readonly CheckBox enabledCheckBox = new CheckBox();
private readonly CheckBox boldCheckBox = new CheckBox();
private readonly CheckBox backgroundCheckBox = new CheckBox();
private readonly Button foregroundButton = new Button();
private readonly Button backgroundButton = new Button();
private readonly RichTextBox previewBox = new RichTextBox();
private readonly Font previewBoldFont;
private bool loadingRule;
public ColorRuleEditorForm(IEnumerable<LogColorRule> sourceRules)
{
rules = sourceRules.Select(rule => rule.Clone()).ToList();
InitializeWindow();
previewBoldFont = new Font(previewBox.Font, FontStyle.Bold);
RefreshRuleList(0);
RefreshPreview();
}
public List<LogColorRule> Rules => rules.Select(rule => rule.Clone()).ToList();
protected override void Dispose(bool disposing)
{
if (disposing)
{
previewBoldFont.Dispose();
}
base.Dispose(disposing);
}
private void InitializeWindow()
{
Text = "Log color rules";
Icon = Properties.Resources.TBF_icon;
StartPosition = FormStartPosition.CenterParent;
MinimumSize = new Size(760, 500);
ClientSize = new Size(860, 560);
var root = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 1, RowCount = 3, Padding = new Padding(10) };
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 145F));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42F));
var split = new SplitContainer { Dock = DockStyle.Fill, SplitterDistance = 280 };
split.Panel1.Padding = new Padding(0, 0, 8, 0);
split.Panel2.Padding = new Padding(8, 0, 0, 0);
ruleList.Dock = DockStyle.Fill;
ruleList.IntegralHeight = false;
ruleList.SelectedIndexChanged += RuleList_SelectedIndexChanged;
var listButtons = new FlowLayoutPanel { Dock = DockStyle.Bottom, Height = 36, FlowDirection = FlowDirection.LeftToRight };
listButtons.Controls.Add(CreateButton("Add", AddRule_Click));
listButtons.Controls.Add(CreateButton("Delete", DeleteRule_Click));
listButtons.Controls.Add(CreateButton("Up", MoveUp_Click));
listButtons.Controls.Add(CreateButton("Down", MoveDown_Click));
split.Panel1.Controls.Add(ruleList);
split.Panel1.Controls.Add(listButtons);
var editor = new TableLayoutPanel { Dock = DockStyle.Top, AutoSize = true, ColumnCount = 2, Padding = new Padding(4) };
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
enabledCheckBox.Text = "Rule enabled";
enabledCheckBox.AutoSize = true;
enabledCheckBox.CheckedChanged += EditorValueChanged;
AddEditorRow(editor, "State", enabledCheckBox);
patternTextBox.Dock = DockStyle.Fill;
patternTextBox.TextChanged += EditorValueChanged;
AddEditorRow(editor, "Substring", patternTextBox);
foregroundButton.Text = "Choose text color...";
foregroundButton.AutoSize = true;
foregroundButton.Click += ForegroundButton_Click;
AddEditorRow(editor, "Text color", foregroundButton);
var backgroundPanel = new FlowLayoutPanel { Dock = DockStyle.Fill, AutoSize = true };
backgroundCheckBox.Text = "Use background";
backgroundCheckBox.AutoSize = true;
backgroundCheckBox.CheckedChanged += EditorValueChanged;
backgroundButton.Text = "Choose...";
backgroundButton.AutoSize = true;
backgroundButton.Click += BackgroundButton_Click;
backgroundPanel.Controls.Add(backgroundCheckBox);
backgroundPanel.Controls.Add(backgroundButton);
AddEditorRow(editor, "Background", backgroundPanel);
boldCheckBox.Text = "Bold text";
boldCheckBox.AutoSize = true;
boldCheckBox.CheckedChanged += EditorValueChanged;
AddEditorRow(editor, "Font", boldCheckBox);
var resetButton = CreateButton("Restore default rules", RestoreDefaults_Click);
resetButton.AutoSize = true;
AddEditorRow(editor, string.Empty, resetButton);
split.Panel2.Controls.Add(editor);
previewBox.Dock = DockStyle.Fill;
previewBox.ReadOnly = true;
previewBox.WordWrap = true;
previewBox.Font = new Font("Consolas", 9F);
previewBox.Text = "2026-09-10 14:25:31.042|DEBUG|TBF[14280]|TBF.UI.MainWnd|Device configuration loaded.\n2026-09-10 14:25:31.384|INFO |TBF[14280]|TBF.Rig.StateMachine|Test bench started.\n2026-09-10 14:25:32.018|WARN |TBF[14280]|TBF.Device|Pressure is approaching the limit.\n2026-09-10 14:25:32.611|ERROR|TBF[14280]|TBF.Device|Communication failed.";
var previewGroup = new GroupBox { Text = "Live preview", Dock = DockStyle.Fill, Padding = new Padding(8) };
previewGroup.Controls.Add(previewBox);
var footer = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.RightToLeft, Padding = new Padding(0, 8, 0, 0) };
var okButton = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true };
var cancelButton = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, AutoSize = true };
footer.Controls.Add(okButton);
footer.Controls.Add(cancelButton);
AcceptButton = okButton;
CancelButton = cancelButton;
root.Controls.Add(split, 0, 0);
root.Controls.Add(previewGroup, 0, 1);
root.Controls.Add(footer, 0, 2);
Controls.Add(root);
}
private static Button CreateButton(string text, EventHandler clickHandler)
{
var button = new Button { Text = text, AutoSize = true };
button.Click += clickHandler;
return button;
}
private static void AddEditorRow(TableLayoutPanel panel, string labelText, Control control)
{
int row = panel.RowCount++;
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
var label = new Label { Text = labelText, AutoSize = true, Anchor = AnchorStyles.Left, Margin = new Padding(3, 8, 3, 3) };
control.Margin = new Padding(3, 5, 3, 5);
panel.Controls.Add(label, 0, row);
panel.Controls.Add(control, 1, row);
}
private void RefreshRuleList(int selectedIndex)
{
ruleList.BeginUpdate();
ruleList.Items.Clear();
foreach (LogColorRule rule in rules)
{
ruleList.Items.Add(rule);
}
ruleList.EndUpdate();
if (rules.Count > 0)
{
ruleList.SelectedIndex = Math.Max(0, Math.Min(selectedIndex, rules.Count - 1));
}
}
private void RuleList_SelectedIndexChanged(object sender, EventArgs e)
{
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
loadingRule = true;
enabledCheckBox.Checked = rule.Enabled;
patternTextBox.Text = rule.Pattern;
foregroundButton.BackColor = rule.ForeColor;
backgroundCheckBox.Checked = rule.UseBackColor;
backgroundButton.Enabled = rule.UseBackColor;
backgroundButton.BackColor = rule.UseBackColor ? rule.BackColor : SystemColors.Control;
boldCheckBox.Checked = rule.Bold;
loadingRule = false;
}
private void EditorValueChanged(object sender, EventArgs e)
{
if (loadingRule)
{
return;
}
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
rule.Enabled = enabledCheckBox.Checked;
rule.Pattern = patternTextBox.Text;
rule.UseBackColor = backgroundCheckBox.Checked;
rule.Bold = boldCheckBox.Checked;
backgroundButton.Enabled = rule.UseBackColor;
int index = ruleList.SelectedIndex;
RefreshRuleList(index);
RefreshPreview();
}
private void ForegroundButton_Click(object sender, EventArgs e)
{
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
using (var dialog = new ColorDialog { Color = rule.ForeColor, FullOpen = true })
{
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
rule.ForeColorArgb = dialog.Color.ToArgb();
foregroundButton.BackColor = dialog.Color;
RefreshPreview();
}
}
private void BackgroundButton_Click(object sender, EventArgs e)
{
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
Color initialColor = rule.UseBackColor ? rule.BackColor : SystemColors.Window;
using (var dialog = new ColorDialog { Color = initialColor, FullOpen = true })
{
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
rule.BackColorArgb = dialog.Color.ToArgb();
rule.UseBackColor = true;
backgroundCheckBox.Checked = true;
backgroundButton.BackColor = dialog.Color;
RefreshPreview();
}
}
private void AddRule_Click(object sender, EventArgs e)
{
rules.Add(new LogColorRule { Pattern = "NEW SUBSTRING", ForeColorArgb = Color.MediumPurple.ToArgb() });
RefreshRuleList(rules.Count - 1);
patternTextBox.Focus();
patternTextBox.SelectAll();
}
private void DeleteRule_Click(object sender, EventArgs e)
{
int index = ruleList.SelectedIndex;
if (index < 0)
{
return;
}
rules.RemoveAt(index);
RefreshRuleList(Math.Min(index, rules.Count - 1));
RefreshPreview();
}
private void MoveUp_Click(object sender, EventArgs e)
{
MoveSelectedRule(-1);
}
private void MoveDown_Click(object sender, EventArgs e)
{
MoveSelectedRule(1);
}
private void MoveSelectedRule(int offset)
{
int index = ruleList.SelectedIndex;
int newIndex = index + offset;
if (index < 0 || newIndex < 0 || newIndex >= rules.Count)
{
return;
}
LogColorRule rule = rules[index];
rules.RemoveAt(index);
rules.Insert(newIndex, rule);
RefreshRuleList(newIndex);
RefreshPreview();
}
private void RestoreDefaults_Click(object sender, EventArgs e)
{
rules.Clear();
rules.AddRange(LogColorRule.CreateDefaults());
RefreshRuleList(0);
RefreshPreview();
}
private void RefreshPreview()
{
int selectionStart = previewBox.SelectionStart;
int selectionLength = previewBox.SelectionLength;
string text = previewBox.Text;
LogColorizer.Apply(previewBox, 0, text.Length, text, rules, previewBox.Font, previewBoldFont);
previewBox.Select(Math.Min(selectionStart, previewBox.TextLength), Math.Min(selectionLength, Math.Max(0, previewBox.TextLength - selectionStart)));
}
}
}
+24
View File
@@ -0,0 +1,24 @@
using AppDiagnostic.Logging;
using System;
namespace AppDiagnostic
{
public static class DiagnosticLogFormatter
{
public static string Format(DiagnosticLogEntry entry)
{
if (entry == null)
{
return string.Empty;
}
string level = (entry.Level ?? string.Empty).ToUpperInvariant().PadRight(5);
string application = string.IsNullOrWhiteSpace(entry.ApplicationName) ? "Unknown" : entry.ApplicationName;
string logger = entry.LoggerName ?? string.Empty;
string message = entry.Message ?? string.Empty;
string exception = string.IsNullOrWhiteSpace(entry.Exception) ? string.Empty : Environment.NewLine + entry.Exception;
return $"{entry.TimestampUtc.ToLocalTime():yyyy-MM-dd HH:mm:ss.fff}|{level}|{application}[{entry.ProcessId}]|{logger}|{message}{exception}";
}
}
}
+82
View File
@@ -0,0 +1,82 @@
using AppDiagnostic.Logging;
using System.Collections.Generic;
using System.Linq;
namespace AppDiagnostic
{
public sealed class DiagnosticLogStore
{
private const int MaximumLogCount = 10000;
private static readonly DiagnosticLogStore instance = new DiagnosticLogStore();
private readonly object syncRoot = new object();
private readonly List<DiagnosticLogEntry> entries = new List<DiagnosticLogEntry>();
private long totalReceived;
private long version;
private DiagnosticLogStore()
{
}
public static DiagnosticLogStore Instance => instance;
public long TotalReceived
{
get
{
lock (syncRoot)
{
return totalReceived;
}
}
}
public long Version
{
get
{
lock (syncRoot)
{
return version;
}
}
}
public void Add(DiagnosticLogEntry entry)
{
if (entry == null)
{
return;
}
lock (syncRoot)
{
entries.Add(entry);
totalReceived++;
version++;
int excessCount = entries.Count - MaximumLogCount;
if (excessCount > 0)
{
entries.RemoveRange(0, excessCount);
}
}
}
public List<DiagnosticLogEntry> GetSnapshot()
{
lock (syncRoot)
{
return entries.ToList();
}
}
public void Clear()
{
lock (syncRoot)
{
entries.Clear();
version++;
}
}
}
}
+164
View File
@@ -0,0 +1,164 @@
using AppDiagnostic.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
namespace AppDiagnostic
{
public sealed class DiagnosticPipeServer : IDisposable
{
private readonly Action<DiagnosticLogEntry> messageReceived;
private readonly CancellationTokenSource cancellation = new CancellationTokenSource();
private readonly object syncRoot = new object();
private readonly List<NamedPipeServerStream> connectedClients = new List<NamedPipeServerStream>();
private NamedPipeServerStream waitingServer;
private Task serverTask;
public DiagnosticPipeServer(Action<DiagnosticLogEntry> messageReceived)
{
this.messageReceived = messageReceived ?? throw new ArgumentNullException(nameof(messageReceived));
}
public int ConnectedClientCount
{
get
{
lock (syncRoot)
{
return connectedClients.Count;
}
}
}
public void Start()
{
if (serverTask != null)
{
return;
}
serverTask = Task.Run((Action)AcceptConnections);
}
private void AcceptConnections()
{
while (!cancellation.IsCancellationRequested)
{
NamedPipeServerStream server = null;
try
{
server = new NamedPipeServerStream(DiagnosticProtocol.DefaultPipeName, PipeDirection.In, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
lock (syncRoot)
{
waitingServer = server;
}
server.WaitForConnection();
lock (syncRoot)
{
waitingServer = null;
connectedClients.Add(server);
}
NamedPipeServerStream connectedServer = server;
server = null;
Task.Run(() => ReadClient(connectedServer));
}
catch (ObjectDisposedException)
{
if (!cancellation.IsCancellationRequested)
{
throw;
}
}
catch (IOException)
{
if (!cancellation.IsCancellationRequested)
{
Thread.Sleep(250);
}
}
finally
{
lock (syncRoot)
{
if (ReferenceEquals(waitingServer, server))
{
waitingServer = null;
}
}
server?.Dispose();
}
}
}
private void ReadClient(NamedPipeServerStream client)
{
try
{
while (client.IsConnected && !cancellation.IsCancellationRequested)
{
DiagnosticLogEntry entry = DiagnosticMessageSerializer.ReadFramed(client);
messageReceived(entry);
}
}
catch (EndOfStreamException)
{
// The producer application was closed.
}
catch (IOException)
{
// The producer application disconnected.
}
catch (ObjectDisposedException)
{
// The diagnostic application is shutting down.
}
finally
{
lock (syncRoot)
{
connectedClients.Remove(client);
}
client.Dispose();
}
}
public void Dispose()
{
cancellation.Cancel();
lock (syncRoot)
{
waitingServer?.Dispose();
waitingServer = null;
foreach (NamedPipeServerStream client in connectedClients.ToArray())
{
client.Dispose();
}
connectedClients.Clear();
}
try
{
serverTask?.Wait(2000);
}
catch (AggregateException)
{
// Cancellation during shutdown is expected.
}
cancellation.Dispose();
}
}
}
+65
View File
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Drawing;
namespace AppDiagnostic
{
[Serializable]
public sealed class LogColorRule
{
public bool Enabled { get; set; } = true;
public string Pattern { get; set; } = string.Empty;
public int ForeColorArgb { get; set; } = Color.Black.ToArgb();
public int BackColorArgb { get; set; }
public bool UseBackColor { get; set; }
public bool Bold { get; set; }
public Color ForeColor => Color.FromArgb(ForeColorArgb);
public Color BackColor => Color.FromArgb(BackColorArgb);
public LogColorRule Clone()
{
return new LogColorRule
{
Enabled = Enabled,
Pattern = Pattern,
ForeColorArgb = ForeColorArgb,
BackColorArgb = BackColorArgb,
UseBackColor = UseBackColor,
Bold = Bold
};
}
public override string ToString()
{
string state = Enabled ? string.Empty : "[disabled] ";
return state + Pattern;
}
public static List<LogColorRule> CreateDefaults()
{
return new List<LogColorRule>
{
Create("|TRACE|", Color.DimGray, false),
Create("|DEBUG|", Color.RoyalBlue, false),
Create("|INFO |", Color.ForestGreen, false),
Create("|WARN |", Color.DarkOrange, true),
Create("|ERROR|", Color.Crimson, true),
Create("|FATAL|", Color.White, true, Color.DarkRed)
};
}
private static LogColorRule Create(string pattern, Color foreground, bool bold, Color? background = null)
{
return new LogColorRule
{
Enabled = true,
Pattern = pattern,
ForeColorArgb = foreground.ToArgb(),
BackColorArgb = background?.ToArgb() ?? Color.Empty.ToArgb(),
UseBackColor = background.HasValue,
Bold = bold
};
}
}
}
+46
View File
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace AppDiagnostic
{
public static class LogColorRuleRepository
{
private static readonly string settingsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Sensus", "AppDiagnostic");
private static readonly string settingsPath = Path.Combine(settingsFolder, "color-rules.xml");
public static List<LogColorRule> Load()
{
try
{
if (!File.Exists(settingsPath))
{
return LogColorRule.CreateDefaults();
}
var serializer = new XmlSerializer(typeof(List<LogColorRule>));
using (FileStream stream = File.OpenRead(settingsPath))
{
var rules = serializer.Deserialize(stream) as List<LogColorRule>;
return rules == null || rules.Count == 0 ? LogColorRule.CreateDefaults() : rules;
}
}
catch
{
return LogColorRule.CreateDefaults();
}
}
public static void Save(IEnumerable<LogColorRule> rules)
{
Directory.CreateDirectory(settingsFolder);
var serializer = new XmlSerializer(typeof(List<LogColorRule>));
using (FileStream stream = File.Create(settingsPath))
{
serializer.Serialize(stream, new List<LogColorRule>(rules));
}
}
}
}
+47
View File
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace AppDiagnostic
{
public static class LogColorizer
{
public static void Apply(RichTextBox target, int startIndex, int length, string text, IEnumerable<LogColorRule> rules, Font regularFont, Font boldFont)
{
if (target == null || length <= 0)
{
return;
}
target.Select(startIndex, length);
target.SelectionColor = target.ForeColor;
target.SelectionBackColor = target.BackColor;
target.SelectionFont = regularFont;
foreach (LogColorRule rule in rules)
{
if (rule == null || !rule.Enabled || string.IsNullOrEmpty(rule.Pattern))
{
continue;
}
int searchIndex = 0;
while (searchIndex < text.Length)
{
int matchIndex = text.IndexOf(rule.Pattern, searchIndex, StringComparison.OrdinalIgnoreCase);
if (matchIndex < 0)
{
break;
}
target.Select(startIndex + matchIndex, rule.Pattern.Length);
target.SelectionColor = rule.ForeColor;
target.SelectionBackColor = rule.UseBackColor ? rule.BackColor : target.BackColor;
target.SelectionFont = rule.Bold ? boldFont : regularFont;
searchIndex = matchIndex + rule.Pattern.Length;
}
}
}
}
}
+245 -214
View File
@@ -1,278 +1,309 @@
using System.Windows.Forms;
namespace AppDiagnostic
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.ToolStrip mainToolStrip;
private System.Windows.Forms.ToolStripButton pauseButton;
private System.Windows.Forms.ToolStripButton refreshButton;
private System.Windows.Forms.ToolStripButton clearButton;
private System.Windows.Forms.ToolStripButton saveButton;
private System.Windows.Forms.ToolStripButton copyButton;
private System.Windows.Forms.ToolStripButton copyAllButton;
private System.Windows.Forms.ToolStripButton wrapButton;
private System.Windows.Forms.ToolStripButton autoScrollButton;
private System.Windows.Forms.ToolStripButton alwaysOnTopButton;
private System.Windows.Forms.ToolStripButton colorRulesButton;
private System.Windows.Forms.ToolStripButton closeButton;
private System.Windows.Forms.TableLayoutPanel filterPanel;
private System.Windows.Forms.Label filterLabel;
private System.Windows.Forms.TextBox filterTextBox;
private System.Windows.Forms.Label levelLabel;
private System.Windows.Forms.ComboBox levelComboBox;
private System.Windows.Forms.Label applicationLabel;
private System.Windows.Forms.ComboBox applicationComboBox;
private System.Windows.Forms.Button applyFilterButton;
private System.Windows.Forms.Button clearFilterButton;
private System.Windows.Forms.RichTextBox logView;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel receiverStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel statusSpacer;
private System.Windows.Forms.ToolStripStatusLabel countStatusLabel;
private System.Windows.Forms.ContextMenuStrip logContextMenu;
private System.Windows.Forms.ToolStripMenuItem copySelectionMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyLineMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyAllMenuItem;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
if (disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
//private BufferedListView memoListView;
private System.Windows.Forms.ColumnHeader columnHeaderTime;
private System.Windows.Forms.ColumnHeader columnHeaderMessage;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.columnHeaderTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderMessage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.panel1 = new System.Windows.Forms.Panel();
this.refreshMemoButton = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.filterManagementPanel = new System.Windows.Forms.Panel();
this.button5 = new System.Windows.Forms.Button();
this.filterButton = new System.Windows.Forms.Button();
this.components = new System.ComponentModel.Container();
this.mainToolStrip = new System.Windows.Forms.ToolStrip();
this.pauseButton = new System.Windows.Forms.ToolStripButton();
this.refreshButton = new System.Windows.Forms.ToolStripButton();
this.clearButton = new System.Windows.Forms.ToolStripButton();
this.saveButton = new System.Windows.Forms.ToolStripButton();
this.copyButton = new System.Windows.Forms.ToolStripButton();
this.copyAllButton = new System.Windows.Forms.ToolStripButton();
this.wrapButton = new System.Windows.Forms.ToolStripButton();
this.autoScrollButton = new System.Windows.Forms.ToolStripButton();
this.alwaysOnTopButton = new System.Windows.Forms.ToolStripButton();
this.colorRulesButton = new System.Windows.Forms.ToolStripButton();
this.closeButton = new System.Windows.Forms.ToolStripButton();
this.filterPanel = new System.Windows.Forms.TableLayoutPanel();
this.filterLabel = new System.Windows.Forms.Label();
this.filterTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.wndControlPanel = new System.Windows.Forms.Panel();
this.button2 = new System.Windows.Forms.Button();
this.flowControlsPanel = new System.Windows.Forms.Panel();
this.runButton = new System.Windows.Forms.Button();
this.stopButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.memoListView = new BufferedListView();
this.panel1.SuspendLayout();
this.filterManagementPanel.SuspendLayout();
this.wndControlPanel.SuspendLayout();
this.flowControlsPanel.SuspendLayout();
this.levelLabel = new System.Windows.Forms.Label();
this.levelComboBox = new System.Windows.Forms.ComboBox();
this.applicationLabel = new System.Windows.Forms.Label();
this.applicationComboBox = new System.Windows.Forms.ComboBox();
this.applyFilterButton = new System.Windows.Forms.Button();
this.clearFilterButton = new System.Windows.Forms.Button();
this.logContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.copySelectionMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyLineMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyAllMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.logView = new System.Windows.Forms.RichTextBox();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.receiverStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.statusSpacer = new System.Windows.Forms.ToolStripStatusLabel();
this.countStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.mainToolStrip.SuspendLayout();
this.filterPanel.SuspendLayout();
this.logContextMenu.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// columnHeaderTime
// mainToolStrip
//
this.columnHeaderTime.Text = "Time";
this.columnHeaderTime.Width = 150;
this.mainToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.mainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.pauseButton,
this.refreshButton,
this.clearButton,
this.saveButton,
new System.Windows.Forms.ToolStripSeparator(),
this.copyButton,
this.copyAllButton,
new System.Windows.Forms.ToolStripSeparator(),
this.wrapButton,
this.autoScrollButton,
this.alwaysOnTopButton,
this.colorRulesButton,
this.closeButton});
this.mainToolStrip.Location = new System.Drawing.Point(0, 0);
this.mainToolStrip.Name = "mainToolStrip";
this.mainToolStrip.Padding = new System.Windows.Forms.Padding(6, 3, 6, 3);
this.mainToolStrip.Size = new System.Drawing.Size(1184, 31);
this.mainToolStrip.TabIndex = 0;
//
// columnHeaderMessage
// pauseButton
//
this.columnHeaderMessage.Text = "Message";
this.columnHeaderMessage.Width = 350;
this.pauseButton.CheckOnClick = true;
this.pauseButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.pauseButton.Text = "Pause";
this.pauseButton.ToolTipText = "Pause screen updates while continuing to receive logs";
this.pauseButton.Click += new System.EventHandler(this.pauseButton_Click);
//
// panel1
// refreshButton
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.panel1.Controls.Add(this.refreshMemoButton);
this.panel1.Controls.Add(this.button6);
this.panel1.Controls.Add(this.button7);
this.panel1.Location = new System.Drawing.Point(189, 356);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(283, 26);
this.panel1.TabIndex = 16;
this.refreshButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.refreshButton.Text = "Refresh";
this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click);
//
// refreshMemoButton
// clearButton
//
this.refreshMemoButton.Location = new System.Drawing.Point(108, 0);
this.refreshMemoButton.Name = "refreshMemoButton";
this.refreshMemoButton.Size = new System.Drawing.Size(84, 26);
this.refreshMemoButton.TabIndex = 17;
this.refreshMemoButton.Text = "Refresh memo";
this.refreshMemoButton.UseVisualStyleBackColor = true;
this.refreshMemoButton.Click += new System.EventHandler(this.refreshMemoButton_Click);
this.clearButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.clearButton.Text = "Clear";
this.clearButton.Click += new System.EventHandler(this.clearButton_Click);
//
// button6
// saveButton
//
this.button6.Location = new System.Drawing.Point(0, 0);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(102, 26);
this.button6.TabIndex = 4;
this.button6.Text = "Clean diag cache";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.button6_Click);
this.saveButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.saveButton.Text = "Save...";
this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
//
// button7
// copyButton
//
this.button7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.button7.Location = new System.Drawing.Point(198, 0);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(72, 26);
this.button7.TabIndex = 5;
this.button7.Text = "Save logs";
this.button7.UseVisualStyleBackColor = true;
this.button7.Click += new System.EventHandler(this.button7_Click);
this.copyButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.copyButton.Text = "Copy";
this.copyButton.ToolTipText = "Copy selected text or the current log line";
this.copyButton.Click += new System.EventHandler(this.copyButton_Click);
//
// filterManagementPanel
// copyAllButton
//
this.filterManagementPanel.Controls.Add(this.button5);
this.filterManagementPanel.Controls.Add(this.filterButton);
this.filterManagementPanel.Controls.Add(this.filterTextBox);
this.filterManagementPanel.Controls.Add(this.label2);
this.filterManagementPanel.Location = new System.Drawing.Point(127, 6);
this.filterManagementPanel.Name = "filterManagementPanel";
this.filterManagementPanel.Size = new System.Drawing.Size(393, 26);
this.filterManagementPanel.TabIndex = 15;
this.copyAllButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.copyAllButton.Text = "Copy all";
this.copyAllButton.Click += new System.EventHandler(this.copyAllButton_Click);
//
// button5
// wrapButton
//
this.button5.Enabled = false;
this.button5.Location = new System.Drawing.Point(294, 4);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(81, 20);
this.button5.TabIndex = 11;
this.button5.Text = "Add new filter";
this.button5.UseVisualStyleBackColor = true;
this.wrapButton.Checked = true;
this.wrapButton.CheckOnClick = true;
this.wrapButton.CheckState = System.Windows.Forms.CheckState.Checked;
this.wrapButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.wrapButton.Text = "Wrap lines";
this.wrapButton.Click += new System.EventHandler(this.wrapButton_Click);
//
// filterButton
// autoScrollButton
//
this.filterButton.Location = new System.Drawing.Point(225, 4);
this.filterButton.Name = "filterButton";
this.filterButton.Size = new System.Drawing.Size(64, 20);
this.filterButton.TabIndex = 10;
this.filterButton.Text = "Set filter";
this.filterButton.UseVisualStyleBackColor = true;
this.filterButton.Click += new System.EventHandler(this.filterButton_Click_1);
this.autoScrollButton.Checked = true;
this.autoScrollButton.CheckOnClick = true;
this.autoScrollButton.CheckState = System.Windows.Forms.CheckState.Checked;
this.autoScrollButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.autoScrollButton.Text = "Auto-scroll";
//
// filterTextBox
// alwaysOnTopButton
//
this.filterTextBox.Location = new System.Drawing.Point(33, 4);
this.filterTextBox.Name = "filterTextBox";
this.filterTextBox.Size = new System.Drawing.Size(187, 20);
this.filterTextBox.TabIndex = 7;
this.alwaysOnTopButton.CheckOnClick = true;
this.alwaysOnTopButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.alwaysOnTopButton.Text = "Always on top";
this.alwaysOnTopButton.Click += new System.EventHandler(this.alwaysOnTopButton_Click);
//
// label2
// colorRulesButton
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Filter";
this.colorRulesButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.colorRulesButton.Text = "Color rules...";
this.colorRulesButton.Click += new System.EventHandler(this.colorRulesButton_Click);
//
// wndControlPanel
// closeButton
//
this.wndControlPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.wndControlPanel.Controls.Add(this.button2);
this.wndControlPanel.Location = new System.Drawing.Point(831, 356);
this.wndControlPanel.Name = "wndControlPanel";
this.wndControlPanel.Size = new System.Drawing.Size(70, 26);
this.wndControlPanel.TabIndex = 14;
this.closeButton.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.closeButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.closeButton.Text = "Close";
this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
//
// button2
// filterPanel
//
this.button2.Location = new System.Drawing.Point(3, 0);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(64, 26);
this.button2.TabIndex = 2;
this.button2.Text = "Close";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
this.filterPanel.ColumnCount = 8;
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 42F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 42F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 105F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 72F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 180F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F));
this.filterPanel.Controls.Add(this.filterLabel, 0, 0);
this.filterPanel.Controls.Add(this.filterTextBox, 1, 0);
this.filterPanel.Controls.Add(this.levelLabel, 2, 0);
this.filterPanel.Controls.Add(this.levelComboBox, 3, 0);
this.filterPanel.Controls.Add(this.applicationLabel, 4, 0);
this.filterPanel.Controls.Add(this.applicationComboBox, 5, 0);
this.filterPanel.Controls.Add(this.applyFilterButton, 6, 0);
this.filterPanel.Controls.Add(this.clearFilterButton, 7, 0);
this.filterPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.filterPanel.Location = new System.Drawing.Point(0, 31);
this.filterPanel.Name = "filterPanel";
this.filterPanel.Padding = new System.Windows.Forms.Padding(6, 5, 6, 5);
this.filterPanel.RowCount = 1;
this.filterPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.filterPanel.Size = new System.Drawing.Size(1184, 38);
this.filterPanel.TabIndex = 1;
//
// flowControlsPanel
// filter controls
//
this.flowControlsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.flowControlsPanel.Controls.Add(this.runButton);
this.flowControlsPanel.Controls.Add(this.stopButton);
this.flowControlsPanel.Location = new System.Drawing.Point(12, 356);
this.flowControlsPanel.Name = "flowControlsPanel";
this.flowControlsPanel.Size = new System.Drawing.Size(133, 26);
this.flowControlsPanel.TabIndex = 13;
this.filterLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.filterLabel.AutoSize = true;
this.filterLabel.Text = "Filter";
this.filterTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.filterTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.filterTextBox_KeyDown);
this.levelLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.levelLabel.AutoSize = true;
this.levelLabel.Text = "Level";
this.levelComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.levelComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.levelComboBox.SelectedIndexChanged += new System.EventHandler(this.filterValueChanged);
this.applicationLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.applicationLabel.AutoSize = true;
this.applicationLabel.Text = "Application";
this.applicationComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.applicationComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.applicationComboBox.SelectedIndexChanged += new System.EventHandler(this.filterValueChanged);
this.applyFilterButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.applyFilterButton.Text = "Apply";
this.applyFilterButton.Click += new System.EventHandler(this.applyFilterButton_Click);
this.clearFilterButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.clearFilterButton.Text = "Reset";
this.clearFilterButton.Click += new System.EventHandler(this.clearFilterButton_Click);
//
// runButton
// logContextMenu
//
this.runButton.Enabled = false;
this.runButton.Location = new System.Drawing.Point(0, 0);
this.runButton.Name = "runButton";
this.runButton.Size = new System.Drawing.Size(64, 26);
this.runButton.TabIndex = 4;
this.runButton.Text = "Run";
this.runButton.UseVisualStyleBackColor = true;
this.runButton.Click += new System.EventHandler(this.runButton_Click);
this.logContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.copySelectionMenuItem,
this.copyLineMenuItem,
this.copyAllMenuItem});
this.copySelectionMenuItem.Text = "Copy selection";
this.copySelectionMenuItem.Click += new System.EventHandler(this.copySelectionMenuItem_Click);
this.copyLineMenuItem.Text = "Copy current line";
this.copyLineMenuItem.Click += new System.EventHandler(this.copyLineMenuItem_Click);
this.copyAllMenuItem.Text = "Copy all visible logs";
this.copyAllMenuItem.Click += new System.EventHandler(this.copyAllButton_Click);
//
// stopButton
// logView
//
this.stopButton.Location = new System.Drawing.Point(69, 0);
this.stopButton.Name = "stopButton";
this.stopButton.Size = new System.Drawing.Size(64, 26);
this.stopButton.TabIndex = 5;
this.stopButton.Text = "Stop";
this.stopButton.UseVisualStyleBackColor = true;
this.stopButton.Click += new System.EventHandler(this.stopButton_Click);
this.logView.BackColor = System.Drawing.SystemColors.Window;
this.logView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.logView.ContextMenuStrip = this.logContextMenu;
this.logView.DetectUrls = false;
this.logView.Dock = System.Windows.Forms.DockStyle.Fill;
this.logView.Font = new System.Drawing.Font("Consolas", 9F);
this.logView.HideSelection = false;
this.logView.Location = new System.Drawing.Point(0, 69);
this.logView.Name = "logView";
this.logView.ReadOnly = true;
this.logView.Size = new System.Drawing.Size(1184, 554);
this.logView.TabIndex = 2;
this.logView.Text = "";
this.logView.WordWrap = true;
//
// label1
// statusStrip
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 13);
this.label1.TabIndex = 12;
this.label1.Text = "Flow of events";
//
// memoListView
//
this.memoListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.memoListView.FullRowSelect = true;
this.memoListView.GridLines = true;
this.memoListView.HideSelection = false;
this.memoListView.Location = new System.Drawing.Point(12, 38);
this.memoListView.Name = "memoListView";
this.memoListView.Size = new System.Drawing.Size(889, 312);
this.memoListView.TabIndex = 0;
this.memoListView.UseCompatibleStateImageBehavior = false;
this.memoListView.View = System.Windows.Forms.View.Details;
this.memoListView.DoubleClick += new System.EventHandler(this.MemoListView_DoubleClick);
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.receiverStatusLabel,
this.statusSpacer,
this.countStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 623);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(1184, 22);
this.statusStrip.TabIndex = 3;
this.receiverStatusLabel.Text = "Listening";
this.statusSpacer.Spring = true;
this.countStatusLabel.Text = "Received: 0 | Visible: 0";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(913, 388);
this.Controls.Add(this.memoListView);
this.Controls.Add(this.panel1);
this.Controls.Add(this.filterManagementPanel);
this.Controls.Add(this.wndControlPanel);
this.Controls.Add(this.flowControlsPanel);
this.Controls.Add(this.label1);
this.ClientSize = new System.Drawing.Size(1184, 645);
this.Controls.Add(this.logView);
this.Controls.Add(this.filterPanel);
this.Controls.Add(this.mainToolStrip);
this.Controls.Add(this.statusStrip);
this.KeyPreview = true;
this.MinimumSize = new System.Drawing.Size(860, 480);
this.Name = "MainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Application live diagnostic";
this.panel1.ResumeLayout(false);
this.filterManagementPanel.ResumeLayout(false);
this.filterManagementPanel.PerformLayout();
this.wndControlPanel.ResumeLayout(false);
this.flowControlsPanel.ResumeLayout(false);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown);
this.mainToolStrip.ResumeLayout(false);
this.mainToolStrip.PerformLayout();
this.filterPanel.ResumeLayout(false);
this.filterPanel.PerformLayout();
this.logContextMenu.ResumeLayout(false);
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.Button button7;
private System.Windows.Forms.Panel filterManagementPanel;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button filterButton;
private System.Windows.Forms.TextBox filterTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel wndControlPanel;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Panel flowControlsPanel;
private System.Windows.Forms.Button runButton;
private System.Windows.Forms.Button stopButton;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button refreshMemoButton;
private BufferedListView memoListView;
}
}
+390 -212
View File
@@ -1,267 +1,445 @@
using log4net.Config;
using log4net;
using AppDiagnostic.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using log4net.Appender;
using SharedComponents;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.IO; // Pre File.WriteAllLines a prácu so súbormi
using System.Linq;
namespace AppDiagnostic
{
public partial class MainForm : Form
{
private bool stopUpdate = false; // Premenná na zastavenie aktualizácie
private int lastDisplayedLogIndex = 0;
private bool autoScrollEnabled = true; // Automatický posun, predvolene povolený
private MainForm appDiagnosticForm;
private Timer refreshTimer;
private LogAdapter _logAdapter; // Pre LogAdapter
private LogFilter _logFilter; // LogFilter objekt pre filtráciu
private readonly Func<int> connectedClientCountProvider;
private readonly Func<bool> activationRequestProvider;
private readonly Timer refreshTimer;
private readonly Font regularLogFont;
private readonly Font boldLogFont;
private List<LogColorRule> colorRules;
private long lastRenderedVersion = -1;
private int observedEntryCount;
private int visibleEntryCount;
private bool loadingFilters;
public MainForm()
public MainForm() : this(null, null)
{
this.Icon = Properties.Resources.TBF_icon;
}
public MainForm(Func<int> connectedClientCountProvider, Func<bool> activationRequestProvider)
{
this.connectedClientCountProvider = connectedClientCountProvider;
this.activationRequestProvider = activationRequestProvider;
InitializeComponent();
Icon = Properties.Resources.TBF_icon;
// Inicializujeme LogAdapter a priradíme ho k memoListView
_logAdapter = new LogAdapter(memoListView);
regularLogFont = new Font(logView.Font, FontStyle.Regular);
boldLogFont = new Font(logView.Font, FontStyle.Bold);
colorRules = LogColorRuleRepository.Load();
RefreshLogView();
InitializeFilters();
// Pripojenie na udalosť pri pridaní nového logu
// nakoľko sa memo refreshuje cyklicky, tak refresh na udalosť nepotrebujem
//LiveLogCache.Instance.LogAdded += OnLogAdded;
// Vytvoríme LogFilter objekt
//_logFilter = new LogFilter(memoListView);
}
private void OnLogAdded(string log)
{
try
{
RefreshLogView();
}
catch (Exception ex)
{
MessageBox.Show($"Error in OnLogAdded: {ex.Message}");
throw;
}
}
private void RefreshLogView()
{
// Skontrolujte, či voláme z iného vlákna
if (InvokeRequired)
{
Invoke((Action)RefreshLogView);
return;
}
memoListView.BeginUpdate(); // Zabraňuje vizuálnym aktualizáciám počas vykresľovania
try
{
// Skontrolujte, či je užívateľ na poslednom viditeľnom zázname
if (memoListView.Items.Count > 0)
{
var lastVisibleIndex = memoListView.TopItem.Index + memoListView.ClientRectangle.Height / memoListView.Items[0].Bounds.Height;
autoScrollEnabled = lastVisibleIndex >= memoListView.Items.Count - 1;
}
// Získajte nové logy od posledného indexu
var logs = LiveLogCache.Instance.GetLogs(lastDisplayedLogIndex, LiveLogCache.Instance.Logs.Count - lastDisplayedLogIndex);
// Pridajte len nové logy
foreach (var log in logs)
{
memoListView.Items.Add(new ListViewItem(log));
}
// Aktualizujte posledný zobrazený index
lastDisplayedLogIndex = LiveLogCache.Instance.Logs.Count;
// Ak je autoScrollEnabled, posuňte sa na posledný záznam
if (autoScrollEnabled && memoListView.Items.Count > 0)
{
memoListView.EnsureVisible(memoListView.Items.Count - 1);
}
}
finally
{
memoListView.EndUpdate(); // Umožní vizuálne aktualizácie
}
}
// Táto metóda sa spustí pri scrollovaní v memoListView (tzn. ak sa používateľ dostane na spodok listu)
private void memoListView_Scroll(object sender, EventArgs e)
{
// Skontrolujte, či používateľ dosiahol spodok ListView
if (memoListView.Items.Count > 0 &&
memoListView.Items[memoListView.Items.Count - 1].Bounds.Bottom <= memoListView.ClientSize.Height)
{
// Ak áno, načítame ďalšie logy
RefreshLogView();
}
}
private void button6_Click(object sender, EventArgs e)
{
//LiveLogCache.Instance.AddLog("Nový log z hlavnej aplikácie");
LiveLogCache.Instance.ClearLogs();
ClearListView();
}
private void runButton_Click(object sender, EventArgs e)
{
if (stopUpdate) // Ak je časovač zastavený, spustíme ho
{
stopUpdate = false; // Zastav aktualizáciu
runButton.Enabled = false; // Zakážeme tlačidlo Start počas behu
stopButton.Enabled = true; // Povolenie tlačidla Stop
refreshTimer = new Timer { Interval = 250 };
refreshTimer.Tick += refreshTimer_Tick;
refreshTimer.Start();
}
}
private void stopButton_Click(object sender, EventArgs e)
{
if (!stopUpdate) // Ak časovač beží, môžeme ho zastaviť
{
stopUpdate = true; // Spusti aktualizáciu
runButton.Enabled = true; // Povolenie tlačidla Start
stopButton.Enabled = false; // Zakážeme tlačidlo Stop
refreshTimer.Stop();
}
}
private void ClearListView()
{
if (InvokeRequired)
{
Invoke(new Action(ClearListView));
return;
}
memoListView.Items.Clear();
}
private void refreshMemoButton_Click(object sender, EventArgs e)
{
}
private void button7_Click(object sender, EventArgs e)
{
SaveLogsToFile();
//LiveLogCache.Instance.AddLog("Toto je nový log.");
RefreshView(true);
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
// Odpojenie udalosti, keď sa okno zatvára, inak môže po opätovnom spustení okna a pridaní nového itemu do listu zhhodiť program
// nakoľko sa memo refreshuje cyklicky, tak refresh na udalosť nepotrebujem
//LiveLogCache.Instance.LogAdded -= OnLogAdded;
_logAdapter = null;
refreshTimer.Stop();
refreshTimer.Dispose();
regularLogFont.Dispose();
boldLogFont.Dispose();
base.OnFormClosing(e);
}
private void filterButton_Click_1(object sender, EventArgs e)
private void InitializeFilters()
{
// Aplikujeme filter na základe textu z filterTextBox
string filterText = filterTextBox.Text;
//_logFilter.ApplyFilter(filterText); // Aplikovanie filtra
_logAdapter.ApplyFilter(filterText);
loadingFilters = true;
levelComboBox.Items.AddRange(new object[] { "All levels", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" });
levelComboBox.SelectedIndex = 0;
applicationComboBox.Items.Add("All applications");
applicationComboBox.SelectedIndex = 0;
loadingFilters = false;
}
private void SubForm_FormClosing(object sender, FormClosingEventArgs e)
private void refreshTimer_Tick(object sender, EventArgs e)
{
ProcessActivationRequest();
RefreshView(false);
}
private void ProcessActivationRequest()
{
if (activationRequestProvider == null || !activationRequestProvider())
{
return;
}
if (WindowState == FormWindowState.Minimized)
{
WindowState = FormWindowState.Normal;
}
Show();
BringToFront();
Activate();
}
private void RefreshView(bool forceFullRefresh)
{
List<DiagnosticLogEntry> snapshot = DiagnosticLogStore.Instance.GetSnapshot();
UpdateApplicationFilter(snapshot);
if (pauseButton.Checked)
{
UpdateStatus(snapshot.Count);
return;
}
long currentVersion = DiagnosticLogStore.Instance.Version;
if (!forceFullRefresh && currentVersion == lastRenderedVersion)
{
UpdateStatus(snapshot.Count);
return;
}
bool canAppend = !forceFullRefresh && snapshot.Count > observedEntryCount;
if (canAppend)
{
AppendEntries(snapshot.Skip(observedEntryCount));
}
else
{
RebuildView(snapshot);
}
observedEntryCount = snapshot.Count;
lastRenderedVersion = currentVersion;
UpdateStatus(snapshot.Count);
}
private void RebuildView(IEnumerable<DiagnosticLogEntry> entries)
{
logView.SuspendLayout();
logView.Clear();
visibleEntryCount = 0;
AppendEntries(entries, false);
logView.ResumeLayout();
if (autoScrollButton.Checked)
{
ScrollToEnd();
}
}
private void AppendEntries(IEnumerable<DiagnosticLogEntry> entries, bool scrollAfterAppend = true)
{
int originalSelectionStart = logView.SelectionStart;
int originalSelectionLength = logView.SelectionLength;
foreach (DiagnosticLogEntry entry in entries)
{
if (!MatchesFilter(entry))
{
continue;
}
AppendEntry(entry);
visibleEntryCount++;
}
if (scrollAfterAppend && autoScrollButton.Checked)
{
ScrollToEnd();
}
else if (!autoScrollButton.Checked)
{
int safeStart = Math.Min(originalSelectionStart, logView.TextLength);
int safeLength = Math.Min(originalSelectionLength, logView.TextLength - safeStart);
logView.Select(safeStart, safeLength);
}
}
private void AppendEntry(DiagnosticLogEntry entry)
{
string text = DiagnosticLogFormatter.Format(entry);
if (logView.TextLength > 0)
{
logView.AppendText(Environment.NewLine);
}
int startIndex = logView.TextLength;
logView.AppendText(text);
LogColorizer.Apply(logView, startIndex, text.Length, text, colorRules, regularLogFont, boldLogFont);
logView.Select(logView.TextLength, 0);
}
private bool MatchesFilter(DiagnosticLogEntry entry)
{
string selectedLevel = levelComboBox.SelectedItem as string;
if (!string.IsNullOrEmpty(selectedLevel) && selectedLevel != "All levels" && !string.Equals(entry.Level, selectedLevel, StringComparison.OrdinalIgnoreCase))
{
return false;
}
string selectedApplication = applicationComboBox.SelectedItem as string;
if (!string.IsNullOrEmpty(selectedApplication) && selectedApplication != "All applications" && !string.Equals(entry.ApplicationName, selectedApplication, StringComparison.OrdinalIgnoreCase))
{
return false;
}
string filter = filterTextBox.Text.Trim();
return filter.Length == 0 || DiagnosticLogFormatter.Format(entry).IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
}
private void UpdateApplicationFilter(IEnumerable<DiagnosticLogEntry> entries)
{
string selectedApplication = applicationComboBox.SelectedItem as string ?? "All applications";
List<string> applications = entries.Select(entry => entry.ApplicationName).Where(name => !string.IsNullOrWhiteSpace(name)).Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(name => name).ToList();
List<string> currentApplications = applicationComboBox.Items.Cast<string>().Skip(1).ToList();
if (applications.SequenceEqual(currentApplications, StringComparer.OrdinalIgnoreCase))
{
return;
}
loadingFilters = true;
applicationComboBox.BeginUpdate();
applicationComboBox.Items.Clear();
applicationComboBox.Items.Add("All applications");
applicationComboBox.Items.AddRange(applications.Cast<object>().ToArray());
applicationComboBox.SelectedItem = applicationComboBox.Items.Cast<string>().FirstOrDefault(item => string.Equals(item, selectedApplication, StringComparison.OrdinalIgnoreCase)) ?? "All applications";
applicationComboBox.EndUpdate();
loadingFilters = false;
}
private void UpdateStatus(int storedCount)
{
int clients = connectedClientCountProvider?.Invoke() ?? 0;
receiverStatusLabel.Text = pauseButton.Checked ? $"Paused | Connected sources: {clients}" : $"Listening | Connected sources: {clients}";
countStatusLabel.Text = $"Received: {DiagnosticLogStore.Instance.TotalReceived:N0} | Stored: {storedCount:N0} | Visible: {visibleEntryCount:N0}";
}
private void ScrollToEnd()
{
logView.Select(logView.TextLength, 0);
logView.ScrollToCaret();
}
private void pauseButton_Click(object sender, EventArgs e)
{
pauseButton.Text = pauseButton.Checked ? "Resume" : "Pause";
if (!pauseButton.Checked)
{
RefreshView(true);
}
else
{
UpdateStatus(DiagnosticLogStore.Instance.GetSnapshot().Count);
}
}
private void refreshButton_Click(object sender, EventArgs e)
{
RefreshView(true);
}
private void clearButton_Click(object sender, EventArgs e)
{
DiagnosticLogStore.Instance.Clear();
observedEntryCount = 0;
visibleEntryCount = 0;
RefreshView(true);
}
private void saveButton_Click(object sender, EventArgs e)
{
using (var dialog = new SaveFileDialog())
{
dialog.Filter = "Text files (*.txt)|*.txt|Log files (*.log)|*.log|All files (*.*)|*.*";
dialog.Title = "Save visible diagnostic logs";
dialog.DefaultExt = "log";
dialog.FileName = $"AppDiagnostic_{DateTime.Now:yyyyMMdd_HHmmss}.log";
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
try
{
// Vaša logika pri uzatváraní formy
// this.Hide(); // Podforma sa len skryje
File.WriteAllText(dialog.FileName, logView.Text);
}
catch (Exception ex)
catch (Exception exception)
{
// Ošetrenie výnimky
MessageBox.Show("Chyba pri zatváraní pod-aplikácie: " + ex.Message);
MessageBox.Show(this, $"Unable to save diagnostic logs: {exception.Message}", "Save error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void SaveLogsToFile()
private void copyButton_Click(object sender, EventArgs e)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
saveFileDialog.Title = "Save TBF live logs";
saveFileDialog.DefaultExt = "txt";
saveFileDialog.FileName = "TBFLiveLogs.txt";
CopySelectionOrCurrentLine();
}
if (saveFileDialog.ShowDialog() == DialogResult.OK)
private void copySelectionMenuItem_Click(object sender, EventArgs e)
{
if (logView.SelectionLength > 0)
{
CopyText(logView.SelectedText);
}
}
private void copyLineMenuItem_Click(object sender, EventArgs e)
{
CopyCurrentLine();
}
private void copyAllButton_Click(object sender, EventArgs e)
{
CopyText(logView.Text);
}
private void CopySelectionOrCurrentLine()
{
if (logView.SelectionLength > 0)
{
CopyText(logView.SelectedText);
}
else
{
CopyCurrentLine();
}
}
private void CopyCurrentLine()
{
if (logView.Lines.Length == 0)
{
return;
}
int lineIndex = logView.GetLineFromCharIndex(logView.SelectionStart);
if (lineIndex >= 0 && lineIndex < logView.Lines.Length)
{
CopyText(logView.Lines[lineIndex]);
}
}
private void CopyText(string text)
{
if (string.IsNullOrEmpty(text))
{
return;
}
try
{
// Načítanie všetkých logov z LiveLogCache
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.GetCount());
// Uloženie logov do vybraného súboru
File.WriteAllLines(saveFileDialog.FileName, logs);
MessageBox.Show("Logs saved successfully.", "Save TBF live logs", MessageBoxButtons.OK, MessageBoxIcon.Information);
Clipboard.SetText(text);
}
catch (Exception ex)
catch (Exception exception)
{
MessageBox.Show($"An error occurred while saving TBF live logs: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
MessageBox.Show(this, $"Unable to copy text: {exception.Message}", "Clipboard error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button2_Click(object sender, EventArgs e)
private void wrapButton_Click(object sender, EventArgs e)
{
this.Close();
//this.Hide(); // Podforma sa len skryje
logView.WordWrap = wrapButton.Checked;
}
private void MemoListView_DoubleClick(object sender, EventArgs e)
private void alwaysOnTopButton_Click(object sender, EventArgs e)
{
if (memoListView.SelectedItems.Count > 0)
{
var selectedItem = memoListView.SelectedItems[0];
int selectedIndex = memoListView.Items.IndexOf(selectedItem);
if (selectedIndex >= 0)
{
// Zrušenie filtra
_logAdapter._filterText = string.Empty;
// Načítanie logov od indexu vybraného riadku
var logs = LiveLogCache.Instance.GetLogs(selectedIndex, LiveLogCache.Instance.GetCount() - selectedIndex);
// Obnovenie ListView s novými údajmi
memoListView.BeginUpdate();
memoListView.Items.Clear();
foreach (var log in logs)
{
var item = new ListViewItem(log)
{
BackColor = memoListView.Items.Count % 2 == 0 ? Color.White : Color.FromArgb(240, 240, 240)
};
memoListView.Items.Add(item);
TopMost = alwaysOnTopButton.Checked;
}
memoListView.EndUpdate();
private void colorRulesButton_Click(object sender, EventArgs e)
{
using (var editor = new ColorRuleEditorForm(colorRules))
{
if (editor.ShowDialog(this) != DialogResult.OK)
{
return;
}
colorRules = editor.Rules;
try
{
LogColorRuleRepository.Save(colorRules);
}
catch (Exception exception)
{
MessageBox.Show(this, $"Unable to save color rules: {exception.Message}", "Settings error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
RefreshView(true);
}
}
private void applyFilterButton_Click(object sender, EventArgs e)
{
RefreshView(true);
}
private void clearFilterButton_Click(object sender, EventArgs e)
{
loadingFilters = true;
filterTextBox.Clear();
levelComboBox.SelectedIndex = 0;
applicationComboBox.SelectedIndex = 0;
loadingFilters = false;
RefreshView(true);
}
private void filterValueChanged(object sender, EventArgs e)
{
if (!loadingFilters)
{
RefreshView(true);
}
}
private void filterTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
RefreshView(true);
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.Escape)
{
clearFilterButton_Click(sender, EventArgs.Empty);
e.SuppressKeyPress = true;
}
}
private void closeButton_Click(object sender, EventArgs e)
{
Close();
}
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.F)
{
filterTextBox.Focus();
filterTextBox.SelectAll();
e.SuppressKeyPress = true;
}
else if (e.Control && e.KeyCode == Keys.S)
{
saveButton_Click(sender, EventArgs.Empty);
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.F5)
{
RefreshView(true);
e.SuppressKeyPress = true;
}
}
}
+19 -1
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -14,9 +15,26 @@ namespace AppDiagnostic
[STAThread]
static void Main()
{
bool isFirstInstance;
using (var instanceMutex = new Mutex(true, "Sensus.AppDiagnostic.SingleInstance", out isFirstInstance))
using (var activationEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Sensus.AppDiagnostic.Activate"))
{
if (!isFirstInstance)
{
activationEvent.Set();
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
using (var diagnosticServer = new DiagnosticPipeServer(DiagnosticLogStore.Instance.Add))
{
diagnosticServer.Start();
Application.Run(new MainForm(() => diagnosticServer.ConnectedClientCount, () => activationEvent.WaitOne(0)));
}
}
}
}
}
+149 -78
View File
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.5.11723.231 stable
VisualStudioVersion = 18.5.11723.231
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBF", "TBF\TBF.csproj", "{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}"
ProjectSection(ProjectDependencies) = postProject
@@ -106,11 +106,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabelPrinting", "LabelPrint
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBFTests", "TBFTests\TBFTests.csproj", "{77EB589F-C670-4489-AAD6-2A3C02061FD1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic", "AppDiagnostic\AppDiagnostic.csproj", "{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}"
ProjectSection(ProjectDependencies) = postProject
{8F942729-F454-4C99-BA6C-746962065AE3} = {8F942729-F454-4C99-BA6C-746962065AE3}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedComponents", "SharedComponents\SharedComponents.csproj", "{8F942729-F454-4C99-BA6C-746962065AE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sensus.iPerl.RfidCom", "..\iPerlHead\Sensus.iPerl.RfidCom\Sensus.iPerl.RfidCom.csproj", "{A3E14180-7F00-42E5-94A9-8DB62EAD6EE8}"
@@ -208,6 +203,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tools.JsonToXlsHelper", "Ex
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MagFluxConfig", "ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\MagFlux\MagFluxConfig\MagFluxConfig.csproj", "{70398B99-B134-4BBD-968B-7399B70C3CE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic", "AppDiagnostic\AppDiagnostic.csproj", "{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic.Logging", "AppDiagnostic.Logging\AppDiagnostic.Logging.csproj", "{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
_MANUAL_CONTROL|Any CPU = _MANUAL_CONTROL|Any CPU
@@ -2638,78 +2637,6 @@ Global
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.XP32bit|x64.Build.0 = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.XP32bit|x86.ActiveCfg = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.XP32bit|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.Build.0 = Release|Any CPU
{8F942729-F454-4C99-BA6C-746962065AE3}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{8F942729-F454-4C99-BA6C-746962065AE3}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{8F942729-F454-4C99-BA6C-746962065AE3}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -5806,6 +5733,150 @@ Global
{70398B99-B134-4BBD-968B-7399B70C3CE2}.XP32bit|x64.Build.0 = Debug|Any CPU
{70398B99-B134-4BBD-968B-7399B70C3CE2}.XP32bit|x86.ActiveCfg = Debug|Any CPU
{70398B99-B134-4BBD-968B-7399B70C3CE2}.XP32bit|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+3
View File
@@ -490,6 +490,9 @@ namespace TBF
}
}
//AppDiagnostic SDK - nlog connector registration
AppDiagnostic.Logging.AppDiagnosticConnector.Register();
try
{
/// Open the main application window
+8 -3
View File
@@ -4595,9 +4595,9 @@
<Project>{5954d496-caab-4f7a-bde2-bdc8f47dab19}</Project>
<Name>NfcS5_DLL</Name>
</ProjectReference>
<ProjectReference Include="..\AppDiagnostic\AppDiagnostic.csproj">
<Project>{fa9abad1-7184-4295-ade8-d44f2e3de6b2}</Project>
<Name>AppDiagnostic</Name>
<ProjectReference Include="..\AppDiagnostic.Logging\AppDiagnostic.Logging.csproj">
<Project>{a7af8ed2-362e-4dbb-b607-eba2820719ec}</Project>
<Name>AppDiagnostic.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\Common\Common.csproj">
<Project>{c8939821-ba5c-4988-a3d0-bf53b74865c7}</Project>
@@ -4694,4 +4694,9 @@
<ItemGroup>
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisCalibrationFactors.cs" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>if not exist "$(TargetDir)AppDiagnostic\" mkdir "$(TargetDir)AppDiagnostic\"
xcopy /Y /E /I "$(SolutionDir)AppDiagnostic\bin\$(ConfigurationName)\*" "$(TargetDir)AppDiagnostic\"
if errorlevel 1 exit /b 1</PostBuildEvent>
</PropertyGroup>
</Project>
+55 -35
View File
@@ -22,6 +22,8 @@ using SharedComponents;
using System.Diagnostics;
using TBF.Rig.TestMethods.iPerlCommunication;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
using System.Diagnostics;
using System.IO;
namespace TBF.UI
{
@@ -31,6 +33,7 @@ namespace TBF.UI
public partial class MainWnd : Form
{
static readonly ILog log = LogManager.GetLogger(typeof(MainWnd));
private static readonly NLog.Logger diagnosticLogger = NLog.LogManager.GetCurrentClassLogger();
/// Used when re-scaling the dialog: 100% = 96dpi, 125% = 120dpi, 150% = 144dpi
public static int Dpi;
@@ -142,7 +145,7 @@ namespace TBF.UI
cameraTSMItem.Text = Strings.Camera;
cameraTSMItem.Click += new System.EventHandler(this.cameraTSMItem_Click);
mainMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.cameraTSMItem});
mainMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.cameraTSMItem });
#endif
UpdateMenuItemsVisibility();
@@ -166,10 +169,10 @@ namespace TBF.UI
Rig.StateMachine.MachineState = TBF.DB.CurrentBench.IsRealBench ? Rig.MachineState.StartingUp : Rig.MachineState.Disabled;
#if DEBUG
#if DEBUG
//define always valid for printer test - BUMI
Rig.StateMachine.MachineState = Rig.MachineState.StartingUp;
#endif
#endif
///
if (Rig.StateMachine.MachineState == Rig.MachineState.StartingUp)
@@ -324,43 +327,43 @@ namespace TBF.UI
}
#endif
Bridge.ButtonsEtcHandler += delegate(object sndr, ButtonsEtcEventArgs args)
Bridge.ButtonsEtcHandler += delegate (object sndr, ButtonsEtcEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<ButtonsEtcEventArgs>(OnButtonsEtc), sndr, args); }
else OnButtonsEtc(sndr, args);
};
Bridge.ActivityHandler += delegate(object sndr, UiBridge.ActivityEventArgs args)
Bridge.ActivityHandler += delegate (object sndr, UiBridge.ActivityEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.ActivityEventArgs>(OnActivity), sndr, args); }
else OnActivity(sndr, args);
};
Bridge.StateChangedHandler += delegate(object sndr, UiBridge.StateChangedEventArgs args)
Bridge.StateChangedHandler += delegate (object sndr, UiBridge.StateChangedEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.StateChangedEventArgs>(OnStateChanged), sndr, args); }
else OnStateChanged(sndr, args);
};
Bridge.StateMachineTickHandler += delegate(object sndr, UiBridge.StateMachineTickEventArgs args)
Bridge.StateMachineTickHandler += delegate (object sndr, UiBridge.StateMachineTickEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.StateMachineTickEventArgs>(OnStateMachineTick), sndr, args); }
else OnStateMachineTick(sndr, args);
};
Bridge.TestProgressHandler += delegate(object sndr, UiBridge.TestProgressEventArgs args)
Bridge.TestProgressHandler += delegate (object sndr, UiBridge.TestProgressEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.TestProgressEventArgs>(OnTestProgress), sndr, args); }
else OnTestProgress(sndr, args);
};
Bridge.ProcedureSelectedHandler += delegate(object sndr, UiBridge.ProcedureSelectedEventArgs args)
Bridge.ProcedureSelectedHandler += delegate (object sndr, UiBridge.ProcedureSelectedEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.ProcedureSelectedEventArgs>(OnProcedureSelected), sndr, args); }
else OnProcedureSelected(sndr, args);
};
Bridge.SaveSettingsHandler += delegate(object sndr, UiBridge.SaveSettingsEventArgs args)
Bridge.SaveSettingsHandler += delegate (object sndr, UiBridge.SaveSettingsEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.SaveSettingsEventArgs>(OnSaveSettings), sndr, args); }
else OnSaveSettings(sndr, args);
@@ -716,7 +719,7 @@ namespace TBF.UI
private void benchMetrologyTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Metrology.MetrologyDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchUncertaintyTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Uncertainties.UncertaintiesDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchTestProfilesTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.TestProfiles.TestProfilesDlg().ShowDialog(); Cursor = Cursors.Default; }
private void editSchDrawingTSMItem_Click(object sender, EventArgs e){ Cursor = Cursors.WaitCursor; new TBF.UI.Bench.EditSchDrawing.EditSchDrawingDlg().ShowDialog();Cursor = Cursors.Default; }
private void editSchDrawingTSMItem_Click(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.EditSchDrawing.EditSchDrawingDlg().ShowDialog(); Cursor = Cursors.Default; }
private void proceduresTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Procedures.ProceduresDlg().ShowDialog(); Cursor = Cursors.Default; }
private void usersTSMItem_Click(object s, EventArgs e)
@@ -1162,39 +1165,56 @@ namespace TBF.UI
private void appDiagnosticMenuItem_Click(object sender, EventArgs e)
{
/*diagApi = new DiagApi(liveLogCache);
//diagApi.AddLog("ahoj, toto je prvy log");
ILog loger = LogManager.GetLogger("logCache");
log.Debug("ahoj, ideme");*/
LiveLogCache.Instance.AddLog("=== Live diagnostic entry ===");
DiagApi liveDiagApi = new DiagApi();
/*try
try
{
// Predpoklad�me, �e ApplicationDiagnostic.exe je v rovnakom adres�ri ako hlavn� aplik�cia
string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AppDiagnostic.exe");
string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AppDiagnostic", "AppDiagnostic.exe");
if (File.Exists(exePath))
if (!File.Exists(exePath))
{
ProcessStartInfo startInfo = new ProcessStartInfo
MessageBox.Show($"AppDiagnostic.exe not found:\n{exePath}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = exePath,
UseShellExecute = true // Spust� aplik�ciu ako samostatn� proces
};
System.Diagnostics.Process.Start(startInfo);
}
else
{
MessageBox.Show("ApplicationDiagnostic.exe not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
WorkingDirectory = Path.GetDirectoryName(exePath),
UseShellExecute = true
});
// Temporary diagnostic test.
SendDiagnosticTestLogs();
}
catch (Exception ex)
{
MessageBox.Show($"Failed to start ApplicationDiagnostic: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}*/
MessageBox.Show($"Failed to start AppDiagnostic or send test logs: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SendDiagnosticTestLogs()
{
NLog.Logger deviceLogger = NLog.LogManager.GetLogger("TBF.TestBench.DeviceSimulation");
deviceLogger.Trace("TRACE: Communication cycle started.");
deviceLogger.Debug("DEBUG: Device configuration loaded.");
deviceLogger.Info("INFO: Test bench started.");
deviceLogger.Warn("WARN: Simulated pressure is approaching the limit.");
for (int position = 1; position <= 10; position++)
{
deviceLogger.Debug($"Reading simulated device at position {position}.");
}
try
{
throw new InvalidOperationException("Simulated device communication failure.");
}
catch (Exception ex)
{
deviceLogger.Error(ex, "ERROR: Unable to communicate with simulated device.");
}
deviceLogger.Fatal("FATAL: Simulated emergency stop.");
}
private void optoHeadsToolStripMenuItem_Click(object sender, EventArgs e)
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogLevel="Trace"
internalLogFile="${basedir}/nlog-internal.log"
throwConfigExceptions="true">
<extensions>
<add assembly="Xylem.Common.Utils.Logging" />
<add assembly="AppDiagnostic.Logging" />
</extensions>
<targets>
<target name="uiTrace"
xsi:type="UiTarget"
layout="${time}|${level:uppercase=true:padding=-5}|${message}" />
<target name="appDiagnostic"
xsi:type="AppDiagnostic"
pipeName="Sensus.AppDiagnostic.LogPipe"
queueLimit="10000"
reconnectDelayMilliseconds="500"
connectTimeoutMilliseconds="250"
layout="${message}" />
<target name="logfile"
xsi:type="File"
fileName="${basedir}/GenesisCordonelInterfaceLogger.log"
layout="${longdate}|${level:uppercase=true:padding=-5}|${logger}|${message}|${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="uiTrace" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
+14 -1
View File
@@ -1,9 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogLevel="Trace"
internalLogFile="${basedir}/nlog-internal.log"
throwConfigExceptions="true">
<extensions>
<add assembly="Xylem.Common.Utils.Logging" />
<add assembly="AppDiagnostic.Logging" />
</extensions>
<targets>
@@ -11,6 +15,14 @@
xsi:type="UiTarget"
layout="${time}|${level:uppercase=true:padding=-5}|${message}" />
<target name="appDiagnostic"
xsi:type="AppDiagnostic"
pipeName="Sensus.AppDiagnostic.LogPipe"
queueLimit="10000"
reconnectDelayMilliseconds="500"
connectTimeoutMilliseconds="250"
layout="${message}" />
<target name="logfile"
xsi:type="File"
fileName="${basedir}/GenesisCordonelInterfaceLogger.log"
@@ -18,6 +30,7 @@
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="uiTrace" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="logfile" />
</rules>