定义LoggerMessage

时间:2018-01-25 11:17:21

标签: c# logging asp.net-core asp.net-core-2.0 serilog

我在我的ASP.NET Core WebApp中使用serilog作为LoggingProvider,我想使用Microsoft.Extensions.Logging.Abstractions中的LoggerMessage功能。我的日志是JSON格式的。

如果我想用Serilog记录对象,我可以记录对象的简单.ToString()或用@ -Operator对对象进行破坏。示例:

的ToString:

Log.Information("Some information about {MyObject}", myObject);

解构:

Log.Information("Some information about {@MyObject}", myObject);

现在我使用LoggerMessage来定义LoggingActions,并在ILogger的扩展方法中调用它们,如official documentation中所述:

private static readonly Action<ILogger, MyObject, Exception> = // Exception is required
        LoggerMessage.Define<MyObject>(
            LogLevel.Information, 
            new EventId(1), 
            "Some Information about {MyObject}");

但我不能将Exception作为消息参数传递来解构Exception。这意味着我没有在日志中将我的异常作为JSON对象提供,但只有这样:

"Exception":"System.ArgumentException: Exception occured\r\nParameter name: test\r\n   at Test.Controllers.TestController.TestLog() in C:\\Source\\Repos\\Test\\Project\\Controllers\\TestController.cs:line 40"

另一个(小)缺点是,我不希望为errorMessage提供与messageMes​​sage相同的LoggingLevel ...

我现在看到的唯一可能性是放弃使用LoggerMessages作为我的异常消息,并按照以下方式执行:

public static void LogMyObjectError(this ILogger logger, MyObject myObject, Exception ex)
{
    string msg = "Some error with {MyObject} {@Exception}";
    logger.LogWarning(msg, myObject, ex);
}

我有什么想法可以使用LoggerMessage “destructured Exception”?

2 个答案:

答案 0 :(得分:1)

  

我有什么想法可以使用LoggerMessage和#34; destructured Exception&#34;?

您可以通过将异常对象包含为记录操作的另一个参数来实现此目的:

#include <SoftwareSerial.h>
SoftwareSerial SIM900A(9, 10);
void setup(){
    Serial.begin(9600);
    SIM900A.begin(9600);
    pinMode(13,OUTPUT);
    Serial.println("Program Started");
    SIM900A.println("AT+CMGD=ALL");
    SIM900A.println("AT+CNMI=2,2,0,0");
}

void loop(){
    if (SIM900A.available()>0){
        String k=SIM900A.readString();
        Serial.println("*** RECEIVED SMS ***");
        Serial.println(k);
        int len=k.length();
        Serial.println("the length is ");
        Serial.println(len);

        // Remove first 51 characters
        Serial.println("After removing first 51 characters");

        k.remove(0, 51);
        Serial.println(k);
        len = k.length();
        Serial.println("the length is ");
        Serial.println(len);
        // Remove \r\n from tail
        k.remove(len - 2, 2);Serial.println("After removing first r & n characters");
        Serial.println("the length is ");
        len = k.length();
        Serial.println(len);
        Serial.println(k);
        String L=k;
        Serial.println(L);

        if((L.equals("ON"))||(L.equals("On"))||(L.equals("on"))){
            Serial.println("now relay can be on");
            digitalWrite(13,HIGH);delay(5000);
        }
        else{
            digitalWrite(13,LOW);
            Serial.println("Else loop executed");
        };
        Serial.println("*** END SMS ***");
    };
}

然而,当它调用日志记录操作时会变得很难看,因为你应该在传递的参数中复制异常对象:

private static readonly Action<ILogger, MyObject, Exception, Exception> _someErrorEvent =
    LoggerMessage.Define<MyObject, Exception>(
        LogLevel.Information,
        new EventId(1),
        "Some Information about {MyObject} {@Exception}");

您可以通过定义基于_someErrorEvent(logger, myObject, exception, exception); 的自己的帮助程序(例如LoggerMessageEx.DefineError<T1>())来解决此问题:

LoggerMessage

现在您可以使用以下调用创建日志记录操作:

public static class LoggerMessageEx
{
    public static Action<ILogger, T1, Exception> DefineError<T1>(LogLevel logLevel, EventId eventId, string formatString)
    {
        var action = LoggerMessage.Define<T1, Exception>(logLevel, eventId, formatString);
        return (logger, arg1, exception) => action(logger, arg1, exception, null);
    }
}

通过传递一个异常对象来调用它:

private static readonly Action<ILogger, MyObject, Exception> _someErrorEvent =
    LoggerMessageEx.DefineError<MyObject>(
        LogLevel.Information,
        new EventId(1),
        "Some Information about {MyObject} {@Exception}");

对我而言,只有当你有很多这样的事件时,这一切才有意义。否则,我会选择您使用_someErrorEvent(logger, new MyObject(), exception); 方法。

答案 1 :(得分:1)

而不是根据异常类型对异常进行解构(可能会产生意想不到的后果),插入Serilog.Exceptions将实现您所拥有的功能,并获得针对特定异常类型的附加优势。