使用 Logstash 可靠性和可用性记录到 elasticsearch,处理丢失的日志?

时间:2021-05-02 07:41:52

标签: c# elasticsearch logstash serilog fluentd

我正在关注 ELK 上的这篇文章:Building Logging System in Microservice Architecture with ELK Stack and Serilog .NET Core,在这种架构中,serilog 记录到 Logstash,然后将 logstash 推送到 Elastic 搜索,如果弹性搜索不可达或如果 logstash 服务关闭或如果网络宕机或系统宕机,总之我要去哪里,我如何确保我的日志在所有场景中都不会丢失,日志也应该离线可用,我想先存储在日志中文件,然后将日志从文件处理到弹性搜索,但是文件会在一段时间内增长,然后我必须注意没有重复的消息并且消息也需要删除,最重要的是没有读写文件时出现死锁的情况,能否请您帮我了解一下ELK是否小心,如果我使用fluend或fluentbit而不是logstash,它们更好吗??

代码:

var log = new LoggerConfiguration()
         .WriteTo.Console()
         .WriteTo.Http("http://localhost:8080")
         .CreateLogger();


while (true)
{
    var customer = Customer.Generate();
    log.Information("{@customer} registered", customer);
    Thread.Sleep(1000);
}

输出:

[13:56:02 INF] {"FirstName": "Lourdes", "LastName": "Kreiger", "SSNumber": "350-11-7869", "$type": "Customer"} registered
[13:56:03 INF] {"FirstName": "Desmond", "LastName": "Balistreri", "SSNumber": "929-58-1854", "$type": "Customer"} registered
...

使用 ELK 发送日志

Http 输入监听端口 8080

input {
    http {
        #default host 0.0.0.0:8080
        codec => json
    }
}

# Separate the logs
filter {
    split {
        field => "events"
        target => "e"
        remove_field => "events"
    }
}

# Send the logs to Elasticsearch
output {
    elasticsearch {
        hosts => "elasticsearch:9200"
        index=>"customer-%{+xxxx.ww}"
    }
}

1 个答案:

答案 0 :(得分:1)

您有两个可能导致数据丢失的主要故障点,logstash 和 elasticsearch 之间的通信以及您的服务和 logstash 之间的通信。

logstash 和 elasticsearch 之间的通信

当发送数据到elasticsearch时,logstash默认使用管道的input块和filter块之间的内存队列,这个队列的存在是为了在logstash无法与之通信的情况下存储事件弹性搜索。

这个内存队列有固定大小的 1000 个事件,所以如果你每秒有很多事件,它没有多大帮助。您可以更改管道以使用 persisted queue,此队列将执行与内存中队列相同的操作,但它会写入 logstash 服务器中的文件,您可以更改文件大小以存储更多事件.

如果持久化队列已满,elasticsearch 仍然关闭,logstash 将停止接受新的事件,队列何时会填满完全取决于队列的大小、事件的大小和事件的速率,但持久化队列是您可以避免在 logstash 和 elasticsearch 之间丢失数据的方法之一。

服务和logstash之间的通信

如果您的服务无法与 logstash 通信,那么您需要在其上实现一些逻辑以避免数据丢失。如何做到这一点完全掌握在您的手中。

您可以复制 logstash 使用的持久队列并将未发送到 logstash 的事件写入文件,然后在 logstash 返回时重播这些事件。

这将添加许多您需要自己实现的额外内容。

替代方案

我认为最好的方法是将日志写入日志文件,然后使用 filebeat 将这些日志发送到 logstash,如果您不想在 logstash 中使用任何过滤器,甚至可以直接发送到 elasticsearch ,filebeat 可以在输出服务不可达的情况下自动重试发送日志,并跟踪已发送或未发送的内容。

由于您使用的是 dotnet,因此您可以使用 log4net 进行日志记录,它会处理日志记录部分,并在达到指定大小时轮换您的日志。

相关问题