如何在c#中对所有日志进行分组

Posted

技术标签:

【中文标题】如何在c#中对所有日志进行分组【英文标题】:How to group all the logs in c# 【发布时间】:2021-10-18 04:24:01 【问题描述】:

我有一个主 mvc 应用程序,它将调用 3 个 Web api 应用程序,并将使用 log.LogInformation() 为每个方法命中和 mvc 项目中的每个控制器写入日志。我创建了一个名为 username 的变量,并让每个日志都在消息末尾包含该用户名。 IE。 log.LogInformation("You have hit the home page of the mvc project... @Username, username)so 在我使用@Username 并传递username 的每条日志消息的末尾。我想根据该变量 username 对所有整个日志进行分组。有没有办法将记录到记录器的所有整个日志分组,从 mvc 项目到每个调用的 web api 项目?我正在使用Serilog 编写日志。


跟进:

因此,在阅读 Log scopes 并使用 BeginScope 之后,我可以在我的最后一个控制器中的 mvc 项目中创建另一个方法,如下所示:

    public IActionResult GetAllLogs()
    
        using (_logger.BeginScope("Gathering all the logs created for @Username", HomeController.username))
        

        
    

所以保留它可以从 mvc 项目中收集所有日志,包括 web api 项目日志?我不需要在using() 语句中做任何事情?

【问题讨论】:

您可以检查Log scopes (Read here)。使用BeginScope,范围内的所有日志语句都将属性记录为自定义属性。 因此,使用 Log 范围,您无需将属性传递到第 n 个函数级别。由于属性被记录为自定义属性,因此您可以进行分组、过滤等。 谢谢!我正在阅读Log scopesBeginScope 我不需要在using() 语句中执行任何操作来收集所有日志,因为BeginScope 将收集所有日志?请查看我编辑的帖子@user1672994 我也看到了这个docs.microsoft.com/en-us/dotnet/api/…,但它传递了一个属性......你是说我不需要?它怎么知道我想使用变量username @MarrkCo - 我已经发布了答案,如果您需要任何详细信息,请查看并告诉我。 【参考方案1】:

您可以检查日志范围 (Read here)。使用 BeginScope,范围内的所有日志语句都会将属性记录为自定义属性。

例如:Scope 在调用 Method1 -> Method2 -> Method3DoesTheLogging 的 SomeAPI API 处启动。现在直到方法Method3DoesTheLogging,不需要传递任何属性来记录日志语句。日志框架会自动附加在BeginScope.中定义的自定义属性

    public IActionResult SomeAPI()
    
        using (_logger.BeginScope("Gathering all the logs created for @Username", HomeController.username))
        
            Method1();
        
    
    
    public void Method1()
    
        Method2();
    
    
    public void Method2()
    
        Method3DoesTheLogging();
    
    
    public void Method3DoesTheLogging()
    
        _logger.LogInformation("This log statement will log the username automatically as custom property".);
    

因此,使用 Log 范围,您无需将属性传递到第 n 个函数级别。由于属性被记录为自定义属性,因此您可以进行分组、过滤等,

【讨论】:

感谢您的详细解释。那么无论.BeginScope() 放置在哪里,它就会开始根据自定义属性收集/分组所有日志?如果您不知道在应用程序启动期间将调用哪个方法怎么办?因为我看到您调用了发生日志记录的最后一个方法?而且我的每个方法都有一个日志,所以当我在一个方法中调用一个方法时,我仍然不需要传递属性吗? when I would call a method within a method, I still would not need to pass the property - 是的,不需要。开始范围定义自定义属性的范围,该范围将由作为范围一部分的日志语句记录。 What if you do not know which method will be called during the start of the application- 这个概念称为结构日志记录,其中每个方法定义要记录的内容;其他自定义属性是根据它们所在的范围记录的。所以假设如果从两个地方调用 method1,1) 有范围,2) 没有范围。然后对于#1,将为#2 记录自定义属性,不会记录自定义属性....所以从调用链的函数开始是一个很好的实践。 使用 Scope 的另一个优点是还可以使用 Scope 的嵌套。您可以尝试在this repo 中创建的示例。 我现在关注,谢谢你给我解释! :)

以上是关于如何在c#中对所有日志进行分组的主要内容,如果未能解决你的问题,请参考以下文章

如何在每个循环中对 Json 对象进行分组

如何从相关表中对 SQL 中的结果进行分组?

如何在AngularJS ui-grid中对分组行进行排序?

如何在我的 Qt 应用程序中对小部件进行分组?

在 C# 中对字典列表进行分组

如何像实体框架一样在Core Data的一个类文件中对属于一个实体的方法进行分组?