Hi,各位朋友,大家好!欢迎大家关注我的博客,我的博客地址是: https://blog.yuanpei.me。今天是远程办公以来的第一个周末,虽然公司计划在远程两周后恢复正常办公,可面对着每天都有人离开的疫情,深知这一切都不会那么容易。窗外的阳光透过玻璃照射进屋子,这一切都昭示着春天的脚步渐渐近了。可春天来了,有的人却没有再回来。那些在2019年结束时许下的美好期待、豪言壮语,在这样一场灾难面前,终究是如此的无力而苍白。可不管怎么样,生活还是要继续,在这些无法出门的日子里,在这样一个印象深刻的春节长假里,除了做好勤洗手多通风戴口罩这些防疫保护措施以外,博主还是希望大家能够抽空学习,通过知识来充实这“枯燥”的生活。所以,从今天开始,我将为大家带来 .NET Core + ELK搭建可视化日志分析平台 系列文章,希望大家喜欢。

什么是ELK

当接触到一个新的事物的时候,我们最好是从它的概念开始入手。那么,什么是ELK呢?ELK,是ElastaicsearchLogstashKibana三款软件的简称。其中,Elastaicsearch是一个开源的全文搜索引擎。如果你没有听说过它,那至少应该听说过Lucene这个开源搜索引擎。事实上,ElastaicsearchLucene的封装,它提供了REST API 的操作接口 。而Logstash则是一个开源的数据收集引擎,具有实时的管道,它可以动态地将不同的数据源的数据统一起来。最后,Kibana是一个日志可视化分析的平台,它提供了一系列日志分析的Web接口,可以使用它对日志进行高效地搜索、分析和可视化操作。至此,我们可以给ELK一个简单的定义:

ELK是一个集日志收集、搜索、日志聚合和日志分析于一身的完整解决方案。

下面这张图,展示了ElastaicsearchLogstashKibana三款软件间的协作关系。可以注意到,Logstash负责从应用服务器收集日志。我们知道,现在的应用程序都是跨端应用,程序可能运行在PC、移动端、H5、小程序等等各种各样的终端上,而Logstash则可以将这些不同的日志信息通过管道转换为统一的数据接口。这些日志将被存储到Elasticsearch中。我们提到Elastaicsearch是一个开源的全文搜索引擎,故而它在数据查询上相对传统的数据库有着更好的优势,并且Elasticsearch可以根据需要搭建单机或者集群。最终,KibanaElasticsearch中查询数据并绘制可视化图表,并展示在浏览器中。在最新的ELK架构中,新增了FireBeat这个软件,它是它是一个轻量级的日志收集处理工具(Agent),适合于在各个服务器上搜集日志后传输给Logstash

ELK-01.png
ELK-01.png

总而言之,ELK可以让我们以一种更优雅的方式来收集日志,传统的日志收集通常会把日志写到文件或者数据库中。前者,不利于日志的集中管理和查询;后者,则无法应对海量文本检索的需求。所以,使用ELK可以为我们带来下面这些便利:分布式日志数据集中式查询和管理;系统监控,譬如对系统硬件和应用各个组件的监控;故障排查;报表功能;日志查询,问题排查,上线检查; 服务器监控、应用监控、错误报警;性能分析、用户行为分析、时间管理等等

如何安装ELK

安装ELK的方式,首推以Docker方式安装。关于Docker的安装、使用请大家查阅官方文档:https://docs.docker.com/。这里我假设大家都已经掌握了Linux和Docker的使用。首先我们拉取ELK镜像:

1
docker pull sebp/elk

接下来,我们利用此镜像来运行一个容器:

1
docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 --name elk sebp/elk

通常情况下,完成这两个步骤以后,我们就完成了ELK安装。此时,我们可以在浏览器中输入地址:http//localhost:9200,这是Elasticsearch的默认端口。如果浏览器中返回了了类似下面的信息,则表示ELK安装成功。这里是博主获得的关于Elasticseach的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "elk",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "GGlJrOvtT2uSfoHioLCWww",
"version" : {
"number" : "7.5.2",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "8bec50e1e0ad29dad5653712cf3bb580cd1afcdf",
"build_date" : "2020-01-15T12:11:52.313576Z",
"build_snapshot" : false,
"lucene_version" : "8.3.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

接下来,我们继续在浏览器中输入地址:http://localhost:5601/app/kibana。显然,这是Kibana的默认地址,至此ELK的“庐山真面目”终于揭晓,首次安装完ELK,Kibana的界面应该试类似下面这样:

ELK的庐山真面目
ELK的庐山真面目

按照指引,我们可以添加示例数据来感受下ELK全家桶的魅力:

ELK示例 - Global Flight Dashboard
ELK示例 - Global Flight Dashboard

这样,我们就完成ELK环境的快速搭建。下面,按照惯例,我们将实现一个“Hello World”级别的实例,即:通过ELK来收集一个ASP .NET Core应用的日志信息。为了让这个示例尽可能地简单一点,我们选择了直接向Elasticsearch写入日志的方式,这里选择的日志库是Serilog

Hello ELK

本文所用的例子已发布到Github。首先,我们准备一个ASP.NET Core的项目,MVC或者Web API都可以。接下来,在项目中引入三个依赖项:SerilogSerilog.Extensions.LoggingSerilog.Sinks.ElasticSearch。对于前两个,如果大家用过Log4Net或者NLog应该会感到非常熟悉啦,这一点不在赘述。而第三个,从名字就可以看出来这是冲着Elasticsearch来的,因为这是这个系列的第一篇文章,所以,我们直接写Elasticsearch即可。Logstash管道相关的内容,是一个非常复杂的东西,我们会在下一篇文章中单独来讲。

接下来,主要是Serilog在ASP.NET Core中的配置。首先是Startup类,在构造函数中初始化Serilog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Startup(IConfiguration configuration)
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Debug()
.WriteTo.Elasticsearch(
new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
{
MinimumLogEventLevel = LogEventLevel.Verbose,
AutoRegisterTemplate = true
})
.CreateLogger();
Configuration = configuration;
}

还记得http://localhost:9200这个地址是什么吗?不错,这是Elasticsearch的默认地址,所以,这部分代码主要的作用就是告诉Elasticsearch,接下来的日志信息都写到Elasticsearch中。为了让日志的信息更丰富一点,我们这里设置最小的日志事件级别为Verbose

接下来,在ConfigureServices()方法中注册ILogger实例:

1
services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));

接下来,在业务层增加日志:

1
2
3
4
5
6
7
8
private readonly ILogger _logger = Log.Logger;

[HttpGet]
public double Add(double n1, double n2)
{
_logger.Information($"Invoke {typeof(CoreCalculatorService).Name}/Add: {n1},{n2}");
return n1 + n2;
}

至此,ELK在ASP.NET Core中的集成已经全部结束,这意味着我们所有的日志都会写入到ELK中。那么,要到那里去找这些日志信息呢?且听博主娓娓道来。我们在Kibana中点击左侧导航栏最底下的设置按钮,然后再点击右侧的Create index pattern按钮创建一个索引。什么叫做索引呢?在Elasticsearch中索引相当于一张”表”,而这个“表”中的一条行记录则被称为Document,如图:

为Kibana创建索引1
为Kibana创建索引1

创建索引的时候,会发现列表中列出了目前Elasticsearch中可用的数据。以博主为例,这里的logstash-2020.02.15就是本文中的ASP.NET Core应用产生的日志信息。在这里,我们可以通过一个模糊匹配来匹配同种类型的数据。通常这里需要我们选择一个过滤字段,我们选择时间戳即可:

为Kibana创建索引2
为Kibana创建索引2

创建完索引,就可以看到目前收集的日志信息了,在此基础上,我们可以做进一步的检索、过滤,来生成各种各样的“查询”。而每一个“查询”实际上就是一个数据源。我们就可以利用这些数据源来完成可视化,这是利用ELK进行可视化分析的一般流程:

在Kibana中查看当前日志信息
在Kibana中查看当前日志信息

下面是博主自己制作的一个简单的可视化看板,果然很长时间没有再用过Kibana,我都快忘记了要怎么做一个折线图。这实在是一篇迟到的博客,我早该在2019年的时候就完成这个系列的,这要命的拖延症啊,虽然没有新冠病毒恐怖,可终究不是什么好习惯!

一个简单的可视化看板
一个简单的可视化看板

本文小结

这篇博客是这个系列的第一篇,是一篇珊珊来迟的博客,因为博主早在2019年就开始着手学习ELK。考虑最新公司有使用ELK的打算,而因疫情又让博主有充足的时间,所以,博主决定把ELK相关的内容花点时间梳理出来。ELK是一个集日志收集、搜索、日志聚合和日志分析于一身的完整解决方案。博主计划在接下来的篇幅中介绍Logstash/FireBeat管道配置、Docker容器内的日志收集、以及自定义日志组件开发这些话题,希望大家继续关注我的博客。以上就是这篇博客的全部内容啦,晚安!