目录
介绍
背景
设置基础结构
设置解决方案
控制台文件
packages.config
appsettings.json
Program.cs中
LogProducer文件
BasicLogProducer.cs
配置,运行和测试
现代.NET应用程序的高级日志记录 周日早晨的概念证明。
介绍在本文中,您将学习如何设置开发环境以将Elasticsearch和Kibana用于日志记录。在此过程中,您将使用Docker,非常基本的用法,您还将了解在Windows经典桌面应用程序中使用.NET标准库是多么容易。
背景我将证明Elasticsearch和Kibana在我们的系统中的集成非常简单。为此,我将设置和配置Docker网络和两个Docker镜像,一个用于Elasticsearch,另一个用于Kibana。此基础结构将由Windows 经典桌面控制台使用,该控制台将执行一些随机日志记录。我将配置三个日志输出,控制台,并且使用Serilog,我将配置并使用滚动文件shink和Elasticsearch Shink。这些Shinks将在.NET Standard 2库中使用,但这个库将由控制台应用程序引用,使用最新的Microsoft Dependency Injection Extensions。
设置基础结构首先,我们需要在我们的机器中安装和配置好Docker,我使用Win10和Docker for Windows。(如果你没有它,你可以在这里找到它)。我们只需要运行三个命令来设置Docker的所有内容。(这太棒了,不是吗?)
- docker network create elk-logging-poc --driver=bridge
- docker run -p 5601:5601 --name kibana -d --network elk-logging-poc kibana
- docker run -p 9200:9200 -p 9300:9300 --name elasticsearch -d --network elk-logging-poc elasticsearch
第一个创建了一个在这个概念证明中使用的网络,第二个运行Kibana,如果它本地不存在则从Docker Hub中提取图像,第三个用于Elasticsearch。
初始状态:
- 创建网络:
- 安装并运行Kibana:
此时,安装了Kibana但是如果我们转到localhost:5601,我们可以看到Kibana缺少Elasticsearch:
安装Elasticsearch:
现在Kibana已准备好配置:
好吧,现在是时候设置我们的解决方案了,正如我所说,我将使用Windows经典桌面控制台应用程序和.NET标准库。所以,我将创建一个新的解决方案和WCD控制台项目:
提示:虽然它是POC,但我总是尝试使用强大的命名空间,我总是记住POC可以成为原型,然后是产品。这些事情发生了。
现在,让我们创建.NET标准库:
结果将如下所示:
为了节省您的时间,你需要安装在packages.config中列出的NuGet 包到控制台应用程序,容易手动安装。
packages.config
appsettings.json
{
"Logging": {
"IncludeScopes": true,
"Debug": {
"LogLevel": {
"Default": "Critical"
}
},
"Console": {
"LogLevel": {
"Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
"Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
"Microsoft.AspNetCore.Mvc.Razor": "Error",
"Default": "Critical"
}
},
"LogLevel": {
"Default": "Critical"
}
},
"Serilog": {
"WriteTo": [
{
"Name": "Elasticsearch",
"Args": {
"nodeUris": "http://localhost:9200;http://remotehost:9200/",
"indexFormat": "elk-poc-index-{0:yyyy.MM}",
"templateName": "myCustomTemplate",
"typeName": "myCustomLogEventType",
"pipelineName": "myCustomPipelineName",
"batchPostingLimit": 50,
"period": 2000,
"inlineFields": true,
"minimumLogEventLevel": "Trace",
"bufferBaseFilename": "C:/Logs/docker-elk-serilog-web-buffer",
"bufferFileSizeLimitBytes": 5242880,
"bufferLogShippingInterval": 5000,
"connectionGlobalHeaders":
"Authorization=Bearer SOME-TOKEN;OtherHeader=OTHER-HEADER-VALUE"
}
}
],
"LogFile": "C:/Logs/ElasticSearchPoc.log",
"MinimumLevel": "Information"
}
}
Program.cs中
using ElasticSearchPoc.Domain.LogProducer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using System;
namespace ElasticSearchPoc.Presentation.WCD.Console
{
class Program
{
static void Main(string[] args)
{
// Create service collection
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// Create service provider
var serviceProvider = serviceCollection.BuildServiceProvider();
// Run app (Every execution should create a new RunId)
serviceProvider.GetService().Run();
}
private static void ConfigureServices(IServiceCollection serviceCollection)
{
// Build configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", false)
.Build();
// Add console logging
serviceCollection.AddSingleton(new LoggerFactory()
.AddConsole(configuration.GetSection("Logging"))
.AddSerilog()
.AddDebug());
serviceCollection.AddLogging();
// Add Serilog logging
Log.Logger = new LoggerConfiguration()
.WriteTo.RollingFile(configuration["Serilog:LogFile"])
.ReadFrom.Configuration(configuration)
.CreateLogger();
// Add access to generic IConfigurationRoot
serviceCollection.AddSingleton(configuration);
// Add the App
serviceCollection.AddTransient();
}
}
}
我想添加一些关于这些文件的评论,看一下appsettings.json中的不同日志级别,以及Elasticsearch选项,设置是这个POC的关键。另外,我想强调一下我们程序的源代码是干净的和SOLID,我必须公开表示感谢.NET基础库及其贡献者对这些非常有用的库和扩展。
我们来看看.NET标准库中的文件LogProducer。
LogProducer文件正如您将看到的,它唯一的依赖是Microsoft.Extensions.Logging......
BasicLogProducer.csusing Microsoft.Extensions.Logging;
using System;
using System.Threading;
namespace ElasticSearchPoc.Domain.LogProducer
{
public class BasicLogProducer
{
private readonly ILogger _logger;
public BasicLogProducer(ILogger logger)
{
_logger = logger;
}
public void Run()
{
var runDate = DateTime.Now;
while (true)
{
// Let's randomize our logs...
Array values = Enum.GetValues(typeof(LogLevel));
Random random = new Random();
LogLevel randomLogLevel = (LogLevel)values.GetValue(random.Next(values.Length));
switch (randomLogLevel)
{
case LogLevel.Trace:
_logger.LogTrace($"RunDate: {runDate};
Message Id: {Guid.NewGuid()}; LogLevel: Trace;
LogLevelValue: {randomLogLevel.ToString("D")}");
break;
case LogLevel.Debug:
_logger.LogDebug($"RunDate: {runDate};
Message Id: {Guid.NewGuid()}; LogLevel: Debug;
LogLevelValue: {randomLogLevel.ToString("D")}");
break;
case LogLevel.Information:
_logger.LogInformation($"RunDate: {runDate};
Message Id: {Guid.NewGuid()}; LogLevel: Information;
LogLevelValue: {randomLogLevel.ToString("D")}");
break;
case LogLevel.Warning:
_logger.LogWarning($"RunDate: {runDate};
Message Id: {Guid.NewGuid()}; LogLevel: Warning;
LogLevelValue: {randomLogLevel.ToString("D")}");
break;
case LogLevel.Error:
_logger.LogError($"RunDate: {runDate};
Message Id: {Guid.NewGuid()}; LogLevel: Error;
LogLevelValue: {randomLogLevel.ToString("D")}");
break;
case LogLevel.Critical:
_logger.LogCritical($"RunDate: {runDate};
Message Id: {Guid.NewGuid()}; LogLevel: Critical;
LogLevelValue: {randomLogLevel.ToString("D")}");
break;
case LogLevel.None:
default:
break;
}
Thread.Sleep(100);
}
}
}
}
虽然我总是尝试编写不言自明的源代码,但这个类值得一个简短的解释。它使用DI(依赖注入),ILogger正在创建,因为主机应用程序已注册ILoggingFactory和Serilog,因此记录器将具有我们在主应用程序中配置的任何内容,在这种情况下我们的三个Shinks,控制台,文件和Elasticsearch。该Run方法获取初始运行日期并开始在每次迭代时生成具有随机日志级别的日志。这是非常基本但它会完成它的工作。
配置,运行和测试我不打算提供太多细节。我想通过一些屏幕截图,您可以自己尝试一下。我们要做的第一件事就是在Kibana中配置主索引模式,正如您所看到的,具体而言这是我们在appsettings.json文件中具有的配置参数之一。我使用过"indexFormat": "elk-poc-index-{0:yyyy.MM}",所以我们必须像“ elk-poc-index-*” 那样配置Kibana索引:
好吧,让我们启动我们的应用程序,看看会发生什么......
根据配置参数,控制台仅记录关键:
我们也正在记录到一个文件,如配置文件中所述,在我们的Main方法中,我将用几个截图来演示如何使用我知道的最好的Tail工具,Tail Blazer(如果你读到这一点,你不知道TailBlazer,那么你必须现在去尝试,因为你会喜欢它):
- 平台输出:
- 点击右上角的齿轮图标,我们可以添加一些亮点:
- 而且在主窗口中,我们可以添加一些过滤器:
我会添加Fatal过滤器,所以只看到带有Fatal关键字的条目:
Elasticsearch和Kibana怎么样?好吧,当我正在做这些截图时,控制台应用程序已经在控制台(仅限关键)中生成日志,在本地文件系统中的文件系统中具有信息级别,就像我们刚刚通过TailBlazer看到的那样,程序已经发送了日志到带有跟踪级别的Elasticsearch Shink,所以,如果我们转到Kibana并选择左侧菜单上的Timelion菜单项,我们应该能够看到一个图表,显示收到的日志数量,如下所示:
这个图是有意义的,因为代码每秒发送大约10个日志,因为有一个Thread.Sleep(100),对吗?让我们强制应用程序一点,并将睡眠设置为仅10毫秒。如果我再次运行它,时间轴看起来像这样:
如果我退出睡眠并强制我的机器生成尽可能多的日志怎么办?
好吧,文件日志增长得非常快,正如预期的那样(蓝色表示最近创建的,查看时间戳中的毫秒):
CPU达到100%(正如预期的那样):
Kibana的峰值达到每秒772个记录。考虑到一切都在同一台机器上运行并且我正在调试和监视日志文件,这不是太糟糕,我们可能会强制它更多。
而且,嗯,今天就这样了,我仍然不知道如何使用Kibana正确地显示数据,但POC在这里完成,因为它按预期记录。
原文地址:https://www.codeproject.com/Articles/1218350/Elasticsearch-Kibana-and-Docker-using-NET-Standard