最近公司系統升級,有些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創建更復雜的視圖,幫助你對日志進行挖掘和分析。
