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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文主要介绍如何使用函数计算处理容器服务收集上来的 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 查询日志,甚至可以画个酷炫的图表什么的,接下来就看你的啦~

目录
相关文章
|
16天前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
1月前
|
安全 网络安全 数据安全/隐私保护
访问控制列表(ACL)是网络安全中的一种重要机制,用于定义和管理对网络资源的访问权限
访问控制列表(ACL)是网络安全中的一种重要机制,用于定义和管理对网络资源的访问权限。它通过设置一系列规则,控制谁可以访问特定资源、在什么条件下访问以及可以执行哪些操作。ACL 可以应用于路由器、防火墙等设备,分为标准、扩展、基于时间和基于用户等多种类型,广泛用于企业网络和互联网中,以增强安全性和精细管理。
221 7
|
2天前
|
存储 监控 安全
网络安全视角:从地域到账号的阿里云日志审计实践
日志审计的必要性在于其能够帮助企业和组织落实法律要求,打破信息孤岛和应对安全威胁。选择 SLS 下日志审计应用,一方面是选择国家网络安全专用认证的日志分析产品,另一方面可以快速帮助大型公司统一管理多组地域、多个账号的日志数据。除了在日志服务中存储、查看和分析日志外,还可通过报表分析和告警配置,主动发现潜在的安全威胁,增强云上资产安全。
|
2月前
|
Docker 容器
容器的日志
【10月更文挑战第31天】
132 68
|
5天前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
21 2
|
12天前
|
消息中间件 人工智能 Kubernetes
解密开源Serverless容器框架:事件驱动篇
Knative是一款基于Kubernetes的开源Serverless框架,提供了云原生、跨平台的Serverless编排标准。作为Serverless中必不可少的事件驱动能力,Knative Eventing提供了云原生的事件驱动能力。
|
27天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
67 7
|
27天前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
32 5
|
1月前
|
网络协议 安全 文件存储
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问,即使IP地址变化,也能通过DDNS服务保持连接。适用于家庭网络远程访问设备及企业临时或移动设备管理,提供便捷性和灵活性。示例代码展示了如何使用Python实现基本的DDNS更新。尽管存在服务可靠性和安全性挑战,DDNS仍极大提升了网络资源的利用效率。
55 6
|
1月前
|
存储 JSON 网络协议
Docker面试整理-如何查看和管理Docker容器的日志?
通过本文的介绍,我们了解了如何查看和管理Docker容器的日志,包括使用 `docker logs`命令、配置日志驱动、设置日志选项和集中日志管理。掌握这些技能,不仅可以在面试中展示专业水平,也能在实际工作中高效
184 3