c#简化的方法将异常线编号纳入Serilog
我正在使用Serilog使用此代码来将异常的行编写到我的日志中。这里的问题是行号是将异常放在捕获块中而不是发生异常的实际线路的地方。
问题
try
{
//line: 2
throw new Exception();
}
catch(Exception ex)
{
//line: 15
Log.Here().Error(ex, "Hello, world!");
//Serilog will log the exception line as line 15 instead of line 2
//which doesn't help me at all if I have 100s of lines of code
//that could throw an actual exception
}
这是我当前的serilog代码,
public static class LoggerExtensions
{
public static ILogger Here(this ILogger logger,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0) {
return logger
.ForContext("MemberName", memberName)
.ForContext("FilePath", sourceFilePath)
.ForContext("LineNumber", sourceLineNumber);
}
}
我在我的每个类中都使用这样的Serilog代码,还需要简化以接受任何T型T类,但这是另一天的另一个问题:
Serilog.Log.ForContext<T>()
//类
private static Serilog.ILogger Log => Serilog.Log.ForContext<MyClass>();
// in the method
Log.Here().Information("Hello, world!");
var outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Warning()
.Enrich.FromLogContext()
.WriteTo.RollingFile("log/{Date}.log", outputTemplate, LogEventLevel.Warning)
.WriteTo.Console(LogEventLevel.Warning, outputTemplate, theme: AnsiConsoleTheme.Literate)
.CreateLogger();
部分解决方案
这是我用来找到最初发生异常的实际线路的代码。而不是在每个捕获块中一遍又一遍地使用这3行代码(stacktrace,frax,line),而是想找到一种使用它的方法,并自动将其正确附加到Serilog输出模板上。
catch(Exception ex)
{
var stackTrace = new StackTrace(ex, true);
var frame = stackTrace.GetFrame(0);
var line = frame.GetFileLineNumber();// This is what I need as the actual line number
Log.Here().Error(ex, $"Exception occured on line # {line}"); //This works but doesn't follow the output template pattern
}
I am using this code using serilog to get write the line number of the exception into my logs. The problem here is the line number is where the exception is thrown in the catch block and not the actual line where the exception occurred.
The Problem
try
{
//line: 2
throw new Exception();
}
catch(Exception ex)
{
//line: 15
Log.Here().Error(ex, "Hello, world!");
//Serilog will log the exception line as line 15 instead of line 2
//which doesn't help me at all if I have 100s of lines of code
//that could throw an actual exception
}
This is my current Serilog code
public static class LoggerExtensions
{
public static ILogger Here(this ILogger logger,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0) {
return logger
.ForContext("MemberName", memberName)
.ForContext("FilePath", sourceFilePath)
.ForContext("LineNumber", sourceLineNumber);
}
}
I use like this in each of my classes which also needs to be streamlined to accept any type T but that is another question for another day:
Serilog.Log.ForContext<T>()
// at the beginning of the class
private static Serilog.ILogger Log => Serilog.Log.ForContext<MyClass>();
// in the method
Log.Here().Information("Hello, world!");
var outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Warning()
.Enrich.FromLogContext()
.WriteTo.RollingFile("log/{Date}.log", outputTemplate, LogEventLevel.Warning)
.WriteTo.Console(LogEventLevel.Warning, outputTemplate, theme: AnsiConsoleTheme.Literate)
.CreateLogger();
The Partial Solution
Here is the code that I use to find the actual line where the exception originally occurred. Instead of using these 3 lines of code(stacktrace,frame,line) over and over and over in each catch block I want to find a way to use it once and automatically append it to the serilog output template correctly.
catch(Exception ex)
{
var stackTrace = new StackTrace(ex, true);
var frame = stackTrace.GetFrame(0);
var line = frame.GetFileLineNumber();// This is what I need as the actual line number
Log.Here().Error(ex, quot;Exception occured on line # {line}"); //This works but doesn't follow the output template pattern
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需将代码从捕获块移动到您的“ there()”方法中
,这样就简单地将方法称为相同
,或者您只需将日志直接写入该方法中
,然后只需调用
Just move the code from the catch block into your "Here()" method as such
then simple just call the method as the same
or you can just write the log directly in the method as such
and simply call as so
caller信息 .NET 4.5。这将进行编译,这是必须手动检查堆栈跟踪的很大进步。
Caller Information has been added to .NET 4.5. This will be compiled, a big improvement over having to examine the stack trace manually.