.net 记录类名和方法名的最佳方式是什么?

cyej8jka  于 2023-01-06  发布在  .NET
关注(0)|答案(6)|浏览(135)

我基本上想写一个客户日志记录器/跟踪器,它也记录调用日志记录器/跟踪器的方法的类和方法名。这应该是快速的,这样它就不会影响应用程序的性能,强类型和干净。有人有好主意吗?
以下是我拥有的几个,但由于反思,我担心性能:

  • StackTrace/StackFrame(开销太大?)
  • MethodInfo. GetCurrentMethod()(仍然太慢?并且不是很干净)
  • 将方法作为委托传递(C#可以隐式地这样做,我可以访问MethodInfo,但不是很干净)

我很感激任何人的评论。

    • 更新日期:**

我喜欢StackFrame的简洁,所以我问了一个关于StackFrame性能的更具体的问题here,我得到了一些非常好的回答,包括性能测试。(在我的计算机上大约需要1微秒)和new StackFrame(1)可以按需请求(在我的计算机上大约需要15 - 20微秒)。我把这个方法作为委托选项丢弃了,因为当这个方法有几个参数时太混乱了。

    • 结论:**

我已经考虑了所有的选项,最好的是为PostSharp编写一个自定义插件,在编译过程中向其应用[Trace]这样的自定义属性时,将方法名作为字符串注入MSIL。在我看来,这是最快和最易维护的选项。这甚至可以实现更多的功能,例如传递参数名和参数而不进行任何类型的反射,以及捕获和记录异常此my related question可获取更多信息。

qcbq4gxm

qcbq4gxm1#

最快的方法是在编译时完成,这是事实,但在.NET中最方便的方法是使用CallerMemberNameCallerFilePath和.NET 4.5中引入的其他编译器服务属性:

public void TraceMethodCall([CallerMemberName] string methodName = "")
{
}
5tmbdcev

5tmbdcev2#

简单地说,最快的方法是在编译时静态地执行:

public void DoSomething()
{
    TraceCall("DoSomething");
} 

public void TraceCall(string methodName)
{
    if (!tracingEnabled) { return; }
    // Log the call
}

这个问题和你之前的问题基本上是一样的以可维护和准确的速度完成此任务的最佳方法是什么?我们前面讨论的运行时选项会对性能造成相对严重的影响,但代价是它们易于实现。
正如前面提到的,这开始倾向于面向方面编程; PostSharp就是这样一个库,它可以帮助找到静态编译性能与简单维护之间的平衡。

1yjd4xko

1yjd4xko3#

当您已经在方法内部时(或者如果您正在拦截方法),如果您想保持类型安全,我认为您不会比MethodInfo.GetCurrentMethod做得更好--它不是太快。
既然您想在日志记录中这样做,那么您是否考虑过在异步操作中这样做,这样就不会减慢主线程的速度?
根据应用程序上已有的负载,它可能有帮助,也可能没有帮助。

tkqqtvp1

tkqqtvp14#

最好的方法是在编译时:C++传统上在宏中使用____FILE___和____LINE____预处理符号来实现这一点。不幸的是,C#编译器目前没有提供宏或____FILE___和____LINE___的等价物。
这实际上意味着您唯一的选择是在运行时记录此信息,这意味着要么向要记录的每个方法添加繁琐的手动跟踪,要么像您描述的那样使用反射。

bvhaajcl

bvhaajcl5#

我认为Log4PostSharp会很好地完成这项工作。

c7rzv4ha

c7rzv4ha6#

如果你关心速度比实际日志消息应该使用Event Tracing for Windows创建。ETW是一个高速日志库实现为一个驱动程序,可以从内核模式和用户模式访问。跟踪可以动态打开和关闭。日志添加到应用程序的开销非常小。我已经使用ETW实现高吞吐量服务器应用程序的跟踪。检查NTrace

相关问题