AWS无服务器的最终崩盘价格:使用Kinesis和Lambda进行中心化日志记录

当API失败并且您完全不知道为什么时,您是否只是讨厌它?现在假设您无法访问运行软件的VM,群集或容器。想让我继续这个噩梦吗?

是的,这就是调试AWS Lambda函数看起来的样子。一个可怕的噩梦,不知道发生了什么,也不知道为什么事情会失败。本文将向您展示一种记录函数调用的方法。让您跟踪和监控故障和错误,同时还为您提供了一个很好的结构,用于在需要对行为进行故障排除时记录信息和调试日志。

关键是将所有日志发送到中央位置,以便稍后对其进行分组,过滤和理解。 Sematext是整个软件堆栈的全栈可观察性解决方案。这意味着您可以在任何现有基础架构(如Kubernetes集群和容器)旁边实现功能日志记录。

准备?让我们开始吧

使用CloudWatch进行日志

CloudWatch是显示AWS Lambda日志的默认解决方案。

CloudWatch以日志,指标和事件的形式收集监控和运营数据,为您提供在AWS和本地服务器上运行的AWS资源,应用程序和服务的统一视图。

– AWS文档

通俗地说,它是一种AWS服务,用于在所有AWS服务中显示您的日志。我们想知道它如何处理AWS Lambda日志。当Lambda函数执行时,无论您写入控制台,Go中的fmt.printf()或Node.js中的console.log()都将在后台异步发送到CloudWatch。幸运的是,它不会给函数执行时间增加任何开销。

在函数运行时使用日志记录代理会增加执行开销并增加不必要的延迟。我们希望避免这种情况,并在将日志添加到CloudWatch后处理它们。您可以在下面看到从通用Hello World函数生成的示例日志事件。

让我们退后一步,看看更大的图景。每个函数都会在CloudWatch中创建一个称为日志组的东西。单击特定的日志组。

这些日志组将包含日志流,这些日志流实际上等同于来自特定功能实例的日志事件。

对于系统洞察力以及对软件正在做什么的正确概述,这几乎不是一个足够好的解决方案。由于它的结构,很难看到和区分日志。使用日志的中心位置更有意义。您可以使用自己的Elasticsearch或托管设置。 Sematext为您的基础架构的每个部分提供了全栈可观察性,并公开了Elasticsearch API。让我向您展示创建AWS Lambda函数的CloudWatch日志处理并将它们传输到Sematext Logs应用程序是多么容易。

创建中心化日志解决方案

通过使用CloudWatch日志组订阅和Kinesis,您可以将所有Lambda日志汇集到一个专用函数,该函数将它们发送到Sematext的Elasticsearch API。在那里,您拥有所有日志的中心位置。您可以搜索和过滤所有功能的日志,只需很少的工作就可以深入了解功能的行为和健康状况。

我将演示如何构建一个可以自己使用的单命令部署解决方案。它是使用无服务器框架和Node.js构建的。但是,您可以随意使用AWS SAM或Terraform以及您想要的任何编程语言。这个概念将保持不变。

这是最终的样子。

比CloudWatch更漂亮,你可以找到你想要的东西

设置无服务器项目

首先安装无服务器框架,配置您的IAM用户,并创建一个新项目。完整的指南可以在这里找到。

$npm install -g serverless
$sls配置凭据
– 提供者aws
–key xxxxxxxxxxxxxx
–secret xxxxxxxxxxxxxx
$sls create –template aws-nodejs –path lambda-cwlogs-to-logsene
$cd lambda-cwlogs-to-logsene
$npm init -y
$npm i logsene-js zlib serverless-iam-roles-per-function

甜现在转到serverless.yml。

配置资源

在代码编辑器中打开lambda-cwlogs-to-logsene目录并查看serverless.yml。随意删除所有内容并将其粘贴。

让我们一块一块地分解它。托运者功能将由Kinesis流触发,并且它具有一些用于配置Sematext日志的环境变量。 Kinesis流本身在底部,资源部分中定义,并通过使用其ARN在函数事件中引用。

转到订户功能。它可以通过三种方式触发。这取决于你选择。如果您有许多现有的日志组,您可能希望点击HTTP端点以最初订阅它们。否则,让它每隔一段时间触发一次,或者只在创建新的日志组时触发它就没问题了。

LogsKinesisStream是我们订阅日志组的Kinesis流,CloudWatchLogsRole是IAM角色,它允许CloudWatch将记录放入Kinesis。

有了这个,你现在可以看到我们缺少一个secrets.json文件。但是,在我们继续之前,跳转到Sematext,登录并创建一个Logs App。按绿色小按钮添加日志应用程序。

添加应用程序名称和一些基本信息后,您将看到弹出等待数据屏幕。按积分指南并复制您的令牌。

现在您可以将令牌粘贴到secrets.json文件中。

{
“LOGS_TOKEN”:“你的代币”,
“REGION”:“us-east-1”,
“BATCH_SIZE”:1000,
“LOG_GROUP_RETENTION_IN_DAYS”:1,
“KINESIS_RETENTION_IN_HOURS”:24,
“KINESIS_SHARD_COUNT”:1
}

添加订户功能

我喜欢说Kinesis是Kafka的简单版本。它基本上是一个管道。您订阅要发送到其中的数据并告诉它在满足某个批量大小时触发Lambda函数作为事件。

具有订户功能的目的是将所有日志组订阅到Kinesis流。理想情况下,它们应该在创建时订阅,当然,最初当您想要将所有现有日志组订阅到新的Kinesis流时。作为后备,我还想在我想手动触发订阅者时拥有一个HTTP端点。

在代码编辑器中,创建一个新文件并将其命名为subscriber.js。粘贴此代码段。

查看processAll()函数。它将从CloudWatch中获取与前缀匹配的所有日志组,并将它们放在易于访问的阵列中。然后,您将它们传递给subscribeAll()函数,该函数将在将它们订阅到您在serverless.yml中定义的Kinesis流时映射它们。

另一个很酷的事情是将保留策略设置为7天。您很少需要更多,它将降低在AWS账户中保存日志的成本。

请记住,您还可以编辑将获取日志的filterPattern。就目前而言,我选择将其保持空白而不过滤掉任何内容。但是,根据您的需求,您可以将其与您选择的记录器所创建的模式相匹配。

甜蜜,完成后,让我们继续运送一些日志

添加出货单功能

Kinesis流从CloudWatch接收日志后,它将触发专用于将日志发送到Elasticsearch端点的Lambda函数。对于此示例,我们将使用LogseneJS作为日志发货人。如果你把它分解,那就相当简单了。一批记录将在event参数中发送给shipper函数。您解析日志,为它们提供所需的结构,并将它们发送到Sematext。这是它的样子。创建一个新文件,将其命名为shipper.js并粘贴此代码。

托运人Lambda的核心在于parseLogs()和shipLogs()函数。前者将获取事件参数,提取所有日志事件,解析它们,将它们添加到数组中,然后返回该数组。虽然后者将采用相同的日志数组,但是将每个日志事件添加到LogseneJS缓冲区,并一次性发送它们。该位置是您在上面创建的日志应用程序。

你还记得你在文章开头看到典型函数调用的日志事件的图像吗?在那里你可以看到它生成4种不同类型的日志事件。

START RequestId

END RequestId
报告RequestId

它们可以从这三种模式中的任何一种开始,其中省略号表示在函数运行时(Node.js中的console.log())中打印到stdout的任何类型的字符串。

parseLog()函数将完全跳过START,END和REPORT日志事件,并且仅根据用户定义的stdout或函数运行时中的任何类型的错误,将用户定义的日志事件作为调试或错误返回,配置或持续时间。

日志消息本身可以默认构建,但并非总是如此。默认情况下,在Node.js运行时中,它具有如下所示的结构。

托运人中的代码配置为使用上述结构或仅具有消息部分的结构。如果您正在使用另一个运行时,我建议您使用结构化日志记录为日志事件创建一个通用结构。

完成编码部分后,您就可以部署和测试自定义日志托运器了。

部署并测试中心化日志记录解决方案

使用基础架构作为无服务器框架等代码解决方案的优点在于简单的部署。您可以使用一个命令将所有内容推送到云端。跳回您的终端并在项目运行的目录中:

$sls部署

您将看到输出打印到控制台。

(输出)
无服务器:盘点服务……
无服务器:排除开发依赖性……
无服务器:将CloudFormation文件上传到S3 …
无服务器:上传工件……
无服务器:将服务.zip文件上传到S3(2.15 MB)…
无服务器:验证模板……
无服务器:更新堆栈……
无服务器:检查堆栈更新进度…
…………
无服务器:堆栈更新完成…
服务信息
service:lambda-cwlogs-to-logsene
阶段:开发
地区:us-east-1
stack:lambda-cwlogs-to-logsene-dev
api键:
没有
终点:
GET – https://.execute-api.us-east-1.amazonaws.com/dev/subscribe
功能:
托运人:lambda-cwlogs-to-logsene-dev-shipper
subscriber:lambda-cwlogs-to-logsene-dev-subscriber
层:
没有
无服务器:从S3中删除旧的服务工件…

而已。您现在可以设置将Lambda函数中的所有日志传送到Sematext Cloud。确保触发订阅者功能以将日志组订阅到Kinesis流。触发订阅者后,您将看到订阅者在Sematext中生成的日志,您可以放心,它可以正常工作。

上面你可以看到我如何添加严重性过滤。您可以轻松选择要过滤的值,为您提供跟踪错误,超时和调试日志的简便方法。

成本怎么样?

在您的AWS账户中进行此类设置的成本相当低廉。单个碎片Kinesis流的固定成本大约为每月14美元,并且流量数据的额外成本。单个分片的摄取容量为1MB /秒或1000记录/秒,这对大多数用户来说都很好。

Kinesis成本分为碎片小时和PUT有效载荷单位,大小为25KB。一个碎片每天花费0.36美元,而一百万个PUT有效载荷单位花费0.014美元。假设,如果你每秒有一个碎片和100个PUT有效载荷单位,那么碎片的成本最终为10.8美元,30天期间有效载荷单位的成本为3.6288美元。

Lambda函数配置为使用尽可能少的128MB内存,这意味着在适度使用期间,成本通常会保留在免费层中。这是你最不担心的事情。

总结

拥有日志的中心位置至关重要。尽管CloudWatch以其自己的方式有用,但它缺乏概述感。通过使用中心位置,您无需切换上下文来调试不同类型的应用程序。 Sematext可以监控整个软件堆栈。将您的Kubernetes日志,容器日志和Lambda日志放在Sematext日志中,您可以轻松地跟踪所有内容,这是一个主要的好处。

如果你需要再次查看代码,这里是repo,如果你想让更多人在GitHub上看到它,请给它一个明星。您还可以克隆存储库并立即进行部署。不要忘记先添加Logs App令牌。

如果您需要针对软件堆栈的可观察性解决方案,请查看Sematext。我们正在推动开源我们的产品并产生影响。

希望你们和女孩们一样喜欢读它,就像我喜欢写它一样。如果你喜欢它,打一下那个小小的分享按钮,这样就会有更多的人看到这个教程。直到下一次,好奇并享受乐趣。

最初于2019年3月15日在sematext.com上发布。

资讯来源:由0x资讯编译自HACKERNOON。版权归作者所有,原文链接:https://hackernoon.com/the-definitive-crash-course-on-serverless-with-aws-centralized-logging-with-kinesis-and-lambda-bfbc3439ceac?source=collection_category—4——0———————。未经许可,不得转载
提示:投资有风险,入市需谨慎,本资讯不作为投资理财建议。请理性投资,切实提高风险防范意识;如有发现的违法犯罪线索,可积极向有关部门举报反映。
你可能还喜欢