# Seq 用于 ASP.NET 测井 {-}_Seq 用 " SerilogTtract" 追踪

<datetime class="hidden">2024-08-31T11:20</datetime>

<!--category-- ASP.NET, Seq, Serilog -->
# 一. 导言导言 导言 导言 导言

在前一部分,我教你如何设置 [使用 ASP.NET 核心的 Seq 自定义主机 ](/blog/selfhostingseq)@. @% 现在我们已经设置了它@'_%s 时间来使用更多它的#'}功能,

[TOC]

# 追查追踪

追寻就像Losk++ 它给了您更多层次的信息 关于您的应用程序中发生什么的“' ” . It'}当您拥有分布式系统时特别有用, 您需要通过多个服务跟踪请求@.
这个网站I'@%m利用它快速追踪问题,

## 建立血清系统

设置 Serilog 的追踪功能非常简单 [血清追踪](https://github.com/serilog-tracing/serilog-tracing) .}您需要首先安装软件包@:

在这里,我们还要加上控制台汇和Seq汇

```bash
dotnet add package SerilogTracing
dotnet add package SerilogTracing.Expressions
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.Seq
```

控制台对于调试总是有用, 而 Seq 就是我们这里的 ' @re for @.}Seq 还拥有一帮 MS K2_enrichers@'可以添加额外信息到您的日志中 {.}

```bash
  "Serilog": {
    "Enrich": ["FromLogContext", "WithThreadId", "WithThreadName", "WithProcessId", "WithProcessName", "FromLogContext"],
    "MinimumLevel": "Warning",
    "WriteTo": [
        {
          "Name": "Seq",
          "Args":
          {
            "serverUrl": "http://seq:5341",
            "apiKey": ""
          }
        },
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "logs/applog-.txt",
          "rollingInterval": "Day"
        }
      }

    ],
    "Properties": {
      "ApplicationName": "mostlylucid"
    }
  }
```

要使用这些浓缩器, 您需要将这些添加到您的 `Serilog` 在您的配置 `appsettings.json` . 您也需要安装所有使用 Nuget@ MS K1的分离浓缩器

这是关于Serilog,的好坏一环, 你最后安装了一个包的BUNCH@;}但是这确实意味着你只添加您需要的东西 而不仅仅是一个单一的软件包 @.}
这里的M'我的

![精密喷入器](serilogenrichers.png)

随着这些炸弹袭击 我得到了相当不错的日志输出 在Seq.

![Serilog Seq 错误](serilogerror.png)

您可以在此看到错误消息@ ,, 堆栈追踪 , 线索 id\ MS K2 进程id 和进程名称@ MPK3 这是所有有用的信息 当您试图查找一个问题时\ I.

需要注意的一件事是 I'+#已设置 `  "MinimumLevel": "Warning",` 在我的 `appsettings.json` @ .} 这表示只有警告及以上会被登录到 Seq.} 这将有助于将噪音保留在您的日志@ MS K2}

然而在 Seq 中,您也可以指定此 pap / Api key ;这样你就可以有 `Information` (或如果你真的很热心 `Debug`@)_ 记录设置在此并限制 Seq 用 API 键实际捕捉到的东西@.}

![Seq Api 键](apikey.png)

注意:: 您仍然有应用程序管理@ ,您也可以使这个更动态化, 这样您就可以调整飞上的水平 @ MS K2 见 [Seq 汇汇 ](https://github.com/datalust/serilog-sinks-seq)详细信息@. @%

```json
{
    "Serilog":
    {
        "LevelSwitches": { "$controlSwitch": "Information" },
        "MinimumLevel": { "ControlledBy": "$controlSwitch" },
        "WriteTo":
        [{
            "Name": "Seq",
            "Args":
            {
                "serverUrl": "http://localhost:5341",
                "apiKey": "yeEZyL3SMcxEKUijBjN",
                "controlLevelSwitch": "$controlSwitch"
            }
        }]
    }
}
```

## 追查追踪

现在,我们又用SerilogTtracting它来添加追踪@,。 '相当简单。 我们的设置和以前一样。 但我们为跟踪\.新增了一个水槽。

```bash
dotnet add package SerilogTracing
dontet add package SerilogTracing.Expressions
dotnet add SerilogTracing.Instrumentation.AspNetCore
```

我们还增加一个额外的软件包以记录更详细的 aspnet核心信息@. @%

### 设置于 `Program.cs`

现在我们可以开始实际使用追踪@.}我们首先需要将跟踪添加到我们的 `Program.cs` 备忘文件@. @%

```csharp
    using var listener = new ActivityListenerConfiguration()
        .Instrument.HttpClientRequests().Instrument
        .AspNetCoreRequests()
        .TraceToSharedLogger();
```

追踪使用代表工作单位的“'+Activitients @'Q”概念。 您可以开始一项活动@.+ZB做一些工作, 然后停止它.}这对通过多种服务跟踪请求很有用*._

在此情况下,我们增加额外追踪 HttpCPClient 请求和 AspNetCore 请求的跟踪 `TraceToSharedLogger` 将活动登录到与我们应用程序其它部分相同的日志@. @%

## 服务处使用追踪

现在我们有了追踪设置, 我们可以开始在我们的应用程序中使用它 . 这里MS K1s a example of a service

```csharp
    public async Task<PostListViewModel> GetPostsByCategory(string category, int page = 1, int pageSize = 10,
        string language = MarkdownBaseService.EnglishLanguage)
    {
        using var activity = Log.Logger.StartActivity("GetPostsByCategory {Category}, {Page}, {PageSize}, {Language}",
            new { category, page, pageSize, language });
        try
        {
            var count = await NoTrackingQuery()
                .Where(x => x.Categories.Any(c => c.Name == category) && x.LanguageEntity.Name == language)
                .CountAsync();
            var posts = await PostsQuery()
                .Where(x => x.Categories.Any(c => c.Name == category) && x.LanguageEntity.Name == language)
                .OrderByDescending(x => x.PublishedDate.DateTime)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            var languages = await GetLanguagesForSlugs(posts.Select(x => x.Slug).ToList());
            var postListViewModel = new PostListViewModel
            {
                Page = page,
                PageSize = pageSize,
                TotalItems = count,
                Posts = posts.Select(x => x.ToListModel(
                    languages.FirstOrDefault(entry => entry.Key == x.Slug).Value.ToArray())).ToList()
            };
            activity.Complete();
            return postListViewModel;
        }
        catch (Exception e)
        {
            activity.Complete(LogEventLevel.Error, e);
        }

        return new PostListViewModel();
    }
```

这里的重要线条是 @:#

```csharp
  using var activity = Log.Logger.StartActivity("GetPostsByCategory {Category}, {Page}, {PageSize}, {Language}",
            new { category, page, pageSize, language });
```

这将启动一个新的“ ' @ activity@ '} ” (这是一个工作单位) < it\ .} It'}> 通过多个服务跟踪请求}<. }
正如我们在使用语句中包装的一样,这将在方法结束时完成并处理完毕,但明确完成这种方法的良好做法却是良好的。

```csharp
            activity.Complete();
```

在处理渔获的例外中,我们也完成了活动,但有误差水平和例外 {.}_BARBAR_

## 使用追踪

现在我们有了所有这些设置, 我们可以开始使用它 @ . @ Here'}这是在我的应用程序中追踪的示例@.}

![Http 跟踪](httptrace.png)

您可以看到单个邮件的多个步骤, 以及所有 HttpClient 请求和计时@.}

注意 我使用 Postgres 作为数据库@ , @ 与 SQL 服务器不同, npgsql 驱动程序有本地支持的追踪功能, 这样您可以从您的数据库查询中获得非常有用的数据, 如 SQ L 已执行的SQL ,} 时间等@ MPK2 这些被保存为 @ MS K3\ spans '} 到 Seq 并查看下面的:}

```json
  "@t": "2024-08-31T15:23:31.0872838Z",
"@mt": "mostlylucid",
"@m": "mostlylucid",
"@i": "3c386a9a",
"@tr": "8f9be07e41f7121cbf2866c6cd886a90",
"@sp": "8d716c5f01ad07a0",
"@st": "2024-08-31T15:23:31.0706848Z",
"@ps": "622f1c86a8b33304",
"@sk": "Client",
"ActionId": "91f5105d-93fa-4e7f-9708-b1692e046a8a",
"ActionName": "Mostlylucid.Controllers.HomeController.Index (Mostlylucid)",
"ApplicationName": "mostlylucid",
"ConnectionId": "0HN69PVEQ9S7C",
"ProcessId": 30496,
"ProcessName": "Mostlylucid",
"RequestId": "0HN69PVEQ9S7C:00000015",
"RequestPath": "/",
"SourceContext": "Npgsql",
"ThreadId": 47,
"ThreadName": ".NET TP Worker",
"db.connection_id": 1565,
"db.connection_string": "Host=localhost;Database=mostlylucid;Port=5432;Username=postgres;Application Name=mostlylucid",
"db.name": "mostlylucid",
"db.statement": "SELECT t.\"Id\", t.\"ContentHash\", t.\"HtmlContent\", t.\"LanguageId\", t.\"Markdown\", t.\"PlainTextContent\", t.\"PublishedDate\", t.\"SearchVector\", t.\"Slug\", t.\"Title\", t.\"UpdatedDate\", t.\"WordCount\", t.\"Id0\", t0.\"BlogPostId\", t0.\"CategoryId\", t0.\"Id\", t0.\"Name\", t.\"Name\"\r\nFROM (\r\n    SELECT b.\"Id\", b.\"ContentHash\", b.\"HtmlContent\", b.\"LanguageId\", b.\"Markdown\", b.\"PlainTextContent\", b.\"PublishedDate\", b.\"SearchVector\", b.\"Slug\", b.\"Title\", b.\"UpdatedDate\", b.\"WordCount\", l.\"Id\" AS \"Id0\", l.\"Name\", b.\"PublishedDate\" AT TIME ZONE 'UTC' AS c\r\n    FROM mostlylucid.\"BlogPosts\" AS b\r\n    INNER JOIN mostlylucid.\"Languages\" AS l ON b.\"LanguageId\" = l.\"Id\"\r\n    WHERE l.\"Name\" = @__language_0\r\n    ORDER BY b.\"PublishedDate\" AT TIME ZONE 'UTC' DESC\r\n    LIMIT @__p_2 OFFSET @__p_1\r\n) AS t\r\nLEFT JOIN (\r\n    SELECT b0.\"BlogPostId\", b0.\"CategoryId\", c.\"Id\", c.\"Name\"\r\n    FROM mostlylucid.blogpostcategory AS b0\r\n    INNER JOIN mostlylucid.\"Categories\" AS c ON b0.\"CategoryId\" = c.\"Id\"\r\n) AS t0 ON t.\"Id\" = t0.\"BlogPostId\"\r\nORDER BY t.c DESC, t.\"Id\", t.\"Id0\", t0.\"BlogPostId\", t0.\"CategoryId\"",
"db.system": "postgresql",
"db.user": "postgres",
"net.peer.ip": "::1",
"net.peer.name": "localhost",
"net.transport": "ip_tcp",
"otel.status_code": "OK"
```

您可以看到, 这包括您需要知道的关于查询“ , ” (SQL 已经执行) “,” (连接字符串等“ MPK2 ”)的一切信息。 当您尝试在这样小的一个应用程序中追踪一个问题时, 这是非常有用的信息。 在这样的小程序里, 这只是有趣的“, ” 。

# 在结论中的结论

I'@ve 仅刮过追寻的表面 这里#, @ it'} 希望I'* 已展示使用 Seq @&{Serilog 进行简单追踪有多简单。 ASP=.}NET Core applications@.}这样我就能从应用程序透视等更强大的工具中获得很多好处,