Become a member!

ExeWatch 1.8: .NET SDK für WPF und WinForms, Custom Metrics, Health Monitoring und On Premise

ExeWatch Logo
🌐
Dieser Artikel ist auch in anderen Sprachen verfügbar:
🇬🇧 English  •  🇮🇹 Italiano  •  🇪🇸 Español

TL;DR: ExeWatch 1.8 ist ein wichtiger Schritt: das .NET/C# SDK (WPF, WinForms, Services), Custom Metrics mit Zeitreihengrafiken, automatisches Health Monitoring mit Benachrichtigungen, schreibgeschütztes Application Sharing und — auf Anfrage mehrerer Unternehmen — die Möglichkeit zum On-Premise-Deployment. Jetzt testen auf exewatch.com


ExeWatch über die Delphi-Welt hinaus

Als ich ExeWatch zum ersten Mal vorstellte, beschrieb ich es als Monitoring-Tool für Delphi-Anwendungen. Das stimmte, war aber nur ein Teil des Bildes. Die Grundlagen, die ExeWatch bietet — strukturiertes Logging, Timing, Breadcrumbs, Device Info, Anomaly Detection — sind nicht sprachspezifisch. Es sind universelle Anforderungen für jeden, der Software entwickelt, die “außerhalb des Browsers” läuft, wo Produktionslogs historisch schwer zu bekommen waren.

In den letzten Wochen erhielten wir konkrete Anfragen von Teams, die in C# entwickeln und etwas mit den gleichen Eigenschaften wie ExeWatch, aber für die .NET-Welt suchten. Keine generischen APM-Tools für Cloud-Microservices, sondern etwas Gezieltes für Desktop-Anwendungen, Windows-Dienste, WPF und WinForms.

Anstatt zu sagen “das ist nicht unsere Zielgruppe”, haben wir das SDK geschrieben.

.NET / C# SDK

Das .NET SDK ist jetzt mit Feature Parity zum Delphi SDK verfügbar. Es unterstützt .NET 8.0+ unter Windows und deckt alle gängigen Szenarien ab:

  • Console, WPF, WinForms, Windows Service — ein einziges Basispaket, plus ein optionaler WinForms-Hook (ExeWatch.WinForms), der UI-Thread-Exceptions abfängt
  • Null NuGet-Abhängigkeiten — wie beim Delphi SDK, keine externen Abhängigkeiten
  • Gleiche API — wer das Delphi SDK kennt, fühlt sich sofort zuhause
  • Offline Persistence — Logs werden vor dem Versand auf der Festplatte gespeichert, mit automatischem Retry
  • Serverseitige Konfiguration — Flush Interval, Batch Size und Sampling Rate steuerbar vom Dashboard ohne die Anwendung neu zu verteilen

Die Initialisierung ist identisch mit Delphi:

using ExeWatch;

ExeWatchSdk.Initialize(new ExeWatchConfig
{
    ApiKey = "ew_win_your_key",
    CustomerId = "ACME-Corp"
});

EW.Info("Application started", "startup");

Ab diesem Zeitpunkt ist die API dieselbe. Timing, Breadcrumbs, Metriken:

// Timing mit Kategorie
EW.StartTiming("invoice.generate", "pdf");
// ... PDF generieren ...
EW.EndTiming("invoice.generate");

// Breadcrumb zur Nachverfolgung des Benutzerpfads
EW.AddBreadcrumb("Clicked Export", "ui");

// Counter und Gauge
EW.IncrementCounter("invoices.generated", 1);
EW.RecordGauge("queue.size", pendingJobs.Count);

Für WinForms genügt eine Zeile, um UI-Thread-Exceptions abzufangen:

using ExeWatch;
using ExeWatch.WinForms;

ExeWatchSdk.Initialize(config);
ExeWatchWinForms.Install();  // fängt Application.ThreadException ab

Das Beispiel-Repository enthält drei vollständige .NET-Samples: eine Console App, eine interaktive WinForms-Anwendung und einen Windows Service.

Custom Metrics

Bis zur vorherigen Version sammelte ExeWatch Metriken (Counter und Gauge), zeigte sie aber nur als aggregierte Werte an. Mit 1.8 haben Metriken eine eigene Seite mit Zeitreihengrafiken.

In der Praxis bedeutet das: Du kannst domänenspezifische Größen tracken und sie zeitlich neben Logs und Timings visualisieren:

// Delphi — Business-Metriken tracken
EW.IncrementCounter('orders.processed', 1);
EW.IncrementCounter('orders.failed', 1);
EW.RecordGauge('queue.pending', FPendingQueue.Count);

// Periodischer Gauge — automatisch alle 30 Sekunden abgetastet
EW.RegisterPeriodicGauge('memory_mb',
  function: Double
  begin
    Result := GetCurrentMemoryMB;
  end);
// C# — gleiche API
EW.IncrementCounter("orders.processed", 1);
EW.RecordGauge("connections.active", pool.ActiveCount);

Auf der Metrics-Seite können auch die Daten einer bestimmten Metrik direkt über das Detail-Modal gelöscht werden — nützlich während der Entwicklung oder zum Bereinigen von Testdaten.

Health Monitoring

Eine der häufigsten Fragen, die wir erhielten, war: “Wie erfahre ich, ob meine Anwendung gut läuft, ohne alle 5 Minuten das Dashboard zu prüfen?”

Die Antwort ist Health Monitoring. Jede Anwendung hat jetzt einen Health Score, der automatisch anhand von drei Parametern berechnet wird: Fehlerrate, Abstürze und langsame Operationen der letzten 24 Stunden. Der resultierende Status ist einer von Healthy, Degraded oder Unhealthy.

Das System enthält eine Anti-Flapping-Logik: Ein einzelner Fehler reicht nicht aus, um einen Statuswechsel auszulösen. Das verhindert unnötige Benachrichtigungen und reduziert Rauschen.

Wenn sich der Gesundheitsstatus ändert, sendet ExeWatch Benachrichtigungen per E-Mail und, falls konfiguriert, per Discord über Webhooks. Discord wurde hinzugefügt, weil viele Teams es als operativen Kanal nutzen und Benachrichtigungen dort erhalten möchten, wo sie bereits arbeiten.

Der Detailgrad des Health Monitorings hängt vom Plan ab: Der Hobby-Plan bietet Basis-Monitoring, Pro fügt fehlerbasiertes Monitoring hinzu, Business umfasst die vollständige Analyse mit Timing und Trends.

Application Sharing

Ein Feature, das wir nicht geplant hatten, das aber von mehreren Nutzern angefragt wurde: die Möglichkeit, eine Anwendung im Nur-Lesen-Modus mit externen Nutzern zu teilen.

Das typische Szenario: Du hast einen Kunden, der den Status seiner Installation sehen möchte, ohne dass du ihm Screenshots oder periodische Reports schicken musst. Mit dem Read-Only-Sharing gibst du ihm direkten Zugriff auf das Dashboard seiner Anwendung — Logs, Timing, Health — ohne Änderungsrechte oder Zugriff auf andere Anwendungen des Kontos zu gewähren.

DMVCFramework-Integration

Für Entwickler von Serveranwendungen mit DMVCFramework haben wir ein vollständiges Sample veröffentlicht, das zeigt, wie ExeWatch in eine TemplatePro + HTMX-Webanwendung integriert wird.

Die Integration nutzt zwei Mechanismen, die DMVCFramework nativ bietet. Der erste ist der LoggerPro Callback Appender: Alle LogI, LogW, LogE-Aufrufe des Frameworks — einschließlich der internen — werden automatisch an ExeWatch weitergeleitet.

SetDefaultLogger(
  CreateLogBuilderWithDefaultConfiguration
    .WriteToCallback
    .WithCallback(
      procedure(const ALogItem: TLogItem; const AFormattedMessage: string)
      begin
        if ExeWatchIsInitialized and (ALogItem.LogType > TLogType.Debug) then
          EW.Log(
            TEWLogLevel(Ord(ALogItem.LogType)),
            ALogItem.LogMessage,
            ALogItem.LogTag,
            ALogItem.TimeStamp,
            ALogItem.ThreadID);
      end).Done.Build);

Der zweite ist der integrierte Profiler von DMVCFramework. Da der Logger bereits mit ExeWatch verbunden ist, wird das Timing jeder Controller-Action automatisch erfasst:

Profiler.ProfileLogger := Log;
Profiler.WarningThreshold := 500;           // Warnung wenn Action > 500ms
Profiler.LogsOnlyIfOverThreshold := False;  // immer loggen, nicht nur die langsamen

Mit diesen wenigen Zeilen in der .dpr ist die gesamte Anwendung überwacht, ohne die Controller zu ändern. Das Sample zeigt dann die erweiterten Funktionen dort, wo sie wirklich Mehrwert bieten — zum Beispiel strukturierte Extra-Daten, wenn ein Batch-Import teilweise fehlschlägt:

// Jede fehlgeschlagene Zeile wird mit strukturiertem Kontext geloggt
LRowExtra := TJSONObject.Create;
LRowExtra.AddPair('row_number', TJSONNumber.Create(I + 1));
LRowExtra.AddPair('first_name', LFirstName);
LRowExtra.AddPair('last_name', LLastName);
LRowExtra.AddPair('error', LReason);
EW.Log(llWarning, Format('Import failed for row %d: %s %s (%s)',
  [I + 1, LFirstName, LLastName, LReason]), 'people', LRowExtra);

// Die Zusammenfassung enthält das vollständige Array der fehlgeschlagenen Zeilen
LExtra := TJSONObject.Create;
LExtra.AddPair('total_rows', TJSONNumber.Create(10));
LExtra.AddPair('imported', TJSONNumber.Create(LImported));
LExtra.AddPair('failed', TJSONNumber.Create(LFailed));
LExtra.AddPair('failed_rows', LFailedRows);  // TJSONArray mit Details
EW.Log(llWarning, 'Batch import: 7 imported, 3 failed', 'people', LExtra);

Öffnet man den Log im ExeWatch-Dashboard, sind die Extra-Daten in strukturiertem Format sichtbar — keine Textnachricht mehr zum Interpretieren, sondern navigierbare Daten.

Öffentliches Repository mit allen Beispielen

Wir haben ein GitHub-Repository mit Integrationsbeispielen für alle SDKs und verschiedene Anwendungstypen veröffentlicht: github.com/danieleteti/ExeWatchSamples.

Sample Typ Was es zeigt
Delphi VCL Windows Desktop Logging, Timing, Breadcrumbs, User Identity, Tags, Metriken, VCL-Exception-Erfassung
Delphi WebBroker REST Server Automatisches HTTP-Request-Timing, Error Tracking, Counter
Delphi DMVCFramework Web-App (TemplatePro + HTMX) LoggerPro + Profiler-Integration, CRUD, Nested Timing, Extra Data
.NET Console Console App Alle Features mit getimten Iterationen und zufälligen Fehlern
.NET WinForms Windows Desktop Interaktive GUI, API Key zur Laufzeit, verschachtelte Timings, Metriken
.NET Windows Service Windows-Dienst Processing-Zyklus, Nested Timing, Counter, Gauge, sauberes Shutdown
JavaScript Browser Einzelne HTML-Seite, SDK per CDN, keine Build-Tools

Jedes Beispiel enthält ein detailliertes README und kann in wenigen Minuten kompiliert und gestartet werden. Die API ist bewusst einheitlich über alle SDKs hinweg, sodass der Wechsel zwischen Sprachen nahtlos ist:

// Delphi
EW.Info('User logged in', 'auth');
EW.StartTiming('db.query', 'database');
EW.AddBreadcrumb('Search: "invoice 2024"', 'search');
// C# — gleiche Struktur
EW.Info("User logged in", "auth");
EW.StartTiming("db.query", "database");
EW.AddBreadcrumb("Search: \"invoice 2024\"", "search");
// JavaScript — gleiche Struktur
ew.info("User logged in", "auth");
ew.startTiming("db.query", "database");
ew.addBreadcrumb("Search: \"invoice 2024\"", "search");

On Premise

Mehrere Unternehmen haben uns kontaktiert, um zu fragen, ob es möglich sei, ExeWatch in der eigenen Infrastruktur zu installieren. Die Gründe sind vorhersehbar: Unternehmensrichtlinien, die das Senden von Telemetriedaten an externe Dienste verbieten, branchenspezifische Compliance-Anforderungen, Latenzanforderungen oder einfach die Präferenz für direkte Infrastrukturkontrolle.

Wir haben die On Premise-Option auf der Pricing-Seite hinzugefügt. Es ist kein Self-Service-Plan: Eine direkte Verhandlung ist erforderlich, da jede Installation unterschiedliche Anforderungen in Bezug auf Sizing, Backup, Updates und Support hat. Interessenten können uns unter exewatch@bittime.it kontaktieren.

Webinar und ITDevCon

Am 24. März um 15:00 Uhr MEZ werde ich ein Webinar zu ExeWatch und Delphi-VCL-Anwendungen halten. Nach dem ersten Einführungsvideo auf Englisch wird dieses auf Italienisch sein und sich an Delphi-Desktop-Entwickler richten. Wir gehen die Integration Schritt für Schritt durch, zeigen die erweiterten Funktionen und wie man das Dashboard optimal nutzt. Webinare auf Englisch und Spanisch folgen in Kürze.

Zur Anmeldung: ExeWatch Webinar-Registrierung

Auf der kommenden ITDevCon 2026 Spring Edition (auf Italienisch) werde ich einen Vortrag über ExeWatch halten, in dem ich Integrationen und erweiterte Funktionen im Detail behandle — die Art von Features, auf die man nicht mehr verzichten möchte, wenn man sie einmal entdeckt hat.

Was kommt als Nächstes

Die Arbeit geht an zwei Fronten weiter. Im Backend verbessern wir die Anomaly Detection, um sie granularer zu machen. Auf der SDK-Seite ist der nächste Kandidat Python — viele Desktop-Anwendungen nutzen PyQt oder Tkinter und haben die gleichen Monitoring-Anforderungen.

Wenn du ExeWatch bereits nutzt, sind alle 1.8-Neuerungen bereits in deinem Konto verfügbar. Wenn du es noch nicht ausprobiert hast: Der Hobby-Plan ist kostenlos und erfordert keine Kreditkarte.



ExeWatch — Monitoring für Server-, Desktop- und Webanwendungen. Entwickelt von bit Time Professionals.

Comments

comments powered by Disqus