Ein Logging “Framework” für MSSQL

Eine umfassende Protokollierungslösung für SQL Server Stored Procedures, die strukturiertes Logging mit verschiedenen Schwerelevels, automatischer Erkennung des aufrufenden Procedures und detaillierter Fehlerverfolgung bietet.

Funktionen

  • Mehrere Schweregrade: DEBUG, INFO, WARNING und ERROR Level Logging
  • Automatische Aufrufererkennung: Erkennt automatisch die aufrufende Stored Procedure
  • Strukturierte Protokollierung: Einheitliches Protokollformat mit Zeitstempel, Schweregrad und Kontext
  • Fehlerdetails: Umfassende Fehlerinformationen für Debugging
  • Schema-Organisation: Alle Komponenten sind in einem dedizierten ‘Logger’-Schema organisiert
  • Performance-Optimiert: Enthält entsprechende Indizes für effiziente Protokollabfragen

Installation

  1. Führen Sie das Installationsskript in Ihrer Datenbank aus:
-- Logger-Schema erstellen
CREATE SCHEMA Logger;
GO

-- Logging-Tabelle und Prozeduren erstellen
-- [Hier das vollständige Installationsskript einfügen]

Grundlegende Verwendung

Einfache Protokollierung

-- Info-Logging
EXEC Logger.Info
    @EventType = 'PROZESS_START',
    @Message = 'Starte Datenimport-Prozess';

-- Warnung-Logging
EXEC Logger.Warn
    @EventType = 'DATEN_VALIDIERUNG',
    @Message = 'Optionale Felder fehlen';

-- Fehler-Logging
EXEC Logger.Error
    @EventType = 'PROZESS_FEHLER',
    @Message = 'Aktualisierung der Datensätze fehlgeschlagen',
    @IncludeErrorDetails = 1;

-- Debug-Logging
EXEC Logger.Debug
    @EventType = 'DETAIL_INFO',
    @Message = 'Verarbeite Batch 123',
    @AdditionalInfo = 'Batch-Größe: 500 Datensätze';

Integrations-Beispiel

CREATE PROCEDURE dbo.DatenImport
    @BatchId INT,
    @EnableDebug BIT = 0
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @StartZeit DATETIME = GETDATE();

    -- Start protokollieren
    EXEC Logger.Info
        @EventType = 'IMPORT_START',
        @Message = 'Starte Import-Prozess',
        @AdditionalInfo = CONCAT('BatchId: ', @BatchId);

    BEGIN TRY
        -- Debug-Protokollierung (falls aktiviert)
        IF @EnableDebug = 1
        BEGIN
            EXEC Logger.Debug
                @EventType = 'IMPORT_DETAIL',
                @Message = 'Validiere Batch-Daten';
        END

        -- Ihre Import-Logik hier

        -- Abschluss protokollieren
        EXEC Logger.Info
            @EventType = 'IMPORT_ABGESCHLOSSEN',
            @Message = 'Import-Prozess abgeschlossen',
            @AdditionalInfo = CONCAT(
                'BatchId: ', @BatchId, 
                ', Dauer: ', 
                DATEDIFF(MILLISECOND, @StartZeit, GETDATE()), 'ms'
            );
    END TRY
    BEGIN CATCH
        -- Fehler protokollieren
        EXEC Logger.Error
            @EventType = 'IMPORT_FEHLER',
            @Message = 'Import-Prozess fehlgeschlagen',
            @IncludeErrorDetails = 1;

        THROW;
    END CATCH
END;

Protokolle Abfragen

Aktuelle Fehler

SELECT TOP 100 *
FROM Logger.EventLog
WHERE Severity = 'ERROR'
ORDER BY EventTime DESC;

Protokolle nach Prozedur

SELECT *
FROM Logger.EventLog
WHERE ProcedureName = 'dbo.DatenImport'
ORDER BY EventTime DESC;

Warnungen und Fehler der letzten Stunde

SELECT *
FROM Logger.EventLog
WHERE Severity IN ('WARNING', 'ERROR')
AND EventTime > DATEADD(HOUR, -1, GETDATE())
ORDER BY EventTime DESC;

Tabellenstruktur

Die Logger.EventLog-Tabelle enthält:

  • LogID (INT, Identity) – Primärschlüssel
  • EventTime (DATETIME) – Zeitpunkt des Events
  • ProcedureName (NVARCHAR(128)) – Name der aufrufenden Prozedur
  • EventType (NVARCHAR(50)) – Art des Events
  • Severity (NVARCHAR(20)) – DEBUG/INFO/WARNING/ERROR
  • Message (NVARCHAR(MAX)) – Protokollnachricht
  • Username (NVARCHAR(128)) – Datenbankbenutzer
  • AdditionalInfo (NVARCHAR(MAX)) – Zusätzliche Kontextinformationen

Best Practices

  1. Verwendung der Schweregrade
  • DEBUG: Detaillierte Informationen zur Fehlerbehebung
  • INFO: Allgemeine betriebliche Events
  • WARNING: Potenzielle Probleme, die keine Fehler sind
  • ERROR: Fehlerzustände, die Aufmerksamkeit erfordern
  1. Strukturierte Event-Typen
  • Verwenden Sie einheitliche Event-Typ-Namen (z.B. PROZESS_START, VALIDIERUNG_FEHLER)
  • Fügen Sie relevanten Kontext in AdditionalInfo hinzu
  1. Fehlerbehandlung
  • Verwenden Sie immer ERROR-Schweregrad mit Try-Catch-Blöcken
  • Aktivieren Sie IncludeErrorDetails für umfassende Fehlerinformationen
  1. Protokoll-Wartung
  • Implementieren Sie eine Aufbewahrungsrichtlinie für alte Protokolle
  • Archivieren Sie Protokolle vor dem Löschen, falls erforderlich
  • Überwachen Sie die Größe der Protokolltabelle

Performance-Überlegungen

  1. Die Logging-Tabelle enthält Indizes für:
  • Severity und EventTime
  • ProcedureName und EventTime
  1. Erwägen Sie die Archivierung alter Protokolle zur Aufrechterhaltung der Performance

Lizenz

MIT-Lizenz – Frei zur Verwendung und Modifikation nach Bedarf.

Beispiel für regelmäßige Wartung

-- Erstellen Sie eine Archivtabelle
CREATE TABLE Logger.EventLog_Archive
(
    -- Gleiche Struktur wie Logger.EventLog
);

-- Verschieben Sie alte Protokolle ins Archiv
INSERT INTO Logger.EventLog_Archive
SELECT *
FROM Logger.EventLog
WHERE EventTime < DATEADD(MONTH, -3, GETDATE());

-- Löschen Sie archivierte Protokolle
DELETE FROM Logger.EventLog
WHERE EventTime < DATEADD(MONTH, -3, GETDATE());

Typische Verwendungsmuster

Prozess-Monitoring

-- Erfolgsquote eines Prozesses überwachen
SELECT 
    CAST(EventTime AS DATE) AS Datum,
    COUNT(CASE WHEN EventType = 'PROZESS_ERFOLGREICH' THEN 1 END) AS Erfolge,
    COUNT(CASE WHEN Severity = 'ERROR' THEN 1 END) AS Fehler,
    COUNT(*) AS Gesamt
FROM Logger.EventLog
WHERE ProcedureName = 'dbo.IhreProzedur'
GROUP BY CAST(EventTime AS DATE)
ORDER BY Datum DESC;

Fehleranalyse

-- Häufigste Fehler der letzten Woche
SELECT 
    EventType,
    Message,
    COUNT(*) AS Anzahl
FROM Logger.EventLog
WHERE 
    Severity = 'ERROR'
    AND EventTime > DATEADD(WEEK, -1, GETDATE())
GROUP BY EventType, Message
ORDER BY Anzahl DESC;

Support

Bei Fragen oder Problemen erstellen Sie bitte ein Issue im GitHub-Repository.

gpiwonka/Logging

Leave a Comment




Enter Captcha Here :