[翻译] ASP.NET Core 利用 Docker、ElasticSearch、Kibana 来记录日志
<p>原文: Logging with ElasticSearch, Kibana, ASP.NET Core and Docker</p><p><em>一步一步指导您使用 ElasticSearch, Kibana, ASP.NET Core 2.1 和 Docker 来记录日志</em></p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/elasticsearch-kibana-docker-and-net-core.png" alt="" loading="lazy"></p>
<p>在本教程中,我将向您展示如何启动和运行 ElasticSearch,Kibana 和 ASP.NET Core 2.1</p>
<p>在开始之前,让我们来看看 ElasticSearch,Kibana 和 Serilog 分别是什么。</p>
<h3 id="什么是-elasticsearch-">什么是 ElasticSearch ?</h3>
<p>简单来说,ElasticSearch 是一个开源数据库,非常适合索引日志和分析数据。</p>
<h3 id="什么是-kibana-">什么是 Kibana ?</h3>
<p>Kibana 是开源的 ElasticSearch 的数据可视化用户界面。可以将 ElasticSearch 视为数据库,将Kibana 视为 Web 用户界面,您可以使用它在 ElasticSearch 中构建图表和查询数据。</p>
<h3 id="什么是-serilog-">什么是 Serilog ?</h3>
<p>Serilog 是 ASP.NET Core 的一个插件,可以简化日志记录。Serilog 有各种可用的接收器,例如,有纯文本、SQL 和 ElasticSearch 接收器等等。</p>
<h3 id="为什么-elasticsearch-如此受欢迎">为什么 ElasticSearch 如此受欢迎?</h3>
<p>除了几乎每个应用程序都需要日志记录这一事实之外,ElasticSearch 解决了许多问题并且做得非常好:</p>
<ul>
<li>它是免费和开源的<br>
免费。好吧,我承认是基本功能免费。如果您需要 Kibana 中的安全和警报功能,您可以购买 Kibana 的商业 X-pack 订阅,或者可以找一些开源的替代品。</li>
<li>RESTful API<br>
ElasticSearch 有一个 RESTful 的 API。查询结果以 JSON 格式返回,这意味着结果是非常易用的。通过 RESTful API 查询和插入数据意味着使用任何编程语言都可以轻松使用 ElasticSearch。</li>
<li>易于查询<br>
ElasticSearch 有一个内置的基于 Apache Lucene 的全文搜索引擎。与其他数据库相比,Lucene易于查询。即使是非技术人员也可以编写常见查询。</li>
<li>快 - 非常快<br>
查询大型 SQL 数据库很容易花费 10 或 20 秒。对于大型 ElasticSearch 数据库上的类似查询,在 10 毫秒内返回结果是很常见的。</li>
<li>可扩展<br>
它很容易扩展。再加上它是开源的, 这意味着您可以很容易控制您的钱包。</li>
<li>易于安装<br>
只需启动包含 ElasticSearch 和 Kibana 容器的 docker compose 文件,您就可以开始记录和搜索了。</li>
</ul>
<h3 id="为什么我需要-elasticsearch-和-kibana-">为什么我需要 ElasticSearch 和 Kibana ?</h3>
<p>如果您曾经构建过应用程序,那么你一定记录过日志。我们经常去记录错误,但这些错误日志存储在服务器某处的文件文件里,经常会无法被访问。ElasticSearch 使任何类型的日志记录变得简单,易于访问和搜索。</p>
<p>ElasticSearch 令人难以置信的速度和简单的查询语言加上 Kibana 的图形界面,构成了强大的组合。如果您还没有使用 ElasticSearch 进行日志记录,我强烈建议您开始使用它。</p>
<h2 id="信息足够了让我们开始-coding-">信息足够了,让我们开始 Coding 。</h2>
<p>我将使用 Visual Studio Code,一个开源的跨平台代码编辑器。出于本教程的目的,我将使用 Mac OSX,但您也可以使用 Ubuntu 或 Windows 10。</p>
<h4 id="准备条件">准备条件</h4>
<p>要继续下面的步骤,请确保安装了这些:</p>
<ul>
<li>Docker</li>
<li>Visual Studio Code</li>
<li>.NET Core SDK 2.1.300 或更高版本 ( 下载 )</li>
</ul>
<h4 id="创建项目文件夹">创建项目文件夹</h4>
<pre><code>mkdir elastic-kibana
cd elastic-kibana
</code></pre>
<h4 id="使用-net-core-命令行创建-mvc-项目">使用 .NET Core 命令行创建 MVC 项目</h4>
<pre><code>dotnet new mvc -n elastic-kibana -o src
</code></pre>
<h4 id="在-visual-studio-code-中打开项目">在 Visual Studio Code 中打开项目</h4>
<pre><code>cd elastic-kibana
code .
</code></pre>
<h4 id="创建-docker-compose-文件">创建 docker compose 文件</h4>
<p>接下来,创建一个 docker compose 文件。此文件将一并启动 ElasticSearch 和 Kibana 容器,无需为每个容器运行单独的docker run命令。</p>
<pre><code>mkdir docker
cd docker
</code></pre>
<p>创建一个名为 docker-compose.yml 的文件:</p>
<pre><code>version: '3.1'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.2.4
container_name: elasticsearch
ports:
- "9200:9200"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
networks:
- docker-network
kibana:
image: docker.elastic.co/kibana/kibana:6.2.4
container_name: kibana
ports:
- "5601:5601"
depends_on:
- elasticsearch
networks:
- docker-network
networks:
docker-network:
driver: bridge
volumes:
elasticsearch-data:
</code></pre>
<p>接下来,运行 docker compose 命令来启动容器。</p>
<pre><code>docker-compose up -d
</code></pre>
<p>第一次运行 docker-compose up 命令时,它将从 docker 仓库下载 ElasticSearch 和 Kibana 所需的镜像,因此它将花费几分钟的时间。</p>
<p>运行 docker-compose up 命令后,请检查 ElasticSearch 和 Kibana 是否已经启动。</p>
<h4 id="elasticsearch">ElasticSearch</h4>
<p>打开 http://localhost:9200 确认 ElasticSearch 已经启动。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/ensuring-elasticsearch-is-up-and-running.png" alt="" loading="lazy"></p>
<h4 id="kibana">Kibana</h4>
<p>打开 http://localhost:5601 确认 Kibana 已经启动。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/ensuring-kibana-is-up-and-running.png" alt="" loading="lazy"></p>
<h3 id="添加-nuget-包到项目">添加 Nuget 包到项目</h3>
<p>我们将添加以下 Serilog 的包到项目。</p>
<p>Serilog<br>
Serilog.Sinks.ElasticSearch<br>
Serilog.Extensions.Logging</p>
<pre><code>cd ..
cd elastic-kibana
</code></pre>
<pre><code>dotnet add package Serilog
dotnet add package Serilog.Sinks.ElasticSearch
dotnet add package Serilog.Extensions.Logging
dotnet restore
</code></pre>
<h3 id="添加一些配置信息到-appsettingsjson">添加一些配置信息到 appsettings.json</h3>
<p>添加默认的日志设置以及 ElasticSearch 的 url 到 appsettings.json 文件</p>
<pre><code>{
"Logging": {
"LogLevel": {
"Default": "Information",
"System": "Information",
"Microsoft": "Information"
}
},
"ElasticConfiguration": {
"Uri": "http://localhost:9200/"
}
}
</code></pre>
<h3 id="在-startupcs-中配置日志功能">在 Startup.cs 中配置日志功能</h3>
<p>下一步,在 Startup.cs 中配置日志功能</p>
<p>添加这些 using 语句:</p>
<pre><code>using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Sinks.Elasticsearch;
</code></pre>
<p>然后,配置 Startup 的构造函数以从 appsettings.json 加载 ElasticSearch 的 URL,并配置 ElasticSearch 的接收器。</p>
<pre><code>public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
{
var builder = new ConfigurationBuilder()
.SetBasePath(hostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostingEnvironment.EnvironmentName}.json", reloadOnChange: true, optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
var elasticUri = Configuration["ElasticConfiguration:Uri"];
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(elasticUri))
{
AutoRegisterTemplate = true,
})
.CreateLogger();
}
</code></pre>
<p>最后,在 Configure 方法中将 Serilog 添加到日志工厂。</p>
<pre><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
/// ...
loggerFactory.AddSerilog();
/// ...
}
</code></pre>
<h3 id="开始记录日志到-elasticsearch">开始记录日志到 ElasticSearch</h3>
<p>现在,通过在 Visual Studio Code 中点击 F5 或者命令行中执行 <code>dotnet run</code> 来运行 MVC 应用程序。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/run-the-mvc-application.png" alt="" loading="lazy"></p>
<h3 id="启动-kibana">启动 Kibana</h3>
<p>由于我们在 Startup 类中配置了日志记录并将最小日志级别设置为 <code>Information</code>,因此运行该应用程序会将一些事件记录到 ElasticSearch 。</p>
<p>在 http://localhost:5601 打开 Kibana,以便我们可以查看日志。</p>
<p>加载 Kibana 后,您将看到默认页面。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/launching-kibana.png" alt="" loading="lazy"></p>
<h3 id="在-kibana-中创建索引模式来显示数据">在 Kibana 中创建索引模式来显示数据</h3>
<p>Kibana 现在还不会显示任何日志。您必须先指定索引才能查看记录的数据。为此,请单击导航中的 <code>Management</code> 链接,然后将列在页面底部的 logstash 索引名称复制到文本框中,如下所示,然后单击下一步按钮。或者,您可以使用*号通配符,例如 logstash-*</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/creating-an-index-pattern-in-kibana.png" alt="" loading="lazy"></p>
<p>然后,通过选择 <code>@timestamp</code> 指定时间过滤器字段名称,然后单击 <code>Create index pattern </code>按钮。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/configuring-a-time-filter-field-in-elastic-search.png" alt="" loading="lazy"></p>
<p>您现在可以通过单击导航中的 <code>Discover</code> 链接来查看日志。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/viewing-elasticsearch-logs-with-kibana.png" alt="" loading="lazy"></p>
<h2 id="在-mvc-controller-中记录自定义消息">在 MVC Controller 中记录自定义消息</h2>
<p>由于我们指定要记录日志级别为 <code>Information</code> 或更高级别的消息,因此默认情况下会记录大量信息消息。但是如果我们想记录自己的消息呢?值得庆幸的是,这很容易做到。接下来我将在 HomeController 中记录一条消息。</p>
<p>添加 using 语句:</p>
<pre><code>using Microsoft.Extensions.Logging;
</code></pre>
<p>然后,使用构造函数注入的方式来注入 ILogger 的实例。</p>
<pre><code>ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
</code></pre>
<p>最后,在 Index Action 中记录一条消息。</p>
<pre><code>public IActionResult Index()
{
_logger.LogInformation($"oh hai there! : {DateTime.UtcNow}");
return View();
}
</code></pre>
<h3 id="在-kibana-中搜索">在 Kibana 中搜索</h3>
<p>现在我们已经记录了一条消息,只需打开 Kibana 并搜索日志消息的文本即可。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/searching-in-kibana.png" alt="" loading="lazy"></p>
<p>您还可以将某一条日志在单独的窗口中打开,以查看各个字段记录的信息。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/kibana-view-single-document.png" alt="" loading="lazy"></p>
<p>我将展示一些基本的搜索示例,来演示在 Kibana 中搜索的容易程度以及 ElasticSearch 的强大功能:</p>
<pre><code>message:"oh hai there"
</code></pre>
<pre><code>level:"Information"
</code></pre>
<pre><code>fields.ActionName:"elastic_kibana.Controllers.HomeController.Index"
</code></pre>
<pre><code>(message:"oh hai there" AND fields.ActionName:"elastic_kibana.Controllers.HomeController.Index")
</code></pre>
<h3 id="记录错误日志到-elasticsearch">记录错误日志到 ElasticSearch</h3>
<p>一个典型的需求就是记录错误消息。使用 Serilog 这将变得非常简单,如下所示。</p>
<pre><code>try
{
throw new Exception("oops. i haz cause error in UR codez.");
}
catch (Exception ex)
{
_logger.LogError(ex, "ur code iz buggy.");
}
</code></pre>
<h3 id="在-kibana-中搜索错误日志">在 Kibana 中搜索错误日志</h3>
<p>在 Kibana 中找到错误日志非常简单,使用如下的搜索条件就可以找到所有的错误日志了。</p>
<pre><code>level: "Error"
</code></pre>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/searching-for-errors-in-kibana.png" alt="" loading="lazy"></p>
<p>我们来看看使用 Serilog 和 ElasticSearch 默认记录的详细信息。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/default-level-of-detail-in-error-messages-with-serilog-and-elasticsearch-sink.png" alt="" loading="lazy"></p>
<p>它看起来还不错,但您会注意到异常细节被记录为一个大大的字符串。在此字符串中搜索信息仍会返回结果,但如果根据特定字段记录信息,我们可以执行更强大和特定的搜索。值得庆幸的是,有一个名为 Serilog.Exceptions 的插件可以帮助我们。</p>
<h3 id="安装-serilogexceptions-nuget-包">安装 Serilog.Exceptions Nuget 包</h3>
<p>安装 Serilog.Exceptions Nuget 包:</p>
<pre><code>dotnet add package Serilog.Exceptions
dotnet restore
</code></pre>
<p>接下来,在 Startup.cs 文件中使用如下 using 语句</p>
<pre><code>using Serilog.Exceptions;
</code></pre>
<p>然后,使用 Serilog.Exceptions 来丰富一下 Logger</p>
<pre><code>public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
{
/// ...
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(elasticUri))
{
AutoRegisterTemplate = true,
})
.CreateLogger();
}
</code></pre>
<p>最后,刷新一下,记录一个新的错误,并在 Kibana 中搜索到它,查看更结构化的错误日志记录。</p>
<p><img src="https://www.humankode.com/assets/img-content/blog/42831e9a-82fe-4ae7-904d-27e31f26f2e6/ai/error-logging-with-serilog-exceptions-a-more-structured-approach.png" alt="" loading="lazy"></p>
<h3 id="降低日志级别">降低日志级别</h3>
<p>您可能会发现 <code>Information</code> 级别日志有点过于冗长,不符合您的口味。默认情况下,ASP.NET Core 将记录 Kestrel 托管相关的日志事件。这可能会非常嘈杂。排除掉它们的一种简单方法是通过修改 appsettings 文件,将 <code>Microsoft</code> 日志级别设置为 <code>Warning</code> 。<br>
或者, 您可以通过将 <code>Default</code> 和 <code>System</code> 的最小日志级别设置为 <code>Error</code> 来进一步限制日志记录, 如下所示。</p>
<pre><code>"Logging": {
"LogLevel": {
"Default": "Error",
"System": "Error",
"Microsoft": "Warning"
}
}
</code></pre>
<h3 id="尾声">尾声</h3>
<p>传统的方法,日志记录需要大量的前期工作才能启动和运行。因此,日志记录通常会被完全遗漏,或者写入到难以访问的服务器上的某些模糊的文本文件里。</p>
<p>ElasticSearch 和 Kibana 改变了这一切。而 Docker 已经使 ElasticSearch 和 Kibana 的启动和运行变得毫不费力。ElasticSearch 和 Kibana 提供的强大功能以及非常高的性能,再加上它是开源的,这真的令人印象非常深刻。</p>
<p>即使没有像 Serilog 这样的插件,与传统 ASP.NET 相比,ASP.NET Core 中的日志记录也变得更加容易,因此, 在创建可扩展的日志记录框架方面, 我对 .NET Core 团队表示赞赏。Serilog 简单地构建在此之上,并且扩展了功能,以使 .NET Core 开发人员的日志记录变得更简单。</p>
<p>通过组合 Docker,ElasticSearch,Kibana,ASP.NET Core 和 Serilog ,您获得了前所未有的便利性和功能,再也没有理由不再将日志记录整合到应用程序中了。</p>
<h3 id="下载源代码">下载源代码</h3>
<p>下载源代码 : https://github.com/thecarlo/elastic-kibana-netcore-serilog</p>
<h3 id="资源">资源</h3>
<p>Download .NET Core 2.1 SDK<br>
ElasticSeach<br>
Kibana<br>
Serilog<br>
Serilog.Sinks.ElasticSearch Nuget Package</p><br><br>
来源:https://www.cnblogs.com/Rwing/p/logging-with-elasticsearch-kibana-asp-net-core-and-docker.html
頁:
[1]