函数计算-处理容器中的网络访问日志

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 本文主要介绍如何使用函数计算处理容器服务收集上来的 web 服务器日志,分析出日志后存入新的日志库。进阶篇介绍了如何基于云市场 API 解析日志中的 IP 字段,并将结果作为 API 对接到 API 网关当中

处理容器日志

我的 web 应用是使用 docker 进行部署的,容器的日志由 fluentd 收集到阿里云的 SLS,但容器收集到的日志是这样的:

_

可以看到,日志的真正内容都放在了 log 字段里,不是很便于索引和查看,但有了函数计算,我们就可以把这些日志读出来,然后把 log 字段提取并处理好,然后写入新的 log store 即可。原理见下图(也可以参考阿里云官方文档):

docker_

首先我们需要在函数计算控制台里面,建立一个函数计算的服务,注意需要和 SLS log store 在同一个地域:

3_

建议在这里直接配置高级配置,设置对应的 RAM 角色,可以在这里直接新建角色,比较方便。为了简单,我们这里的策略模板,授予该角色日志的所有访问权限,待会儿我们可以在 RAM 控制台重新修改这个权限,对这个角色做更细粒度的权限控制。
创建好服务之后,我们就可以新建函数了,函数计算提供了很多的模板,这里我们采用 Node.js 完成这个新的函数,选择空白函数:

4_Node_js_

触发器配置中,因为我们需要从日志 store 1 读取日志进行处理,因此触发器选择日志服务:

5_

接下来我们需要对触发器进行配置:

6_

LogStore 相当于是日志源,就是最开始架构图中的 LogStore1,触发器日志就是用于存放函数计算过程中产生的日志的地方,方便排查代码问题。

函数配置是非常有用的配置了,这段配置可以在代码中获取到,类似于向 docker container 里面传递环境变量一样,可以让函数更具备扩展性。这里我们通过函数配置,配置了两个目标 LogStore,一个用于存放分析出来的 NGINX access log:access-log,另外一个 error-log,存放 docker 日志分析出来的其它内容,比如 PHP error、NGINX error 等其它日志。

点击下一步之后,我们就可以创建函数内容了:

7_

这里,经过我多个小时的调试,完成了这个函数,具体过程暂且不表,函数内容我已经上传到 GitHub:地址,待会儿再跟大家分享编写函数代码过程中的一些问题,这里,我们可以先使用默认提供的函数完成设置步骤。

8_

最下面还有一些函数运行时的设置,基本都不用改,函数内存和超时时间可以根据自己的需要适当扩大一些,避免运行过程中遇到错误。也可以这里设置小一些,后面根据函数运行的状况,不够用的话再调大。

最后一步是信息核对,如果没有问题,我们的函数就创建好了,接下来就是激动人心的函数编写过程了。

我们的需求是从 LogStore1 读取日志,进行分析之后,存入 LogStore2,所以我们先看如何从 LogStore1 读取数据。
对于这个函数,有个入口函数:

module.exports.handler = function(event, context, callback) {
  var config = JSON.parse(event.toString());
  console.log(config);
  console.log(context);
  callback(null, 'done');
}

可以看到我们能默认拿到 event, context 两个参数,这两个参数我们可以通过 console.log 打印一下看看是什么(见上面的代码),但注意 event 是个 Buffer,所以我们需要先处理一下。处理之后,我们看一下 event 的内容:

{
  "parameter": {
    "source": {
      "endpoint": "https://cn-hangzhou-intranet.log.aliyuncs.com"
    },
    "target": {
      "endpoint": "https://cn-hangzhou-intranet.log.aliyuncs.com",
      "errorLogStore": "error-log",
      "logStore": "access-log",
      "project": "test"
    }
  },
  "source": {
    "endpoint": "https://cn-hangzhou-intranet.log.aliyuncs.com",
    "projectName": "test",
    "logstoreName": "nginx-access",
    "shardId": 0,
    "beginCursor": "xxxx",
    "endCursor": "xxxx"
  },
  "jobName": "xxxx",
  "taskId": "xxxx",
  "cursorTime": 11111111
}

可以看出来,我们之前配置的“函数配置”是放在 event.parameter 里面的,event.source 则包含了 Log 触发器传递过来的一些信息,比如当前触发任务下的日志 beginCursor 和 endCursor,所以我们需要使用阿里云 OpenAPI SDK 从 SLS 中查到 beginCursor -> endCursor 中的日志。

context 参数里面,则包含了一个 credentials,里面是我们能够访问其他云产品的临时 AK,有效期 5分钟,这样我们就不用把自己再单独生成一个 AK 了。

但翻阅了 SLS 的 API 文档,发现 PullLogs 接口 只接受 beginCursor 和 count,好在 Response Header 里面给出了 nextCursor:x-log-cursor。我们可以依据这个,每次取一条,直到取到 x-log-cursor 和 endCursor 想等的情况下结束(具体需不需要包含 endCursor 我也不是很清楚,文档里貌似没看到,估计要看下其他语言的函数模板里面的代码)

所以我们需要递归去把这些日志捞出来。如果单纯用 callback 方式,写起来比较蛋疼,翻阅文档之后,发现函数计算中的 Node 脚本,默认注入了一些模块,比如 tj 大神的 co,aliyun-sdk 等,就可以不用自己 npm install 后再上传上来了。具体可以参考代码中的 pullLogs 函数。

日志查询出来之后,我们从日志信息中取出 log 字段,使用正则把需要的数据匹配出来,见代码中的 processNginxLogs 函数。

处理完成之后,我们再写入 LogStore2

代码本身比较简单,我就不深入介绍具体的过程了,可以参考 GitHub 上的源码,代码写的比较渣,欢迎各位大神提 PR。这里分享下编写函数过程中的一些心得:

  1. 调试起来只能靠 console.log,建议代码里面多打一些 console.log,方便排查问题,在线编写之后,保存并执行,下面就会有“执行日志”:
    9_

但这个日志只能显示一部分,如果你的日志比较多的话,这里是显示不全的,也没法翻页或者滚动,具体的还需要到 SLS 控制台,找到我们配置的函数计算的日志仓库,看日志。

  1. 函数的执行内存,可以在测试执行的时候看到执行的内存和执行时间,见上一条里面的第一张图,大家可以根据这个设置你的函数需要的内存和超时时间,设置过低的话,函数执行就很容易出现错误,会出现“process exited unexpected……”之类的错误,如果日志里频繁出现这种错误的话,可以看看是不是这里的问题。
  2. 很多时候,自己测试执行的时候没有问题,但是一旦由触发器执行就一堆报错了,这个时候,建议大家去看 SLS 里的函数计算日志,找到函数计算传入的函数配置:
    10_

然后把 task_config 里面的字段复制到函数执行,配置测试事件的自定义事件里面,再点执行,就可以看到该条的执行记录:
11_

  1. 过多的日志也会造成写入到 SLS 里的日志太多太乱,解决方法也比较简单,在函数配置里面加一个开关,比如 debug,然后在代码中判断 debug 是否开启,开启了再打日志,不然就不打,这样 SLS 里面的 Log 就会少很多,方便找内容,也给自己省点资源:)

基本上,经过这些步骤,我们的日志消费函数就完成了。等一段时间,可以看到已经有一些解析好的日志输出了:

12_

可以看到各个字段已经被我们拆出来了,就可以放到 MaxCompute 等产品里面进行分析了。

进阶:解析日志并包装接口

正在沾沾自喜的时候,老板来了:每次查看日志还是得到控制台里面查看,比较麻烦,而且里面都是各种 ip 地址,看起来都不知道来自哪里。老板不满意了,为了不让年终奖飞了,所以我们需要做以下事情:

  1. 新建一个函数,从处理后的 log store 查找出来某个时间段内的所有 NGINX 日志
  2. 调用 API 云市场里面的免费 API,把 ip 解析为地理位置
  3. 把这些日志包装成一个 API 出来,这样就可以写一个简单的网页调用这个 API,把日志展示出来,甚至后面还可以基于开源图表库画个酷炫的图表~

总共需要连接以下云产品:SLS、API Gateway、API 云市场

本例中我们继续采用 Node.js,但考虑到可能需要采用非自带的一些 npm 包,所以我们这次体验一下基于 fcli 来创建函数。

首先到帮助文档中下载 fcli 然后参照文档配置 AK:文档地址

然后新建一个代码目录,也可以直接 clone 我写好的代码:GitHub地址

在该目录下执行 fcli shell,这里我们就偷懒下,直接在已有的服务里面新建一个函数,并且配置 runtime 为 nodejs6,配置代码地址等(文档地址):

Welcome to the function compute world. Have fun!
>>> ls // 先看看我们已有的服务
test-log-filter
>>> cd test-log-filter // 进入该服务
>>> ls // 查看该服务下有哪些已有的函数
log-processor
test-whether
>>> mkf nginx-log-api -d ./ -h index.handler -t nodejs6 // 创建相应的函数
>>> ls // 再看一下已经创建成功了
log-processor
nginx-log-api
test-whether

接下来我们需要通过 OpenAPI-SDK 获取 SLS 里面的日志,有了之前处理 log 的经验,这个过程就很简单了,参考代码中 lib/sls.js 里面的部分。

获取到之后,接下来我们需要拿每个 log 中的 ip 字段去做地理位置解析,我们到云市场里购买一个 IP 查询的服务:地址。购买之后,调用也很简单,使用 aliyun-api-gateway 这个 npm 包完成请求过程

最后,需要按照 API Gateway 要求的返回格式进行返回,参考文档中 3.2 这个部分
写代码的过程中肯定少不了修改和调试的过程,可以通过 fcli 这条命令把代码上传/更新到函数计算服务中:

>>> upf functionName -d ./ -h index.handler -t nodejs6

更新完之后,我们就可以在控制台里面,配置测试事件进行测试了,输入的内容格式参考文档中 3.1 这个部分。

代码写好之后,我们就可以对接 API Gateway 了。在 API Gateway 控制台里面新建一个 API:

13_API

这个步骤根据自己的需要进行填写。接下来需要定义请求参数等,我们需要 from 和 to 两个 query,表示日志的起止时间

14_API_

下一步,我们定义后端类型,这里选择函数计算,同时需要获取 ram 授权,点击获取授权后会跳转到 ram 控制台获取授权,成功之后,我们还需要在 ram 控制台里面找到该角色(FC关键字),找到之后,点击这个角色的详情,把里面的 arn 这个字段复制到后端基础定义这里,稍微麻烦一点,其它根据自己的需要进行填写,函数需要填写我们刚才创建的函数,不然调用不到。

15_

下面我们可以定义一些常量参数,这里非常有用,也推荐大家使用这个功能,这里配置的参数可以根据你配置的规则传入到函数里面,非常适合放置一些配置内容以及一些敏感的信息,比如你的 SLS logStore,云市场 API 请求的 AppCode 等。

16_

比如我这里配置的是在 query 变量获取,不过我建议可以跟上面的后端参数分开会更好一些
最后一步定义返回格式和错误码,可以根据自己需要配置下,这样 API 就配置好了

配置好之后,我们就可以使用 API Gateway 提供的调试功能进行调试啦:

17_API_

填写 from 和 to 两个字段,点击发送请求,就可以看到我们的 API 返回结果了。可以看到,我们正确的查出了 ip 对应的地理位置信息,放到了 location 字段。部分查询不到的,有些字段会返回空。

至此,我们的 API 就创建好了,可以在自己的业务中基于这个 API 查询日志,甚至可以画个酷炫的图表什么的,接下来就看你的啦~

目录
相关文章
|
2月前
|
消息中间件 存储 Serverless
函数计算产品使用问题之怎么访问网络附加存储(NAS)存储模型文件
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
18天前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
20天前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
|
1月前
|
NoSQL 应用服务中间件 Redis
Docker跨宿主机容器通信-通过网络跨宿主机互联
这篇文章介绍了Docker容器跨宿主机通信的实现方法,包括Docker的四种网络模式(host、none、container、bridge)以及如何通过修改网络配置和添加路由规则来实现不同宿主机上的容器之间的互联。
114 0
Docker跨宿主机容器通信-通过网络跨宿主机互联
|
5天前
|
监控 Linux 测试技术
Linux系统命令与网络,磁盘和日志监控总结
Linux系统命令与网络,磁盘和日志监控总结
24 0
|
5天前
|
监控 Linux 测试技术
Linux系统命令与网络,磁盘和日志监控三
Linux系统命令与网络,磁盘和日志监控三
21 0
|
1月前
|
云安全 安全 Serverless
Serverless 安全新杀器:云安全中心护航容器安全
Serverless 安全防护能力除了支持目前既定的等保合规(漏洞扫描、入侵检测、基线检测等)、安全隔离的能力外还支持 WAF 防火墙、支持通信加密、操作审计、权限管控等能力,也正是有了这些能力的加持,SAE 才能很好的服务了金融、政企、医疗等行业的客户;Serverless(SAE)未来还计划规划更多安全能力为企业保驾护航,包括:代码安全扫描、加密、堡垒机、最小权限、身份与访问管理、以及更多的攻击防护等能力的建设。
|
2月前
|
存储 监控 Serverless
函数计算发布功能问题之用户在使用主流函数计算产品的日志服务时可能会遇到使用成本的问题如何解决
函数计算发布功能问题之用户在使用主流函数计算产品的日志服务时可能会遇到使用成本的问题如何解决
|
2月前
|
弹性计算 运维 Serverless
函数计算产品使用问题之容器镜像该如何使用
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
2月前
|
JavaScript 前端开发 Serverless
函数计算产品使用问题之打印日志时间与实际时间相差8小时,是什么原因
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。