64e3fbe035
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes.
67 lines
2.2 KiB
C#
67 lines
2.2 KiB
C#
using Avalonia;
|
|
using Serilog;
|
|
using ZB.MOM.WW.OtOpcUa.Client.Shared;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Client.UI;
|
|
|
|
/// <summary>Entry point for the OPC UA client UI application.</summary>
|
|
public class Program
|
|
{
|
|
/// <summary>Main entry point for the application.</summary>
|
|
/// <param name="args">Command-line arguments passed to the application.</param>
|
|
[STAThread]
|
|
public static void Main(string[] args)
|
|
{
|
|
ConfigureLogging();
|
|
try
|
|
{
|
|
BuildAvaloniaApp()
|
|
.StartWithClassicDesktopLifetime(args);
|
|
}
|
|
finally
|
|
{
|
|
Log.CloseAndFlush();
|
|
}
|
|
}
|
|
|
|
/// <summary>Builds the Avalonia AppBuilder with platform-specific configuration.</summary>
|
|
/// <returns>Configured AppBuilder for desktop lifetime.</returns>
|
|
public static AppBuilder BuildAvaloniaApp()
|
|
{
|
|
return AppBuilder.Configure<App>()
|
|
.UsePlatformDetect()
|
|
.WithInterFont()
|
|
.LogToTrace();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the Serilog root logger with a console sink + a rolling daily file sink
|
|
/// under <c>{LocalAppData}/OtOpcUaClient/logs/</c>. CLAUDE.md mandates Serilog with a
|
|
/// rolling daily file sink as the project standard; this is also the only way the swallow
|
|
/// blocks in the alarms / subscriptions / redundancy view-models surface a diagnosable
|
|
/// trace when an operator hits a problem in the field.
|
|
/// </summary>
|
|
private static void ConfigureLogging()
|
|
{
|
|
var logsDir = Path.Combine(ClientStoragePaths.GetRoot(), "logs");
|
|
try
|
|
{
|
|
Directory.CreateDirectory(logsDir);
|
|
}
|
|
catch
|
|
{
|
|
// Best-effort; file sink will gracefully fall back if the dir can't be created.
|
|
}
|
|
|
|
Log.Logger = new LoggerConfiguration()
|
|
.MinimumLevel.Information()
|
|
.Enrich.FromLogContext()
|
|
.WriteTo.Console()
|
|
.WriteTo.File(
|
|
path: Path.Combine(logsDir, "client-ui-.log"),
|
|
rollingInterval: RollingInterval.Day,
|
|
retainedFileCountLimit: 14,
|
|
shared: true)
|
|
.CreateLogger();
|
|
}
|
|
} |