Made certain config options editable in the app config.

This commit is contained in:
2026-07-03 09:55:38 +02:00
parent 2dab6f970a
commit b6cc34be27
9 changed files with 100 additions and 16 deletions
+22 -2
View File
@@ -145,6 +145,25 @@ File: `src\HostAvailabilityMonitor\appsettings.json`
- `HipVirtualMachines`: optional static VM checks
- `Targets`: endpoints to probe
### Runtime section
Important fields in `Runtime`:
- `MaxConcurrency`: maximum number of parallel endpoint checks
- `DefaultValidateUncPathAccess`: default for UNC targets without their own `ValidateUncPathAccess` value
- `NonZeroExitCodeOnAnyFailure`: exit with code `2` when endpoint failures are found
- `NonZeroExitCodeOnExecutionError`: exit with code `1` on technical execution errors
- `StateDirectory`: directory for the state file
- `StateFileName`: state file name, default `monitor-state.json`
### Logging section
Important fields in `Logging`:
- `LogDirectory`: directory for rolling log files
- `FilePrefix`: prefix for daily log files
- `RetentionDays`: number of daily log files to retain, default `30`; `0` disables automatic cleanup
### Email section
Important fields in `Email`:
@@ -330,12 +349,13 @@ It contains:
- `Logging`
- `EventLog`
- `Email`
- `HipVirtualMachines`
`Targets` is rebuilt by the generator at runtime.
Important:
When the generator writes the monitor JSON, the daily summary options and static HIP VM settings are also copied into the generated target file. That means `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, `DailySummaryMinuteLocal`, and `GeneratedMonitorConfig.HipVirtualMachines` flow directly into the output monitor configuration.
When the generator writes the monitor JSON, runtime, logging, daily summary, and static HIP VM settings are also copied into the generated target file. That means values such as `GeneratedMonitorConfig.Runtime.StateFileName`, `GeneratedMonitorConfig.Logging.RetentionDays`, `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, `DailySummaryMinuteLocal`, and `GeneratedMonitorConfig.HipVirtualMachines` flow directly into the output monitor configuration.
---
@@ -472,7 +492,7 @@ The generator is designed defensively:
The monitor is also defensive:
- daily rolling logs
- default retention of 5 days
- default retention of 30 days, configurable through `Logging.RetentionDays`
- event log writes are best effort only
- state file is written atomically
- failure/recovery emails follow explicit notification rules
+22 -2
View File
@@ -145,6 +145,25 @@ Datei: `src\HostAvailabilityMonitor\appsettings.json`
- `HipVirtualMachines`: optionale statische VM-Prüfungen
- `Targets`: die zu prüfenden Endpunkte
### Runtime
Wichtige Felder im Abschnitt `Runtime`:
- `MaxConcurrency`: maximale Anzahl paralleler Endpoint-Checks
- `DefaultValidateUncPathAccess`: Standardwert fuer UNC-Targets ohne eigenen `ValidateUncPathAccess`-Wert
- `NonZeroExitCodeOnAnyFailure`: bei fachlichen DOWN-Ergebnissen mit Exitcode `2` beenden
- `NonZeroExitCodeOnExecutionError`: bei technischen Ausfuehrungsfehlern mit Exitcode `1` beenden
- `StateDirectory`: Verzeichnis fuer die Statusdatei
- `StateFileName`: Dateiname der Statusdatei, standardmaessig `monitor-state.json`
### Logging
Wichtige Felder im Abschnitt `Logging`:
- `LogDirectory`: Verzeichnis fuer die Rolling-Logdateien
- `FilePrefix`: Prefix der taeglichen Logdateien
- `RetentionDays`: Anzahl der aufzubewahrenden taeglichen Logdateien, standardmaessig `30`; `0` deaktiviert die automatische Bereinigung
### Email
Wichtige Felder im Abschnitt `Email`:
@@ -330,12 +349,13 @@ Hier werden gepflegt:
- `Logging`
- `EventLog`
- `Email`
- `HipVirtualMachines`
`Targets` wird vom Generator zur Laufzeit neu erzeugt.
Wichtig:
Wenn der Generator die Monitor-JSON erzeugt, werden auch die Felder für die Tagesstatus-Mail und die statische HIP-VM-Prüfung mit erzeugt. Das heißt: `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, `DailySummaryMinuteLocal` und `GeneratedMonitorConfig.HipVirtualMachines` werden direkt in die Zielkonfiguration übernommen.
Wenn der Generator die Monitor-JSON erzeugt, werden auch Runtime-, Logging-, Tagesstatus-Mail- und statische HIP-VM-Felder mit erzeugt. Das heißt: Werte wie `GeneratedMonitorConfig.Runtime.StateFileName`, `GeneratedMonitorConfig.Logging.RetentionDays`, `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, `DailySummaryMinuteLocal` und `GeneratedMonitorConfig.HipVirtualMachines` werden direkt in die Zielkonfiguration übernommen.
---
@@ -472,7 +492,7 @@ Der Generator ist defensiv gebaut:
Der Monitor ist ebenfalls defensiv gebaut:
- Rolling-Dateilog mit täglicher Rotation
- Retention standardmäßig 5 Tage
- Retention standardmäßig 30 Tage, konfigurierbar über `Logging.RetentionDays`
- Eventlog-Schreiben nur best effort
- Statusdatei mit atomischem Schreiben
- Failure-/Recovery-Mails nur bei definierten Bedingungen
+3 -1
View File
@@ -86,7 +86,7 @@ Diese Struktur ist bewusst einfach gehalten, damit das Repository sauber in **Gi
- Task-Scheduler-tauglich
- tägliche Logrotation
- Log-Retention standardmäßig 5 Tage
- Log-Retention standardmäßig 30 Tage
- Windows Application Event Log
- SMTP-Mails bei DOWN, Recovery (`DOWN -> UP`) und täglichem Status
- SMTP-Sendports bzw. reine E-Mail-Empfaengerlisten werden vom Generator uebersprungen und vom Monitor defensiv nur als `Skipped` protokolliert, nicht alarmiert
@@ -341,6 +341,8 @@ Wichtige Felder:
- `BizTalk.ApplicationMappings`: Mapping von BizTalk-Anwendungsnamen auf fachliche App-Namen
- `Output.Path`: Pfad der zu erzeugenden Monitor-JSON
- `GeneratedMonitorConfig`: Vorlage für Logging, Runtime, Event Log und Mail des Monitors
- `GeneratedMonitorConfig.Logging.RetentionDays`: Aufbewahrung der taeglichen Monitor-Logdateien, standardmaessig `30`
- `GeneratedMonitorConfig.Runtime.StateFileName`: Dateiname der Statusdatei, falls mehrere Monitor-Konfigurationen getrennten Zustand brauchen
- `GeneratedMonitorConfig.HipVirtualMachines`: statische HIP-VM-Prüfung in der generierten Monitor-JSON einschalten
- `GeneratedMonitorConfig.Email.SendDailySummary`: tägliche Status-Mail in der generierten Monitor-JSON einschalten
- `GeneratedMonitorConfig.Email.DailySummaryHourLocal`: lokale Uhrzeit der Tageszusammenfassung
@@ -213,7 +213,7 @@ namespace BizTalkMonitorConfigGenerator.Configuration
/// <summary>
/// Gets or sets the number of daily generator log files to retain.
/// </summary>
public int RetentionDays { get; set; } = 5;
public int RetentionDays { get; set; } = 30;
}
/// <summary>
@@ -424,6 +424,23 @@ namespace BizTalkMonitorConfigGenerator.Configuration
configuration.Runtime.MaxConcurrency = 1;
}
if (string.IsNullOrWhiteSpace(configuration.Runtime.StateDirectory))
{
configuration.Runtime.StateDirectory = "state";
}
if (string.IsNullOrWhiteSpace(configuration.Runtime.StateFileName))
{
configuration.Runtime.StateFileName = "monitor-state.json";
}
if (Path.IsPathRooted(configuration.Runtime.StateFileName)
|| configuration.Runtime.StateFileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0
|| configuration.Runtime.StateFileName.IndexOfAny(new[] { '\\', '/' }) >= 0)
{
throw new InvalidOperationException("GeneratedMonitorConfig.Runtime.StateFileName muss ein Dateiname ohne Pfadanteile sein.");
}
if (configuration.Logging.RetentionDays < 0)
{
throw new InvalidOperationException("GeneratedMonitorConfig.Logging.RetentionDays darf nicht negativ sein.");
@@ -493,7 +510,8 @@ namespace BizTalkMonitorConfigGenerator.Configuration
DefaultValidateUncPathAccess = configuration.Runtime.DefaultValidateUncPathAccess,
NonZeroExitCodeOnAnyFailure = configuration.Runtime.NonZeroExitCodeOnAnyFailure,
NonZeroExitCodeOnExecutionError = configuration.Runtime.NonZeroExitCodeOnExecutionError,
StateDirectory = configuration.Runtime.StateDirectory
StateDirectory = configuration.Runtime.StateDirectory,
StateFileName = configuration.Runtime.StateFileName
},
Logging = new LoggingOptions
{
+1 -1
View File
@@ -241,7 +241,7 @@ namespace BizTalkMonitorConfigGenerator
try
{
var directory = ResolvePath(baseDirectory ?? AppDomain.CurrentDomain.BaseDirectory, "logs");
var fallbackLogger = new GeneratorFileLogger(directory, "biztalk-monitor-config-generator-startup", 5, "BizTalkMonitorConfigGenerator", "Startup");
var fallbackLogger = new GeneratorFileLogger(directory, "biztalk-monitor-config-generator-startup", 30, "BizTalkMonitorConfigGenerator", "Startup");
fallbackLogger.Error("Generator konnte nicht gestartet werden. Konfiguration=" + (configPath ?? "(nicht aufgeloest)") + ". Fehler=" + exception.GetType().Name + ": " + exception.Message);
fallbackLogger.Error("Details: " + exception);
WriteConsoleInfo("Fallback-Log geschrieben: " + BuildLogFilePreview(directory, "biztalk-monitor-config-generator-startup"));
@@ -4,7 +4,7 @@
"Logging": {
"LogDirectory": "logs",
"FilePrefix": "biztalk-monitor-config-generator",
"RetentionDays": 5
"RetentionDays": 30
},
"EventLog": {
"Enabled": true,
@@ -52,12 +52,13 @@
"DefaultValidateUncPathAccess": false,
"NonZeroExitCodeOnAnyFailure": false,
"NonZeroExitCodeOnExecutionError": true,
"StateDirectory": "state"
"StateDirectory": "state",
"StateFileName": "monitor-state.json"
},
"Logging": {
"LogDirectory": "logs",
"FilePrefix": "host-availability-monitor",
"RetentionDays": 5
"RetentionDays": 30
},
"EventLog": {
"Enabled": true,
@@ -158,6 +158,23 @@ namespace HostAvailabilityMonitor.Configuration
Runtime.MaxConcurrency = 1;
}
if (string.IsNullOrWhiteSpace(Runtime.StateDirectory))
{
Runtime.StateDirectory = "state";
}
if (string.IsNullOrWhiteSpace(Runtime.StateFileName))
{
Runtime.StateFileName = "monitor-state.json";
}
if (Path.IsPathRooted(Runtime.StateFileName)
|| Runtime.StateFileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0
|| Runtime.StateFileName.IndexOfAny(new[] { '\\', '/' }) >= 0)
{
throw new InvalidOperationException("Runtime.StateFileName muss ein Dateiname ohne Pfadanteile sein.");
}
if (HipVirtualMachines == null)
{
HipVirtualMachines = new HipVirtualMachineOptions();
@@ -286,6 +303,11 @@ namespace HostAvailabilityMonitor.Configuration
/// Gets or sets the state directory path.
/// </summary>
public string StateDirectory { get; set; } = "state";
/// <summary>
/// Gets or sets the state file name inside the configured state directory.
/// </summary>
public string StateFileName { get; set; } = "monitor-state.json";
}
/// <summary>
@@ -306,7 +328,7 @@ namespace HostAvailabilityMonitor.Configuration
/// <summary>
/// Gets or sets the number of daily log files to retain.
/// </summary>
public int RetentionDays { get; set; } = 5;
public int RetentionDays { get; set; } = 30;
}
/// <summary>
+2 -2
View File
@@ -58,7 +58,7 @@ namespace HostAvailabilityMonitor
var logDirectory = ResolvePath(baseDirectory, config.Logging.LogDirectory);
var stateDirectory = ResolvePath(baseDirectory, config.Runtime.StateDirectory);
var stateFilePath = Path.Combine(stateDirectory, "monitor-state.json");
var stateFilePath = Path.Combine(stateDirectory, config.Runtime.StateFileName);
WriteConsoleInfo("Initialisiere Dateilog: " + BuildLogFilePreview(logDirectory, config.Logging.FilePrefix));
logger = new FileLogger(logDirectory, config.Logging.FilePrefix, config.Logging.RetentionDays, config.ApplicationName, config.EnvironmentName);
@@ -699,7 +699,7 @@ namespace HostAvailabilityMonitor
try
{
var directory = ResolvePath(baseDirectory ?? AppDomain.CurrentDomain.BaseDirectory, "logs");
var fallbackLogger = new FileLogger(directory, "host-availability-monitor-startup", 5, "HostAvailabilityMonitor", "Startup");
var fallbackLogger = new FileLogger(directory, "host-availability-monitor-startup", 30, "HostAvailabilityMonitor", "Startup");
fallbackLogger.Error("Monitor konnte nicht gestartet werden. Konfiguration=" + (configPath ?? "(nicht aufgeloest)") + ". Fehler=" + exception.GetType().Name + ": " + exception.Message);
fallbackLogger.Error("Details: " + exception);
WriteConsoleInfo("Fallback-Log geschrieben: " + BuildLogFilePreview(directory, "host-availability-monitor-startup"));
+3 -2
View File
@@ -6,12 +6,13 @@
"DefaultValidateUncPathAccess": false,
"NonZeroExitCodeOnAnyFailure": false,
"NonZeroExitCodeOnExecutionError": true,
"StateDirectory": "state"
"StateDirectory": "state",
"StateFileName": "monitor-state.json"
},
"Logging": {
"LogDirectory": "logs",
"FilePrefix": "host-availability-monitor",
"RetentionDays": 5
"RetentionDays": 30
},
"EventLog": {
"Enabled": true,