Betrieb und Wartung
Dieser Abschnitt beschreibt den laufenden Betrieb und die Wartung des MesoWorkerService.
Manuelles Datenbank-Update (optional)
Das manuelle Datenbank-Update ist nur in Sonderfällen erforderlich, z.B. wenn Sie die Datenbank explizit aktualisieren möchten, ohne den Service zu starten.
Windows:
MesoWorker.Win.exe -updateDatabase -silent
Container:
docker run --rm \
-e ConnectionStrings__ConnectionString="Data Source=SQL-SERVER;Initial Catalog=MesoWorkerDb;User ID=sql-user;Password=***;TrustServerCertificate=true" \
-e ConnectionStrings__WinLineSystemDBConnectionString="Data Source=SQL-SERVER;Initial Catalog=CWLSYSTEM;User ID=sql-user;Password=***;TrustServerCertificate=true" \
ghcr.io/css-edv-support/mesoworkerservice-blazor:latest \
-updateDatabase -forceUpdate -silent
Parameter:
-updateDatabase- Startet den Datenbankaktualisierungsmodus-forceUpdate- Erzwingt Update auch wenn Versionen übereinstimmen (optional)-silent- Keine Benutzerinteraktion erforderlich (optional)
Exit Codes: 0 = Erfolgreich, 1 = Fehler, 2 = Update nicht erforderlich
Mail-Journal
Das Mail-Journal protokolliert alle versendeten und fehlgeschlagenen E-Mails.
Informationen im Journal:
- Zeitstempel des Versands/Fehlers
- Empfänger (To, CC, BCC)
- Betreff
- Status (versendet, fehlgeschlagen, wartend)
- Fehlermeldungen (bei fehlgeschlagenen E-Mails)
- Verknüpfter Workflow
Verwendung:
- Überprüfen Sie regelmäßig das Journal auf fehlgeschlagene E-Mails
- Analysieren Sie Fehlermeldungen bei Problemen
- Überwachen Sie die Zustellungsrate
Fehlerbenachrichtigungen
Der Service benachrichtigt Administratoren automatisch bei Problemen.
Benachrichtigungsfälle:
- E-Mail konnte nicht versendet werden
- SMTP-Server ist nicht erreichbar
- Authentifizierung fehlgeschlagen
- Lizenz ist ungültig oder abgelaufen
Protokollierung
Der Service erstellt detaillierte Protokolldateien für Diagnose und Überwachung.
Protokolldateien:
- Windows-Dienst:
logs/MESOWorkerService-[Datum].txtim Programmverzeichnis (bei bestehenden Installationen heißt der Ordner nochLogs, unter Windows ist das gleichbedeutend) - Container: zweifach – die Konsolenausgabe landet im Docker-Log (
docker logs mesoworkerservice, in Portainer unter Logs), zusätzlich schreibt der Worker dieselben Meldungen als Dateien nach/app/logs. Die Web-UI schreibt nur ins Docker-Log
Obergrenzen (NEU): Beide Wege sind ab dieser Version begrenzt, damit kein Datenträger mehr vollläuft:
| Weg | Standardgrenze | Wo einstellbar |
|---|---|---|
| Protokolldateien des Workers | 14 Dateien × 50 MB = max. 700 MB; täglich neue Datei, bei 50 MB wird zusätzlich gerollt | Serilog:WriteTo:1:Args in appsettings.json bzw. Serilog__WriteTo__1__Args__* als Umgebungsvariable |
| Docker-Log je Container | 3 × 10 MB = max. 30 MB | logging:-Block im Stack (siehe Stack-Vorlage) |
Ältere Installationen hatten diese Grenzen nicht: Docker rotiert den Standardtreiber json-file von sich aus nicht, und die Protokolldateien behielten bis zu 31 Tage mit je bis zu 1 GB. Prüfen Sie bei bestehenden Stacks, ob der logging:-Block vorhanden ist, und ergänzen Sie ihn gegebenenfalls. Als Rückfallnetz für alle Container eines Hosts kann die Rotation auch global in /etc/docker/daemon.json gesetzt werden (siehe Ressourcenempfehlung); sie gilt dann für neu erstellte Container.
Hinweis für Container: Im Container muss der Dateipfad /app/logs/… lauten (Kleinschreibung), weil Linux zwischen logs und Logs unterscheidet. Ein abweichender Pfad schreibt in die Container-Schicht statt ins Volume oder scheitert stillschweigend an fehlenden Schreibrechten.
Protokollierungsstufen:
- Information: Normale Betriebsmeldungen
- Warning: Warnungen (z.B. fehlende Empfänger)
- Error: Fehler (z.B. Datenbankverbindung fehlgeschlagen)
- Debug: Detaillierte Debug-Informationen (nur für Fehlersuche)
Konfiguration:
Der Worker protokolliert über Serilog. Die Stufen stehen deshalb im Abschnitt Serilog:MinimumLevel der appsettings.json, nicht unter Logging:LogLevel – Einträge dort haben für den Worker keine Wirkung:
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"Microsoft.AspNetCore": "Warning",
"System": "Warning"
}
}
}
Als Umgebungsvariable im Stack: Serilog__MinimumLevel__Default=Information, Serilog__MinimumLevel__Override__Quartz=Warning usw. Die Stufe Microsoft.AspNetCore steht standardmäßig auf Warning, damit die regelmäßigen Health-Check-Aufrufe das Protokoll nicht füllen.
Die Web-UI verwendet dagegen den Abschnitt Logging:LogLevel (bzw. Logging__LogLevel__*).
Best Practices:
- Überprüfen Sie Protokolle regelmäßig auf Fehler und Warnungen
- Behalten Sie "Information" als Standard-Protokollierungsstufe
- Verwenden Sie "Debug" nur zur Fehlersuche (erzeugt viele Einträge) und stellen Sie danach zurück – mit "Debug" sind die Obergrenzen schnell erreicht und ältere Einträge gehen verloren
- Archivieren Sie Protokolldateien, die Sie länger als 14 Tage aufbewahren möchten, rechtzeitig an einen anderen Ort
SMTP-Debug-Modus
Der SMTP-Debug-Modus ermöglicht eine detaillierte Diagnose des E-Mail-Versands. Bei Aktivierung werden alle ausgehenden E-Mails mit erweiterten Informationen protokolliert und optional als EML-Dateien gespeichert.
Funktionsumfang:
- Detaillierte Protokollierung aller E-Mail-Details (Absender, Empfänger, Betreff, SMTP-Konto-Informationen)
- Optionales Speichern jeder ausgehenden E-Mail als
.eml-Datei zur Analyse - Bestätigungsprotokollierung nach erfolgreichem Versand
Konfigurationsparameter:
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
Enabled |
bool | false |
Aktiviert/Deaktiviert den SMTP-Debug-Modus |
SaveEmlToDirectory |
string | "" |
Verzeichnispfad zum Speichern von EML-Dateien. Leer = kein Speichern |
Konfiguration in appsettings.json (Windows-Dienst):
"SmtpDebug": {
"Enabled": true,
"SaveEmlToDirectory": "C:\\Temp\\MailDebug"
}
Konfiguration als Umgebungsvariablen (Portainer Stack / Docker):
environment:
# SMTP-Debug-Modus aktivieren
- SmtpDebug__Enabled=true
# Optional: EML-Dateien im Container speichern
- SmtpDebug__SaveEmlToDirectory=/app/debug-mails
Wenn EML-Dateien im Container gespeichert werden sollen, muss ein Volume gemappt werden, damit die Dateien auch nach einem Container-Neustart verfügbar bleiben:
services:
mesoworkerservice:
environment:
- SmtpDebug__Enabled=true
- SmtpDebug__SaveEmlToDirectory=/app/debug-mails
volumes:
- type: bind
source: //server/share/debug-mails # Pfad auf dem Host
target: /app/debug-mails
Protokollausgabe bei aktiviertem Debug-Modus:
Die Protokolleinträge werden mit dem Prefix [SMTP-DEBUG] auf der Stufe Warning geschrieben und enthalten:
- SMTP-Konto-Details (EmailFrom, Host, Port, SSL/TLS-Einstellungen)
- Absender- und Empfänger-Adressen (To, CC, BCC)
- Betreff der E-Mail
- Anzahl der Empfänger pro Typ
- Pfad der gespeicherten EML-Datei (wenn
SaveEmlToDirectorykonfiguriert)
Beispiel einer Protokollausgabe:
[SMTP-DEBUG] === Mail wird gesendet ===
SMTP-Account: [email protected], Host=smtp.firma.de, Port=587, SSL=False, StartTLS=True
From: [email protected]
To: [email protected]
CC: (keine)
BCC: [email protected]
Subject: Bestellbestätigung REF-2024-001
BCC-Count: 1 | To-Count: 1 | CC-Count: 0
[SMTP-DEBUG] EML gespeichert: /app/debug-mails/debug_20260217_143022_a1b2c3d4.eml
[SMTP-DEBUG] Mail erfolgreich gesendet via [email protected]: Subject="Bestellbestätigung REF-2024-001"
Wichtige Hinweise:
- Der Debug-Modus sollte nur temporär zur Fehlerdiagnose aktiviert werden
- Die Protokollierung erfolgt auf Stufe
Warning, um auch bei Standard-Protokollierungsstufe sichtbar zu sein - Bei aktiviertem
SaveEmlToDirectorywerden alle ausgehenden E-Mails als Dateien gespeichert — achten Sie auf den Speicherplatz - EML-Dateien können mit jedem E-Mail-Client (z.B. Outlook, Thunderbird) geöffnet und analysiert werden
- Im Container-Betrieb ohne Volume-Mapping gehen gespeicherte EML-Dateien bei Container-Neustart verloren
Wartungsaufgaben
Regelmäßige Aufgaben:
-
Mail-Journal prüfen (täglich)
- Überprüfen Sie fehlgeschlagene E-Mails
- Analysieren Sie Trends bei Fehlern
-
Stammdaten pflegen (wöchentlich)
- Aktualisieren Sie E-Mail-Adressen von Kunden
- Überprüfen Sie Ansprechpartner-Daten
-
SMTP-Konten überwachen (wöchentlich)
- Testen Sie SMTP-Verbindungen
- Überprüfen Sie OAuth-Token (M365)
-
Protokolldateien prüfen (wöchentlich)
- Suchen Sie nach wiederkehrenden Fehlern
- Überprüfen Sie Performance-Warnungen
-
Service-Status überwachen (täglich)
- Health-Check-Endpoint aufrufen:
http://server:5000/health - Windows-Dienst-Status prüfen
- Health-Check-Endpoint aufrufen:
-
Updates einspielen (nach Bedarf)
- Neue Container-Images deployen
- Windows-Dienst aktualisieren
- Konfigurationsänderungen testen
Troubleshooting:
Problem: E-Mails werden nicht versendet
- Überprüfen Sie Mail-Journal auf Fehler
- Prüfen Sie SMTP-Konto-Einstellungen
- Testen Sie SMTP-Server-Erreichbarkeit
- Überprüfen Sie Workflow-Filter-Einstellungen
Problem: Keine Empfänger gefunden
- Überprüfen Sie Kundenstamm-Daten (E-Mail-Adressen)
- Prüfen Sie Empfängerregeln in Mail-Einstellungen
- Überprüfen Sie Ansprechpartner-Zuweisungen
Problem: Service startet nicht
- Überprüfen Sie Lizenz-Einstellungen
- Prüfen Sie Datenbankverbindungen
- Kontrollieren Sie Protokolldateien
Mehrere Instanzen
Der WorkerService darf mehrfach gegen dieselbe Datenbank laufen. Eine Anwendungssperre in der Datenbank stellt sicher, dass jeder Job je Fälligkeit nur auf einer Instanz läuft; die übrigen Instanzen überspringen den Lauf und protokollieren das mit dem Wortlaut <Job> laeuft bereits auf einer anderen Instanz — Lauf uebersprungen. Wer sich fragt, warum ein Job auf einer Instanz „nichts tut", sucht zuerst nach dieser Meldung.
Was die Sperre leistet: Keine doppelten Mails, keine doppelten Buchungsstapel, keine doppelten Berichtsdateien. Fällt eine Instanz aus, übernimmt die andere beim nächsten Turnus.
Was sie nicht leistet: Ein übersprungener Lauf wird nicht nachgeholt. Nach einem harten Absturz kann die Sperre bis zu etwa einer Minute stehen bleiben, bis SQL Server die abgebrochene Verbindung bemerkt — der nächste Turnus holt das auf.
Lange Läufe: Die Sperre hängt an einer Datenbankverbindung, die für die Dauer des Laufs offen bleibt und dabei ungenutzt ist. Reißt diese Verbindung ab — durch ein Leerlauf-Zeitlimit einer Firewall, ein NAT-Gerät oder ein SQL-Server-Failover —, gibt SQL Server die Sperre frei, während der Job weiterläuft. Eine zweite Instanz könnte denselben Job dann parallel starten. Das System bemerkt das nicht und protokolliert es nicht. Für die üblichen Läufe im Sekundenbereich ist das ohne Bedeutung; relevant wird es bei Berichts- oder Banking-Läufen, die viele Minuten dauern. Wer solche Läufe im Mehrinstanzbetrieb fährt, sollte das Leerlauf-Zeitlimit auf dem Weg zur Datenbank prüfen.
Ausnahme — Sofort-Anstoss per HTTP: Die Zusage "keine doppelten Mails, keine doppelten Buchungsstapel" gilt nur für zeitgesteuerte Läufe über Quartz. Der manuelle Sofort-Anstoss POST /banking/trigger (ebenso /banking/rematch) läuft an Quartz vorbei — er führt seine Arbeit per Task.Run in einem eigenen Scope aus, ohne den VetoJobExecution-Haken der Laufsperre zu durchlaufen. Wird dieser Endpoint auf mehreren Instanzen gleichzeitig aufgerufen, sind doppelte Buchungsstapel weiterhin möglich.
Docker Compose: Die mitgelieferte docker-compose.portainer.yml ist trotz der Sperre auf Einzelbetrieb zugeschnitten — sie bindet einen festen Host-Port (${SERVICE_PORT:-5000}:5000) und ein gemeinsames Log-Volume. Die Sperre selbst erlaubt Mehrinstanzbetrieb; ein zweiter Container braucht dafür aber eine eigene Portbindung und ein eigenes Log-Volume (eigene Compose-Datei oder zweiter Dienst) — deploy.replicas: 2 allein reicht nicht.
Wenn die Sperre nicht auswertbar ist: Ist die Datenbank nicht erreichbar oder schlägt die Sperranfrage fehl, lässt das System den Job-Lauf zu, anstatt ihn zu blockieren. Der Grund: In der weit überwiegenden Zahl der Installationen läuft ohnehin nur eine einzige Instanz — dort wäre ein Blockieren bei nicht auswertbarer Sperre ein Ausfall des Jobs, ein Durchlassen bleibt dagegen folgenlos. Nur im Mehrinstanzbetrieb bedeutet dieser Zustand, dass für diesen Lauf wieder mehrere Instanzen parallel arbeiten können. Erkennbar ist er an einer Warnung im Log mit dem Wortlaut Laufsperre fuer {Job} nicht auswertbar — Lauf wird zugelassen..
Konfiguration: Abschalten mit "JobRunLock": { "Enabled": false }. Ohne konfigurierten ConnectionStrings:ConnectionString ist die Sperre wirkungslos und meldet das beim Start.
Den aktuellen Zustand zeigt der Health-Check-Endpoint GET /health/detailed im Abschnitt JobRunLocks.
HTTP-Schnittstelle und API-Schlüssel
Der Worker-Dienst bietet auf seinem Port (Standard 5000) einige HTTP-Endpunkte für Überwachung und Automatisierung. Alle Funktionen stehen auch in der Web-UI zur Verfügung; die Endpunkte sind ein Zusatz für Monitoring-Systeme und Skripte.
API-Schlüssel (ApiAuth:Key): Geschützte Endpunkte erwarten den Schlüssel im HTTP-Header X-Api-Key. Fehlt der Header oder stimmt der Wert nicht, antwortet der Dienst mit 401 Unauthorized.
Achtung – ohne Schlüssel sind die Endpunkte offen. Ist
ApiAuth:Keynicht konfiguriert, lässt der Dienst aus Gründen der Abwärtskompatibilität jede Anfrage durch. Damit kann jeder, der den Port erreicht, Banking-Läufe anstoßen, Mails aus CRM-Fällen versenden und Protokollzeilen abrufen. Setzen Sie den Schlüssel deshalb bei jeder Installation, deren Port über den lokalen Rechner hinaus erreichbar ist, und geben Sie den Port in der Firewall nur für die Systeme frei, die ihn benötigen.
Konfiguration in der appsettings.json bzw. als Umgebungsvariable ApiAuth__Key:
"ApiAuth": {
"Key": "langer-zufaelliger-wert"
}
Aufruf mit Schlüssel:
curl -H "X-Api-Key: langer-zufaelliger-wert" http://IHR-SERVER:5000/health/detailed
Endpunkte:
| Endpunkt | Schlüssel nötig | Zweck |
|---|---|---|
GET /health |
nein | Basis-Zustand für Container-Healthchecks und Monitoring. Antwort Healthy, Degraded (Lizenz fehlt) oder Unhealthy (HTTP 503 bzw. 500) |
GET /health/detailed |
ja | Erweiterter Zustand: Lizenz, vorhandene Verbindungszeichenfolgen, Scheduler-Zustand mit allen Jobs und deren letzter und nächster Ausführung, Laufsperren (JobRunLocks), Laufzeitumgebung |
GET /health/logs |
ja | Die letzten 100 Zeilen der aktuellsten Protokolldatei aus /app/logs (nur Container-Betrieb) |
POST /banking/trigger |
ja | Stößt den Banking-Lauf sofort an (Kontoabruf, Zuordnung, Buchung). Läuft an der Laufsperre vorbei, siehe Mehrere Instanzen |
POST /banking/rematch |
ja | Wiederholt die Zuordnung noch nicht zugeordneter Transaktionen. Body optional: JournalIds (Liste von Transaktions-IDs, leer = alle offenen) und IncludeLlm (true oder leer = vollständige Zuordnung inkl. OP-Suche, Buchungsregeln und KI, false = nur Buchungsregeln) |
POST /banking/lernmodus |
ja | Startet die Lernmodus-Analyse für ein Bankkonto, siehe Lernmodus |
GET /api/Mail/incidence/{Mandant}/{Fall-ID} |
ja | Versendet die für einen einzelnen CRM-Fall konfigurierten E-Mails sofort, ohne auf den nächsten Turnus des Mail-Dienstes zu warten. Mandant ist die vierstellige Mandantennummer |
Die Web-UI (Port 8012 in der Stack-Vorlage) hat keine dieser Endpunkte; ihr Zugriff ist über die Benutzeranmeldung geschützt.
Keine Kommentare vorhanden
Keine Kommentare vorhanden