本文章首發於個人博客 基於 Eleasticsearch 和 Kibana 的運營數據可視化後臺,轉載請註明來源。html
前一段時間在研究 ELK 這個東西,以前也用過一點,但都沒有深刻研究,其實這回也沒有深刻研究,但我找到了在如今狀況下我該怎麼用這個東西的方法。git
ELK 是一個日誌系統的全家桶工具,Elasticsearch 用的人比較多,不少人把這個看成搜索後臺,若是你選擇了 Django 這樣的框架的話也很容易繼承搜索功能進去,好比用這個庫 django-haystack,固然不少人是用來作日誌存儲。github
L 是 Logstash,通過個人調研就發現這個玩意其實不太好用,性能差是主要緣由。這個東西的用途就是一箇中間件,把多個平臺的不一樣格式的日誌所有進行預處理,而後再存入 ES 中,可是做爲一個還很小,沒那麼複雜的後臺服務來講,用不着,只有一個日誌來源,日誌格式也是固定的,一條日誌裏面有四個 JSON object,每一個 object 的 key 不是固定的,只要處理一下時間戳就好了,其餘都不用動,直接 mapping 到 ES 中,剛開始我甚至還用到了 filebeat,先用 filebeat 監控文件,而後 filebeat output 給 logstash,而後 logstash 再 output 給 ES,簡直了,測試的時候沒什麼問題,但一上線過了兩三天日誌數量多了起來我就發現問題了,數量不對,天天都在累加前一天的日誌條數,等於說是 tail 文件沒成功,每次都從頭開始讀文件了,外加用了 rsync 這個東西從生產服務器上同步日誌到 ES 機器上,我也沒整明白究竟是哪裏出了問題,索性直接棄用 logstash 和 filebeat,只用 ES 和 kibana,我本身寫腳本監控文件、把日誌寫入 ES 中,也把日誌按天切分紅文件,簡單又靠譜。django
運營數據日誌的日誌內容其實和消息系統很像,我就直接引用這裏的概念 AVOT,Actor/Verb/Object/Target
。舉例說明: xxx 關注了 yyy
,xxx
是 Actor,關注
是 Verb,yyy
是 Target,這裏沒有 Object,再舉一個例子,xxx 將 uuu 添加到了 yyy 中,這裏的 Verb 是 添加
,Object 是 uuu
,Actor/Object/Target
就是模型,固然咱們不用把模型的所有字段都放進去,放個 type/id/name 就夠了。按照這樣的規則規定好日誌內容以後就簡單了,在每一個須要記錄日誌的地方進行埋點,這個就是比較麻煩的地方,若是業務比較複雜的化,埋點不少,寫的時候必定要一次性寫對 Object 和 Target,不要寫了一次以後複製粘貼,很容易搞錯,一個個寫。還有一點就是 Actor/Object/Target
的 id 都轉成字符串存儲,由於用戶的 id 是 uuid
,日誌 object 直接 to_json()
,django logger 直接用,用戶 id 會變成字符串,其餘 model 的 id 仍是 int
,類型若是不一致再存到 ES 裏面數據會有衝突。json
最終的日誌格式示例:bash
{"target": {"type": "Paper", "title": "Deep Depth Super-Resolution : Learning Depth Super-Resolution using Deep Convolutional Neural Network", "id": "791", "owner": "MKFMIKU"}, "object": {}, "actor": {"agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36", "accept_language": "en-US,en;q=0.8", "username": "qhl722", "host": "zijin.paperweekly.site", "referer": "http://www.paperweekly.site/getting-started"}, "verb": "點贊", "time": 1507000406.305043}
{"target": {"type": "User", "id": "fcc3837f-1a61-4d2c-bdbf-0961085547a3", "owner": "gg5d"}, "object": {}, "actor": {"agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", "accept_language": "zh-CN,zh;q=0.8", "username": "", "host": "zijin.paperweekly.site", "referer": "http://www.paperweekly.site/"}, "verb": "註冊", "time": 1507000688.429523}
複製代碼
我用了 Elasticsearch 的官方 Python API elasticsearch-py,腳本放在了 Gist 裏面。服務器
日誌存到 ES 中是這個樣子:app
Kibana 是一個但是化工具,能看到 ES 中的數據,作一些報表,只要把數據導入到 ES 中,作報表就很簡單了,簡單的也是有前提的,前提是你要定義好日誌的內容。框架
好比點贊數量,在 Visualize 裏面新建一個柱狀圖,搜索 item.verb="點贊"
,而後第一個 Y 軸聚合搜索出來的日誌條數,就是點讚的數量,再添加一個 Y 軸 Unique Count
item.actor.username.keyword
就能得出多少個用戶產生了這麼多贊,X 軸就是按照時間,我都是按天來,選擇 Date Histogram
,Interval
選 Daily
,若是你的日誌系統要求的實時性比較高,還能選擇 Hourly
,而後把實時刷新打開,就能看到比較實時的數據了。elasticsearch
Kibana 最終是這個樣子:
過幾天我把這個東西拆分出來變成一個倉庫再詳細寫一下教程。