c# returns Generische Protokollierung von Funktionsparametern in der Ausnahmebehandlung



summary c# returns (6)

Es gibt Szenarien mit wenigen Parametern oder Große Anzahl von Parametern ...

  1. Wenige Parameter, ohne viel Mühe, schreiben Sie sie besser als Teil der Logging / Exception-Nachricht.

  2. In großen Parametern würde eine mehrschichtige Anwendung ENTITIES (wie customer, CustomerOrder ...) verwenden, um Daten zwischen Layern zu übertragen. Diese Entitäten sollten Override-ToString () - Methoden der Klasse Object implementieren,

Logmessage ("Methode gestartet" + paramObj.ToString ()) würde die Liste der Daten im Objekt geben .. Irgendwelche Meinungen? :)

Vielen Dank

Ein Großteil meines C # -Codes folgt diesem Muster:

void foo(string param1, string param2, string param3)
{
    try
    {
         // do something...
    }
    catch(Exception ex)
    {
        LogError(String.Format("Error in foo(param1={0}, param2={1}, param3={2}), exception={3}", param1, param2, param3, ex.Message));
    }
}

Gibt es eine Möglichkeit in .NET, eine Schlüssel / Wert-Liste der Parameter zu einer Funktion zu erhalten, so dass ich eine andere Funktion aufrufen kann, um meine Fehlerprotokollierungszeichenfolge zu erstellen? ODER Haben Sie einen allgemeineren / besseren Weg dies zu tun?


Dies ist ein wenig veralteter Beitrag, aber nur für den Fall, dass jemand auf diese Art und Weise auftaucht, wie ich es tat - ich löste dieses Problem mit PostSharp .

Es ist jedoch nicht praktisch frei. Die Express-Lizenz (über NuGet in VS herunterladbar) ermöglicht es Ihnen, Ihre Methode mit dem [Log] -Attribut zu dekorieren und dann Ihren bereits konfigurierten Logging-Mechanismus wie log4net nLog usw. zu wählen . Nun werden Sie Debug-Level-Einträge in Ihrem Log sehen und Parameterdetails angeben .

Mit Express-Lizenz konnte ich in meinem Projekt nur maximal 50 Methoden dekorieren. Wenn es Ihren Bedürfnissen entspricht, sind Sie gut zu gehen!


Wenn ich das getan habe, habe ich nur ein generisches Wörterbuch für die Protokollierung erstellt.

Ich habe diese LogArgs-Klasse. Und eine Basisklasse anmelden, die ich anrufe, wenn ich eine Ausnahme habe.

public class LogArgs
{

    public string MethodName { get; set; }
    public string ClassName { get; set; }
    public Dictionary<string, object> Paramters { get; set; }


    public LogArgs()
    {
        this.Paramters = new Dictionary<string, object>();
    }

}

Dann am Anfang jeder Methode, die ich mache

LogArgs args = new LogArgs { ClassName = "ClassName", MethodName = "MethodName" };
args.Paramters.Add("Param1", param1);
args.Paramters.Add("Param2", param2);
args.Paramters.Add("Param3", param3);

base.Logger.MethodStartLog(args);

Wenn ich einen Fehler habe, logge ich es so ein.

base.Logger.LogError(args, ex);

Sie könnten einen ähnlichen Stil zum Erstellen der Nachricht verwenden, aber fügen Sie das Schlüsselwort params in Ihrer LogError-Methode hinzu, um die Argumente zu verarbeiten. Beispielsweise:

    public void LogError(string message, params object[] parameters)
    {
        if (parameters.Length > 0)
            LogError(string.Format(message, parameters));
        else
            LogError(message);
    }

Nein, es gibt keinen Weg dies zu tun.

Normalerweise werden Ausnahmen nicht erfasst, es sei denn, Sie können mit ihnen umgehen.

Dh Sie würden normalerweise nur Exceptions abfangen und sie in einem Exception-Handler der obersten Ebene protokollieren. Sie erhalten dann einen Stack-Trace, erhalten aber natürlich keine Details über alle Parameter aller Methodenaufrufe im Stack.

Offensichtlich wollen Sie beim Debuggen so viele Details wie möglich haben. Andere Möglichkeiten, dies zu erreichen, sind:

  • Verwenden Sie Debug.Assert-Anweisungen großzügig, um die von Ihnen gemachten Annahmen zu testen.

  • Instrumentieren Sie Ihre Anwendung mit Protokollierung, die selektiv aktiviert werden kann. Ich benutze Log4Net, aber es gibt auch andere Alternativen, einschließlich der Verwendung der System.Diagnostics.Trace-Klasse.

Wenn Sie Ausnahmen nur abfangen, um sie zu protokollieren (ich würde dies an einer Tiergrenze in einer n-Tier-Anwendung tun, damit Ausnahmen auf dem Server protokolliert werden), sollten Sie sie immer erneut versuchen:

try
{
    ...
}
catch(Exception ex)
{
    log(ex);
    throw;
}

Sie können die aspektorientierte Programmierung mit PostSharp verwenden (siehe http://www.postsharp.org ) und das Tutorial unter http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx ). Im Grunde könnte man so etwas machen:

public class LogExceptionAttribute : OnExceptionAspect
{
 public override void OnException(MethodExecutionEventArgs eventArgs)
 {
  log.error("Exception occurred in method {0}", eventArgs); 
 }
}

[LoggingOnExceptionAspect]
public foo(int number, string word, Person customer)
{
   // ... something here throws an exception
}

Vielleicht nicht ganz das, was Sie wollen, aber ich bin mir sicher, dass es an Ihre Bedürfnisse angepasst werden kann.





.net