当第一次使用分布式日志记录时,开发人员的第一反应可能是将应用程序日志直接从应用程序发送到日志后端。直接联系很有吸引力:毕竟,要管理的活动部件更少了。这种通信通常发生在事务性REST api上,给开发人员一种错误的安全感,以为他们的所有日志都可以通过。

不幸的是,这种模式有三个弱点:

  1. 反压力在HTTP请求中可能会扰乱仪器代码的正常功能,特别是如果日志达到意外大小或速率。
  2. 将数据发送到日志后端时,延迟可能导致日志数据的传输中的滞后。
  3. 网络连接问题可能导致丢失的日志,当代理从APM instrumented应用程序与中断相关时尤其困扰。

现场可靠性工程的一个核心原则是不断观测系统的遥测数据,使系统不那么脆弱。将你的日志转发器从你的应用程序中解耦绝对可以让你的系统不那么脆弱:当您将转发器与应用程序代码解耦时,您就能够在单独的进程中保持复杂的处理计算,并更频繁地更新转发器的代码或配置,而不必担心会影响底层应用程序。

此外,还内置了日志转发器基于内存或文件的缓冲这为应用程序数据中心和日志后端之间的各种延迟和中断提供了关键的灵活性。

日志转发器也可以:

  • 扩展到支持比底层应用程序代码更广泛的网络协议和输出格式
  • 在基础设施级别进行分离(即,您可以在不同的主机或不同的容器中运行它们)
  • 负载平衡
  • 用于复杂的管道,实现上游聚合和持久缓冲

在本文中,我将分享使用日志转发器向日志后端交付日志的五种企业级模式,例如New Relic的日志- 一个中央组成部分New Relic的一.这些模式将使您大致了解可以通过减少延迟、错误和饱和度来降低整个日志管道的脆弱性的实际选择。我的目标是揭开分布式日志记录过程的神秘面纱,并提供您现在可以使用的实用模式。

选择日志转发器

Logstash(ELK栈的一部分),Rsyslog, 和Fluentd常见且相对容易使用日志转发器。像Wayfair一样的较新的货运地震timber.io.s向量建成高性能用例,但超出了本文档的范围,以比较和对比所有文件。

New Relic Infrastructure代理支持日志转发通过流畅的位延伸。配置通常兼容流畅的比特语法。如果部署基础架构代理,则使用内置的转发器会发出日志是方便的。在此帖子中,我的示例配置将使用Fluent和Fluent Bit作为独立的代理。您可以在无法安装基础架构代理或希望使用集中转发层来处理多个分布式源的场景中使用它们。

笔记:除了Fluentd和Fluent位,Logstash和Vector还为新的遗录日志提供插件。此处未列出的其他转发器可能具有灵活的配置选项,您可以使它们能够将日志发送到任何后端,包括新遗物。

考虑以下特征以确定是否需要Fluentd或Fluent Bit:

凡好

cons

Fluentd

  • 数以百计的插件可用

  • 接收频繁的更新


  • 建于Ruby并需要多个Ruby Gem依赖项

  • 高端内存占用

流利一些

  • 用C语言编译,没有额外的依赖项

  • 低内存占用

  • 适用于物联网和嵌入式系统


  • 接收较少的更新

  • 只有15个插件可用

安装Fluentd或流利的位

New Relic Logs提供了一个快速、可扩展的日志管理平台,允许您将日志数据与其余的遥测数据连接起来。Fluentd和Fluent Bit(和其他)的预构建插件使您可以简单地将数据从任何地方发送到New Relic One。

查看用于安装和配置说明的新遗物文档:

以下示例假设您要将日志转发给新遗物,在这种情况下,您需要一个New Relic许可密钥.如果您还没有许可证密钥,但要测试基本转发功能,则可以下载转发器(请参阅下面的链接)并将其配置为写入输出文件用于测试目的。

注意:构建用于包管理器的这些工具的叉子遵循命名惯例td-agent(Fluentd)和TD-Agent-bit(流利的位)。

流利的包:

FLUENTD包裹:

现在让我们看看五个模式,用于将日志转发给新的遗物,或者要使用的附件)。对于我们来看看PROF和COM的每个模式,我还包括一些示例配置。

图案1:共同定位的转发器,带有文件剪

在这个模式中,您将使用一个文件尾程序来监视一个或多个日志文件,并在它们被写入时将新行发送到日志后端。转发器位于应用程序主机上的两个应用程序之间。大多数转发器有丰富的配置选项,以确定到底如何跟踪工作,以及在发送到日志后端时将使用哪种缓冲。为了获得额外的可伸缩性,位于同一位置的转发器还可以转发到脱机转发器层(类似于下面讨论的模式3)。

模式1的优点

  • 此模式使用应用程序基础架构自动缩放,因为每单位基础架构有一个转发器。
  • 由于此模式使用日志文件,因此您可以将日志转发到遗留应用程序中,您可能无法使用现代记录工具重建。

模式1的缺点

  • 每个转发器都可能消耗大量的计算资源,这可能会增加应用程序基础设施的系统性部署。
  • 共同定位的转发器的配置成为每个应用程序配置的依赖性,它可以增加应用程序配置和部署的复杂性。
  • 在峰值负载点时,日志文件可以长大地增长,即文件剪报器(以及日志旋转实用程序)可能无法跟上,导致日志滞后和可能的存储问题。

图案1的示例配置

笔记:这里的示例(以及本文其余部分的示例)引用了Python APM代理记录器配置。有关如何使用Python代理在上下文中完全配置日志的示例,看文档.另外,看看在设置日志处理程序时官方Python文档以确保正确设置输出。

..#实例化一个新的日志处理程序handler = logging.fileHandler('/ var / log / app-a.log')。。

Fluentd

 @type tail  @type none  path /var/log/app-a.log tag app-a   @type tail  @type none  path /var/log/app-b.log tag app-b   @type newrelic license_key  base_uri https://log-api.newrelic.com/log/v1 

流利一些

[输入]名称尾路径/var/log/app-a.log.[输入]名称尾路径/var/log/app-b.log.[OUTPUT] Name newrelic Match * licenseKey  .输出说明

模式2:使用套接字的同位转发器

在此模式中,应用程序代码将通过UDP或TCP端口直接将日志发送给转发器(不存储文件),转发器将依次将日志异步转发给New Relic(使用新的遗物日志API).转发器位于你的应用程序和New Relic后端之间,并提供了一个最小的缓冲区和处理层。

笔记:它超出了这篇文章的范围,为您是否应该使用提供指导UDP vs TCP..一般来说,UDP对应用程序的影响最小,但是协议的交付保证较低。由于这个原因,大多数高容量日志环境最终将倾向于使用UDP将日志发送到转发器。某些安全应用程序,例如SIEM软件仍然倾向于使用TCP来确保完整性。

模式2的优点

  • 此模式使用应用程序基础架构自动缩放,因为每单位基础架构有一个转发器。
  • 此模式使用套接字协议进行日志输入,因此不需要存储或旋转文件。而且由于转发器是在同一地点,网络开销很低。
  • 一台转发器可以从可以通过网络接口访问它的任何应用程序接收日志。

模式2的成本

  • 每个转发器都可能消耗大量的计算资源,这可能会增加应用程序基础设施的系统性部署。
  • 共存转发器的配置成为每个应用程序配置的依赖项,这可能会增加应用程序配置和部署的复杂性。
  • 您将没有物理日志文件,可以用来对主机上的应用程序进行故障诊断(除非您将其作为另一种配置编写)。
  • TCP协议仍然会对应用程序造成反压力。
  • 你需要优化TCP和UDP这个用例的内核参数。
  • 你需要监控系统遥测,例如:
    • UDP缓冲区(用于UDP)
    • UDP缓冲区接收错误
    • TCP错误

模式2的示例配置

UDP.

# UDP示例。#实例化一个新的日志处理程序DatagramHandler(' localhost ', 5160) . .

TCP.

#TCP示例。#实例化一个新的日志处理程序handler = logging.sockethandler('localhost',5170)。。

Fluentd

 @type udp  @type none  tag udp_5160 port 5160 bind 0.0.0.0   @type tcp tag tcp_5170  @type none  port 5170 bind 0.0.0.0   @type newrelic license_key  base_uri https://log-api.newrelic.com/log/v1 

流利一些
笔记:UDP不被支持为Fluent位的内置插件。

[INPUT] Name tcp Listen 0.0.0.0 Port 5170 [OUTPUT] Name newrelic Match * licenseKey 

模式3:使用插座分别定位转发器

在此模式中,您的日志转发器位于应用程序主机之外。您的应用程序代码将在UDP或TCP端口发送到转发器的日志,转发器又将使用log api.(封装在其新的遗物输出插件中)将它们转发给新的遗物。

将转发器移动到独立的基础设施中,可以获得计算资源利用率方面的规模经济,并集中了日志转发器基础设施的配置和维护。使用这种模式,不同的应用程序家族可以将日志数据发送到相同的基础设施池中。如果需要,您甚至可以使用不同的端口或协议以及模式匹配来对来自不同来源的日志进行自定义处理。

模式3的优点

  • 在此模式中,您拥有特定的基础架构,专门配置为处理日志;您不需要将转发器提供作为应用程序基础架构的一部分。
  • 您可以将不同应用池中的日志发送到同一个日志转发池中。
  • 您将消除反压力,因为您可以独立于应用程序伸缩转发器。
  • 您可以使用许多强大的方法来实现持久缓冲区;例如,您可以使用Apache卡夫卡将日志存储在将它们运送到新的遗物一个或您的日志后端。

模式3的缺点

  • 您将没有物理日志文件,可以用来对主机上的应用程序进行故障诊断(除非您将其作为另一种配置编写)。
  • 您必须使用独立配置维护一类新的基础架构。
  • 您仍然可能遇到“热发送方”应用程序的问题,该应用程序可能会淹没转发器池中的一个转发器。(在下一个模式中,我将展示如何在转发器池前使用负载平衡层来消除这个问题。)

模式3的示例配置

您的Python代理日志记录配置与模式2几乎相同,但有必要使用转发器主机的公共IP或DNS名称:

handler = logging.DatagramHandler(' forwarder1.host.mycompany.com ', 5160)

模式4:单独定位转发器,负载平衡

如在先前的模式中,转发层位于应用外部。但是,在这种情况下,转发层安装在负载平衡器层后面。您的应用程序代码将日志发送到转发层前面的负载平衡层,通常通过UDP端口,负载均衡器基于公共负载平衡规则将数据发送到转发器的适当实例(例如,循环).每个转发器都与前一个模式中的转发器相同配置。

从根本上说,除了负载平衡器层之外,该转发池的配置没有什么不同。在这种情况下Nginx负载均衡器将确保一个应用程序进程不会淹没一个特定的转发器。属性关联的轮询DNS资源将发送日志Nginx UDP负载均衡器

模式4的优点

  • 这种模式允许大规模的可伸缩性。
  • 这非常适合多租户日志转发基础设施。
  • 您将获得高可用性的日志转发基础架构。
  • 来自“热发送者”的日志记录“峰值”将被更好地分布,这样一个可能发送过多日志的应用程序就不会阻塞转发端点。

模式4的缺点

  • 您需要维护具有独立配置的新基础架构类。

模式4的示例配置

您的Python日志记录配置与图案2和3几乎相同,但有必要使用与Nginx负载均衡器相关联的DNS名称。

handler = loging.sockethandler (' loglb.mycompany.com ', 5160)

配置负载平衡器如下:

# Load balance UDP - based DNS traffic across two servers stream {upstream dns_upstreams {server :5160;server :5160;服务器<转发3的IP 3的3>:5016;} server{监听5160 udp;proxy_pass dns_upstreams;proxy_timeout 1 s;proxy_responses 1;error_log日志/ log-lb.log;}}

模式5:日志解释和路由

这组模式可以与我们介绍过的任何其他数据传输模式混合使用。对于大多数企业用例,您需要充实、筛选并适当地路由日志。这些模式的实现往往依赖于转发器,但大多数常见的转发器将支持这些模式。(关于如何处理日志事件的更多背景知识,我推荐流行病活动的生活.)

凡好

  • 这组模式支持大规模的可伸缩性。
  • 这种模式可以缓解速率和日志大小的异常峰值,而不会导致转发器崩溃。

cons

  • 这些模式提供了一层复杂性,因为丢弃和路由日志数据会使日志流变得模糊。
  • 当您启用各种类型的过滤器时,转发器可以消耗大量的CPU和RAM资源。请务必以明智的方式使用过滤器。如果您使用的是多个过滤器,请先运行排除最多数据的过滤器,因此您不会不必要地处理要删除的数据。

让我们来看看过滤,丰富和路由的一些例子。

过滤

选择要在日志流中包含的日志。

Fluentd支持这一点匹配指令为每个输出插件。这匹配指令查找带有匹配标记的事件并处理它们。

  • 允许全部
    …New Relic account A..< / >匹配
  • 仅允许标记为来自某些应用程序的记录
    <匹配app.customer_info >…< / >匹配

需要注意的一个缺点是:如果转发器中有任何中间处理,即使您丢弃了该记录,每个记录也将收到该处理开销。你也可以在FluentD事件处理管道内过滤,允许您尽快丢弃不必要的记录。

…input configs…tag app-a  …input configs…过滤App-A …output configs… .

另一个非常有用的模式是删除或排除不需要的内容。你可以使用一个<排除>过滤器删除来自流的某些日志,例如包含个人身份信息(PII)的日志。

 @type grep 密钥消息模式/用户名/  

富饶

向流中的现有日志添加或修改内容。

充实通常需要向正在处理的记录中添加或更新一个元素。例如,Fluentd提供了许多操作符来实现这一点record_transformer

#添加host_param到每条记录。 @type record_transformer  host_param "#{套接字。gethostname} " > < /记录过滤器> < /

这些基本示例没有充分发挥Fluentd所支持的标记管理的全部功能。看到rewrite_tag_filter.文件对于如何使用的一些很棒的例子rewrite_tag_filter.插件将标签注入到记录中,这使得下游管道具有很大的灵活性。

路由

例如,将不同类型的日志发送到不同的后端(或者为单独的新遗物帐户)。

Fluentd支持了许多强大的功能路由技术这允许您将不同的事件发送到完全不同的后端。路由的两个实际例子是:

  1. 将日志从一个应用程序发送到特定的新遗物帐户,但将从所有其他应用程序发送到不同的新遗物帐户的日志。
  2. 将日志发送到两个不同的输出:a) New Relic和b)一个长期归档的云存储桶。

不要压倒你的系统

在现代的sre环境中,全栈的可观察性是至关重要的,有必要认真考虑上游日志实现将如何扩展,以及它如何对复杂广域网络上数据中心之间可能发生的各种延迟和中断进行弹性处理。

在某些异常情况下,即使是行为良好的应用程序也可能突然开始以每个日志意想不到的大小(多mb堆栈跟踪或对象转储)或以前无法预见的速度(每分钟数百万)发出日志。我所展示的模式提供了工具包的重要组成部分,以确保这些异常不会淹没系统的任何单个部分,并在可观察性方面造成不可接受的破坏。

如果您正在寻找更多来自我们专家的新的遗物日志内容,请不要错过如何在Kubernetes中运行的Java应用程序中设置日志

一定要请求一个演示New Relic Logs的今天!

Jim Hagan是一个基于波士顿的企业解决方案顾问,具有新的遗物。他拥有20年的软件工程师经验,具有地理空间技术和时间序列分析的专业知识。在加入新遗物之前,他在Wayfair的高度分布式测井和度量平台上工作。查看帖子

对新遗物博客的写作有兴趣吗?亚搏体育登入网给我们发个提案!!