我在我的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提供与messageMessage相同的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”?
答案 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将实现您所拥有的功能,并获得针对特定异常类型的附加优势。