上一次我们介绍并演示了如果使用 Consul 做为我们微服务的注册中心,来实现服务的注册与发现。那么本次我们讲会演示如何做日志聚合。日志聚合比较常用的有 ELK 等,但是这次我想要介绍的是一款比较小众的日志聚合工具 - Seq 。
日志是我们写程序离不开的一个东西。在我们排查问题的时候日志就是我们的救命稻草。我们的每个服务都在不停的生产日志。但是实施微服务后,如果按照传统的写本地文件的日志方案,显然会面临跟修改配置一样麻烦的境地。不同的日志分散在各个服务器、容器内,这种情况下查日志简直是生不如死。
日志聚合组件为我们解决了这个问题。所有的服务通过接口发送日志到聚合服务,再由聚合服务进行统一存储,并且提供统一的查询、分析的能力。
日志聚合组件业界有 ELK、Exceptionless、Seq
等。
Seq
是一款使用现代化技术构建的结构化日志存储,查询,分析工具。比起 ELK 这种组合要轻量级许多。只需要一个安装包就具有数据存储,查询,图表分析功能。它对 windows 友好,直接提供了安装包。当然也可以使用 docker 来部署。Seq 对于单个用户是免费的,这对于一些小团队并没有什么问题。Seq 一个比较强大的功能是提供了类似 Sql 语句的数据查询及处理能力,使得用户可以直接写 Select from 来得到自己想要的数据。
seq 的 dashboard 页面。
seq 的查询界面。
seq 网址
docker run --name seq -e ACCEPT_EULA=Y -p 8900:80 -p 5341:5341 datalust/seq
使用 docker run
运行一个实例。8900 绑定容器的 80 端口,该端口是 web 管理界面的入口。5341 绑定容器的 5341 端口,该端口是日志写入时候真正的端口。
docker-compose
安装 seq_server:
image: datalust/seq
restart: always
container_name: seq_server
hostname: seq_server
environment:
- ACCEPT_EULA=Y
ports:
- 8900:80
- 5341:5341
把上面的 docker
命令改写成 docker-compose
命令。
安装好 seq
之后,我们访问一下 http://localhost:8090
如果管理后台出现说明我们安装成功了。
NLog
集成 Seq
seq
安装成功之后,我们可以开始跟 asp.net core
项目进行集成了。这里采用 Nlog
日志组件进行演示,如何跟 seq
集成。
点击 “API KEYS” 、“ADD API KEY” 弹出新增 API KEY 界面。
我们可以在这个界面为每个服务指定一个 APIKEY
当写入 Seq
的是用来区分服务。填写 title
信息,选择具有的权限,还可以自定义一些属性,这些属性会附加到每个日志记录上。比如我们这里为 member_center
这个 apikey
自定义一个 app = member_center
的属性。
Install-Package NLog.Targets.Seq
nuget 安装 Nlog
的 Seq
扩展。
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="info"
internalLogFile="logs/internal-nlog.txt">
<extensions>
<add assembly="NLog.Targets.Seq"/>
extensions>
<targets>
<target xsi:type="Null" name="blackhole" />
<target name="seq" xsi:type="BufferingWrapper" bufferSize="1000" flushTimeout="2000" >
<target xsi:type="Seq" serverUrl="http://192.168.18.164:5341" apiKey="vuRYxr8bMXuvKNbwVNUp">
<property name="ThreadId" value="${threadid}" as="number" />
<property name="stacktrace" value="${onexception:inner=${stacktrace}}"/>
target>
target>
targets>
<rules>
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Trace" writeTo="seq" />
rules>
nlog>
在项目根目录添加一个 nlog.config
的 xml
配置文件。添加一个 seq
的 target
,在这个 target
上填写 serverUrl
(seq的服务地址),apiKey
。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(options =>
{
options.ListenAnyIP(6003);
});
webBuilder.UseStartup<Startup>();
})
.UseNLog();
在 Program
文件的 CreateHostBuilder
方法最后追加 UseNLog
调用。
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
private readonly ILogger _logger;
public TestController(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<TestController>();
}
[HttpGet("TestLogSeq")]
public string TestLogSeq()
{
_logger.LogTrace("this is a test log for trace level .");
_logger.LogDebug("this is a test log for debug level .");
_logger.LogInformation("this is a test log for info level .");
_logger.LogWarning("this is a test log for warning level .");
_logger.LogError(new Exception("this is a ex for seq log ."), "this is a test log for error level .");
return "ok";
}
}
添加一个 TestController
编写一个 TestLogSeq
方法,在这里打一些日志。
我们访问一下这个接口,打开 seq
的站点可以看到我们的日志已经写到 seq
里面了。
我们的服务每天都会产生数以万计的日志,现在把所有服务的日志都聚合在一起,那数量就更加庞大。在海量日志中查找需要的日志,显然变得很困难。
还好 Seq
带有强大的查询功能。我们可以像在数据库里查询那样,使用 Sql 语句来进行查询。
下面演示几个查询例子:
like
查询@Message like '%init%'
@Level = 'Error'
app = 'hotel_base'
查询所有 hotel_base
服务的日志。
3. 聚合函数
select count(1) from stream group by @Level
以上简单的演示了几个查询方案,Seq
的查询相当的强大,具体请查考官方文档:the-seq-query-language
通过以上内容,我们简单的演示了 Seq
日志聚合工具的安装、与.net core
进行集成,查询日志等功能。Seq
虽然比起 ELK
比较冷门,但是最近跟一些朋友交流下来,发现很多朋友都开始使用 Seq
来做为日志聚合工具了。这也说明 Seq
确实有一定的实力,大家不妨一试。