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