using System; using Microsoft.Extensions.Configuration; using Serilog; using Topshelf; using ZB.MOM.WW.LmxProxy.Host.Configuration; namespace ZB.MOM.WW.LmxProxy.Host { internal static class Program { static int Main(string[] args) { // 1. Build configuration (instance override file loaded from LMXPROXY_INSTANCE env var) var instance = Environment.GetEnvironmentVariable("LMXPROXY_INSTANCE"); var configuration = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false) .AddJsonFile($"appsettings.{instance}.json", optional: true, reloadOnChange: false) .AddEnvironmentVariables() .Build(); // 2. Set working directory to exe location so relative log paths resolve correctly Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory; // 3. Configure Serilog Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .Enrich.FromLogContext() .Enrich.WithMachineName() .Enrich.WithThreadId() .CreateLogger(); try { // 4. Bind configuration var config = new LmxProxyConfiguration(); configuration.Bind(config); // 5. Configure Topshelf var exitCode = HostFactory.Run(host => { host.UseSerilog(); host.Service(service => { service.ConstructUsing(() => new LmxProxyService(config)); service.WhenStarted(s => s.Start()); service.WhenStopped(s => s.Stop()); service.WhenPaused(s => s.Pause()); service.WhenContinued(s => s.Continue()); service.WhenShutdown(s => s.Stop()); }); host.SetServiceName("ZB.MOM.WW.LmxProxy.Host"); host.SetDisplayName("SCADA Bridge LMX Proxy"); host.SetDescription("gRPC proxy for AVEVA System Platform via MXAccess COM API"); host.StartAutomatically(); host.EnablePauseAndContinue(); host.EnableServiceRecovery(recovery => { recovery.RestartService(config.ServiceRecovery.FirstFailureDelayMinutes); recovery.RestartService(config.ServiceRecovery.SecondFailureDelayMinutes); recovery.RestartService(config.ServiceRecovery.SubsequentFailureDelayMinutes); recovery.SetResetPeriod(config.ServiceRecovery.ResetPeriodDays); }); }); return (int)exitCode; } catch (Exception ex) { Log.Fatal(ex, "LmxProxy service terminated unexpectedly"); return 1; } finally { Log.CloseAndFlush(); } } } }