【ElasticSearch】 使用AWS云ES服务来分析程序日志

2023-06-25,,

最近公司系统升级,有些API的调用接口达到了每天10几万的请求量。目前公司里的日志,都是写文本文件中的。为了能够更好的分析这些日志数据,公司采用了AWS 的 ElasticSearch服务来分析日志。这篇文章记录了如何使用AWS上的ElasticSearch,以及需要注意那些坑。

1. 准备条件

1. 申请注册AWS的账号(注册AWS需要信用卡哦!)

2. 开通ElasticSearch服务(本文后面会详细介绍这部分),ES服务的中文介绍。目前ES并不是完全免费的,在前12个月,每月有 750 小时的 t2.small.elasticsearch 或 t3.small.elasticsearch 实例使用时间和每月 10GB 的可选 EBS 存储量(磁性或通用)。 关于ES服务免费的最新信息,请移步AWS ElasticSearch Free Tier.

在开通ES服务的过程中,如果你只想使用免费的服务,一定要选对 实例类型,磁盘容量和类型 等限制信息。建议在开通ES服务之前,仔细看看 AWS Free Tier。

3. 熟悉AWS的ElasticSearch开发文档,文档目前只有英文版的。

2. 创建ElasticSearch服务

笔者只是按照目前(2021.1.26)AWS的免费ES服务来介绍创建ES服务的过程,在开始前推荐先熟悉AWS最新的免费价格信息AWS Free Tier.  和 ES服务的中文介绍。

注意:Elasticsearch这篇文章使用7.9的,在后面的设置过程中,和 数据上传属性匹配(mapping)中,不同的版本之间会有略微的不同。

1. 选择部署类型,这里选择 开发和测试

2. 选择数据节点,目前t3.small.elasticsearch 和 t2.small.elasticsearch 都是免费的,t2在后面对数据验证没有t3方便,这里选择t3.small.elasticsearch实例。

3. 网络配置,选择 公有访问权限

4. 启动 精细访问控制,并且选择 创建主用户,填入用户名和密码,这里的用户名和密码,在后面 数据摄取 和 kibana的验证 中会用到

5. 接下来忽略 SAML authentication 和 Amazon Cognito Authentication. 

6. 访问策略,为了简化后面的步骤,这里选择 允许对域进行公开访问。

3. 数据摄取

数据摄取(就是将数据传入到ES服务中)有很多种方法,ES数据摄取是采用REST API的方式,所以只要能发送HTTP REST请求,都可以完成数据摄取过程。

官方的文档对数据摄取这部分也做了详细的介绍

Elasticsearch 如何使用命令行工具 curl 进行数据摄取。
Elasticsearch 进行数据摄取的示例代码(Java, Python, Go, Ruby, Node)
Elasticsearch 从Amazon其它产品导入(From Amazon S3,From Amazon Kinesis Data Streams,From Amazon DynamoDB,From Amazon Kinesis Data Firehose,From Amazon CloudWatch, From AWS IoT)
Elasticsearch 使用 开源框架 Logstash 摄取数据。如果你想进一步了解Logstash,请移步Get Started With Logstash.

开源框架 Logstash 是目前用的最广的数据摄取框架,使用 ES + Logstash + Filebeat + Kibana 搭配功能非常的强大。在下一篇文章,我会介绍Logstash。 本文先用Python代码直接上传日志数据,随便介绍一下直接上传的局限性。

日志文件:log.txt

185.220.70.83    2016-07-15 15:29:50+0800    GET    200    /index.php    50.1049,8.6295
124.200.101.56 2016-07-16 15:29:50+0800 POST 200 /register.php 39.9285,116.385
104.233.154.203 2016-07-17 15:29:50+0800 POST 404 /login.php 37.751,-97.822
104.233.154.203 2016-07-17 15:29:50+0800 POST 404 /API.php 37.751,-97.822
104.233.154.203 2016-07-18 15:29:50+0800 POST 200 /API.php 37.751,-97.822
43.251.227.108 2016-07-19 15:29:50+0800 POST 200 /index.php 22.2578,114.1657

这个日志特别简单,每行的数据以Tab进行分割,分别为IP,时间,访问方法,状态码,访问路径,和 坐标。笔者在这里,稍微解释一下其中的IP和坐标两部分,坐标就是IP地址的坐标。有些小伙伴可能会有疑问,为什么我的日志记录了IP地址,还要记录它的坐标,难道ElasticSearch不能将IP地址转化为坐标吗?  答案:使用ES中的geo-plugin是可以将IP转化为坐标地址的,但是 AWS 的 ES没有安装这个插件。读者可以在测试前查阅一下AWS ES支持的操作有哪些,希望在未来AWS可以加上这个插件。Plugins by Elasticsearch Version

由于目前AWS不支持直接根据IP生成坐标信息,所以笔者才在日志中额外提供了坐标信息,这些坐标信息都是根据maxmind查询得到的。MaxMind提供免费IP坐标数据文件,以及丰富的Demo, 使用起来快捷方便。

一般的日志都不会记录坐标信息,读者完全可以利用maxmind提供的IP库,在程序上传数据之前查出相应的坐标信息。除了程序上传的方式外,读者也可以采用 logstash 框架。

在正式上传数据之前,我们需要先预告诉ES我们想指定的数据类型,普通的数据类型(比如:String, Integer, Decimal)不需要指定,但像时间类型坐标类型,和IP类型的数据就需要先告诉ES服务,这样在后面上传数据的时候才能正确解析。这个命令只需要在上传数据之前执行一次就可以了,这里用curl来执行这个命令。

curl -XPUT -u 'username:password' 'https://end_point/logs' -H 'Content-Type: application/json' -d '
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
},
"datetime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ssZ"
},
"ip_addr":{
"type": "ip"
}
}
}
}'

上面 -u 'username:password' 的为用户名和密码,也就是之前启用精细访问控制创建的主用户和密码。 'https://end_point/logs' 中end_point为ES服务的终端地址,你可以在控制台中查看,终端地址的后面加上Index的值,这里使用logs。文档中的属性 location , datetime ,和  ip_addr  分别指定为 geo_point, geo_point,和 ip类型,下面上传数据的时候会用这些属性。

Python 文件:update.py

# 在运行前先通过pip安装elasticsearch, requests-aws4auth,requests
from elasticsearch import Elasticsearch, RequestsHttpConnection
from requests_aws4auth import AWS4Auth
import json host = 'end_point' # 服务终端HOST,不含HTTPS头部分,比如:my-test-domain.us-east-1.es.amazonaws.com
# username和password为之前的启用精细用户创建的用户名和密码
awsauth = ('username', 'password')
es = Elasticsearch(
hosts = [{'host': host, 'port': 443}],
http_auth = awsauth,
use_ssl = True,
verify_certs = True,
connection_class = RequestsHttpConnection
)
bulk_file = ''
id = 1 # 打开logs.txt文件,索引数据
file = open("logs.txt","r")
for line in file:
ip = line.split("\t")[0]
datetime = line.split("\t")[1]
method = line.split("\t")[2]
responsecode = line.split("\t")[3]
path = line.split("\t")[4]
geoloc = line.split("\t")[5].rstrip()
# ip_addr: ip类型,datetime: date类型,location: geo_point类型
index = { 'ip_addr': ip, 'datetime': datetime, 'method': method,'responsecode':responsecode,'path':path,'location':geoloc }
bulk_file += '{ "index" : { "_index" : "logs", "_type" : "_doc", "_id" : "' + str(id) + '" } }\n'
bulk_file += json.dumps(index) + '\n'
id += 1 #批量上传数据
res = es.bulk(bulk_file)
print(res)

运行脚本,看到上传成功的信息后,表明上传成功。

注意:本文章使用的是Elasticsearch7.9,其余的Elasticsearch版本,Mappings和上传的数据在格式上可能会有所不同

4. 访问Kibana

在数据上传成功后,接下来就进行可视化分析。点击控制台里的Kibana管理界面链接,输入用户名和密码后,成功进入Kibana管理界面。

创建Discovery 和 Visualization 组件,我这里创建了四个Visualization,一个是根据datetime创建的时间柱状图,一个是根据location创建的地理地图,一个根据responsecode创建的饼状图,和 一个根据method创建的饼状图。 然后再创建一个Dashboard,就可以将这些Visualiazation和Discovery组合起来。这些操作通过UI点击就可以完成,这里便不一一展示了,最后展示一下成果Dashboard图。

现在你就可以通过地图看到访问量,某个时间段的访问量,接口和访问量 等等。你还可以通过Kibana创建更复杂的视图,帮助你对日志进行挖掘和分析。

【ElasticSearch】 使用AWS云ES服务来分析程序日志的相关教程结束。

《【ElasticSearch】 使用AWS云ES服务来分析程序日志.doc》

下载本文的Word格式文档,以方便收藏与打印。