2013-05-30 6 views
6

Ich entwickle einen komplizierten verteilten Dienst, der einen iterativen Synchronisationsprozess durchführt. Es synchronisiert alle 10 Sekunden Geschäftsentitäten in verschiedenen Informationssystemen. Eine Iteration besteht aus einer Reihe von 3D-Party-Serviceaufrufen, um den aktuellen Status von Geschäftsobjekten (Anzahl der Kunden, Waren, bestimmte Kunden- und Warendetails usw.) abzufragen, Abfragen an die lokale DB und dann Differenzen zwischen ihnen zu beseitigen und diese zu synchronisieren Unterschiede.Wie wird der komplexe Synchronisationsprozess protokolliert?

Es gibt verschiedene Arten von Iterationen. Sie sind schnell (nur Änderungen in der Menge der Objekte) und langsame Iterationen (vollständige Überprüfung der Daten). Fast sind alle 10 Sekunden und langsam sind einmal am Tag.

Also, wie kann ich diese Prozesse mit NLog protokollieren? Ich verwende SQLite zum Speichern von Daten. Aber ich bin im DB-Design für Protokolle fest.

Deshalb möchte ich Fluss jeder Iteration protokollieren: 1. Antrag auf aktuellen Stand der Objekte 3d Party-Service 2. Abfrage der lokalen Datenbank für aktuellen Stand der Objekte 3. Holen Unterschiede Liste 4. Rufen extern Service zum Einreichen unzureichender Daten 5. Aktualisieren Sie lokale Datenbank für unzureichende Daten

Aber es gibt so viele Arten von Informationen zu protokollieren, so kann ich es nicht einfach in ein TEXT Feld setzen.

Im Moment arbeite ich für Protokolle solche Struktur bin mit:

CREATE TABLE [Log] (
    [id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
    [ts] TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    [iteration_id] varchar, 
    [request_response_pair] varchar, 
    [type] VARCHAR NOT NULL, 
    [level] TEXT NOT NULL, 
    [server_id] VARCHAR, 
    [server_alias] VARCHAR, 
    [description] TEXT, 
    [error] Text); 

jede Service-Anfrage und Antwort So zu description und request_response_pair setzt, ist ein Schlüssel jede Antwort auf jede Anfrage zu verknüpfen.

Hier ist meine NLog config:

<?xml version="1.0" encoding="utf-8" ?> 
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" internalLogFile="D:\nlog.txt" internalLogLevel="Trace"> 
    <targets> 
    <target name="Database" xsi:type="Database" keepConnection="false" 
      useTransactions="false" 
      dbProvider="System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.82.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" 
      connectionString="Data Source=${basedir}\SyncLog.db;Version=3;" 
      commandText="INSERT into Log(iteration_id, request_response_pair, type, level, server_id, server_alias, description, error) values(@Iteration_id, @Request_response_pair, @Type, @Loglevel, @server_id, @server_alias, @Description, @Error)"> 
     <parameter name="@Type" layout="${message}"/> 
     <parameter name="@Loglevel" layout="${level:uppercase=true}"/> 
     <parameter name="@Request_response_pair" layout="${event-context:item=request_response_pair}"/> 
     <parameter name="@Iteration_id" layout="${event-context:item=iteration_id}"/> 
     <parameter name="@server_id" layout="${event-context:item=server_id}"/> 
     <parameter name="@server_alias" layout="${event-context:item=server_alias}"/> 
     <parameter name="@Description" layout="${event-context:item=description}"/> 
     <parameter name="@Error" layout="${event-context:item=error}"/> 
    </target> 
    </targets> 
    <rules> 
    <logger name="*" minlevel="Trace" writeTo="Database" /> 
    </rules> 
</nlog> 

Hier ist, wie ich log:

namespace NLog 
{ 
    public static class LoggerExtensions 
    { 
     public static void InfoEx(this Logger l, string message, Dictionary<string, object> contextParams) 
     { 
      LogEventInfo eventInfo = new LogEventInfo(LogLevel.Info, "", message); 
      foreach (KeyValuePair<string, object> kvp in contextParams) 
      { 
       eventInfo.Properties.Add(kvp.Key, kvp.Value); 
      } 

      l.Log(eventInfo); 
     } 

     public static void InfoEx(this Logger l, string message, string server_id, string server_alias, Dictionary<string, object> contextParams = null) 
     { 
      Dictionary<string, object> p = new Dictionary<string, object>(); 
      p.Add("server_id", server_id); 
      p.Add("server_alias", server_alias); 
      if (contextParams != null) 
      { 
       foreach (KeyValuePair<string, object> kvp in contextParams) 
       { 
        p.Add(kvp.Key, kvp.Value); 
       } 
      } 

      l.InfoEx(message, p); 
     } 
    } 
} 

Ich weiß, über Protokolliergrade aber ich brauche all diese ausführliche Protokolle, so dass ich log sie als Info. Ich kann kein Tutorial finden, um diese komplizierten, strukturierten Protokolle zu protokollieren. Nur einfache dumme Log-Nachrichten.

+8

Es tut mir leid, aber was genau ist Ihre Frage? – Dirk

+0

Ich verwende Enterprise Library für die Protokollierung. Mit EL können Sie protokollieren/tracen: Ereignisanzeige, Datenbank, Xml, Flat-Datei, und so weiter, ohne etwas von Ihnen Code ändern, nur in Ihrer app.config (web.config). Sie können auch nach Typ, Priorität usw. filtern. http://msdn.microsoft.com/en-us/library/ff648549.aspx – Max

Antwort

1

Ich nehme an, Sie sprechen über "Logs" für die typischen "Log-Dinge", also haben wir etwas zu sehen, wenn wir unseren Workflow (Fehler/Leistung) überprüfen müssen ". Ich nehme an, dass Sie nicht Protokolle als z. in "Wir benötigen Buchhaltungsinformationen und das Protokoll ist Teil unserer Domain-Daten und ist im Workflow enthalten."

Und von dem, was ich von Ihrem Posting bekommen habe, sorgen Sie sich über das Backend-Speicherformat in den Protokollen, damit Sie sie später verarbeiten und für die Diagnose verwenden können?


Dann würde ich empfehlen, dass Sie den Logging-Code unabhängig von den Domain-Besonderheiten machen.

Frage: Wie werden die von Ihnen erstellten Protokolle verarbeitet? Müssen Sie wirklich überall auf sie zugreifen, so dass Sie die Datenbank benötigen, um Ihnen eine strukturierte Ansicht zu bieten? Ist es in irgendeiner Weise relevant, wie schnell Sie Ihre Protokolle filtern können? Oder landen sie in einer großen Log-Analyzer-Anwendung, die nur in der zweiten Woche läuft, wenn etwas Schlimmes passiert?

Meiner Meinung nach, die größten Gründe, weshalb Sie alle Domänen Besonderheiten im Protokoll vermeiden wollen, dass „Protokolle funktionieren sollen, wenn etwas schief gehen“ und „Protokolle funktionieren sollen, nachdem die Dinge geändert“.

Logs sollte funktionieren, wenn etwas schief

gehen Wenn Sie Spalten in der Protokolltabelle für domänenspezifische Werte wie „Request_response_pair“ haben, und es gibt kein Paar, dann selbst das Protokoll zu schreiben, kann fehlschlagen (zB wenn es ein Indexfeld ist). Natürlich können Sie sicherstellen, dass Sie keine Nicht-Null-Spalten und keine Einschränkungen in Ihrem DB-Design haben, aber machen Sie einen Schritt zurück und fragen Sie: Warum wollen Sie die Struktur in Ihrer Log-Datenbank trotzdem? Protokolle sollen so zuverlässig wie möglich funktionieren, so dass jede Art von Vorlage, auf die Sie sie drücken, die Anwendungsfälle einschränken oder dazu führen kann, dass Sie wichtige Informationen nicht protokollieren können.

Logs sollten nach Dinge funktionieren

geändert Vor allem, wenn Sie benötigen Protokolle zur Erkennung und Behebung von Fehlern oder die Leistung verbessern, das bedeutet, dass Sie regelmäßig Protokolle vergleichen wird von „vor der Änderung“, um Protokolle von „nach der Veränderung". Wenn Sie die Struktur Ihrer Protokolldatenbank ändern müssen, weil Sie Ihre Domänendaten geändert haben, wird Ihnen dies weh tun, wenn Sie die Protokolle vergleichen müssen.

Richtig, wenn Sie eine Datenstruktur ändern, müssen Sie wahrscheinlich immer noch einige Tools wie Log Analyzer und so aktualisieren, aber es gibt in der Regel einen großen Teil der Protokollierung/Analyse Code, der völlig agnostisch auf die tatsächliche Struktur der Domain.


Viele Systeme (einschließlich komplexen) mit leben „nur einen log einfachen String“ und später Werkzeuge wieder schreibt die Zeichenfolge auseinander zu nehmen, wenn sie benötigen, um die Protokolle zu filtern oder zu verarbeiten.

Andere Systeme schreiben Protokolle in einfache String-Schlüssel/Wert-Paare. Die Log-Funktion selbst ist nicht domänenspezifisch, sondern akzeptiert nur ein String-Dictionary und schreibt es ab (oder noch einfacher, eine params-Zeichenfolge [], die eine gerade Anzahl von Parametern haben sollte und jeden zweiten Parameter als Schlüssel verwendet - falls nicht Angst vor diesem Vorschlag :-D).

Natürlich werden Sie wahrscheinlich eine weitere Tooling-Schicht über die Basis-Log-Funktionen schreiben, die über domänenspezifische Datenstrukturen informiert und dann das String-Dictionary zusammensetzt und weitergibt. Sie wollen sicherlich nicht den zerlegenden Code herum kopieren. Stellen Sie die Basisfunktionen jedoch überall dort zur Verfügung, wo Sie sich anmelden möchten. Es ist wirklich hilfreich, wenn Sie tatsächlich in "seltsame" Situationen geraten (Exception-Handler), wo einige Informationen fehlen.

Verwandte Themen