在不少項目中,埋點數據使用表格來統計的,隨着項目的進行,數據量愈來愈複雜,愈來愈難以維護。因此不少公司都已經開發了一整套系統,從埋點的錄入到代碼的輸出。node
咱們項目中iOS和Android雙方的埋點內容因爲溝通以及一些緣由,也沒有徹底統一,增長了不少溝通成本,爲了規範化和統一化,咱們也須要這樣一個相似的系統。可是不少時候一套系統對於一個小項目來講太過於複雜了,因此這裏我作了一個輕量級的本地管理客戶端。https://github.com/djs66256/lilyreact
因爲咱們實現的是一套本地管理的系統,因此我把程序系統和數據分開了,因此啓動的時候須要選擇對應的數據目錄,好比本項目目錄下的/demo-data/,以微信爲例。關於目錄下文件功能格式會在以後說明。webpack
啓動以後,咱們能夠看到咱們的埋點數據界面,這裏我根據咱們的需求把數據分爲3類:git
事件-數據點github
頁面web
具體參數正則表達式
數據點包含全部埋點信息,參數是由參數列表選擇,能夠查看歷史和進行編輯。npm
頁面包含了咱們的全部頁面id,由於一個普通的App擁有的頁面不會有太多,因此頁面的分級能夠少一點。json
參數包含了咱們埋點過程當中全部遇到的參數,考慮到咱們項目中所涉及到的參數比較統一,因此就沒有進行分類redux
每行數據的每次改動都會造成一條記錄保存在本地,這樣咱們就能夠追溯歷史變動了。這裏還把全部參數都列了出來,而不是主頁面精簡後的了。因爲性能問題,這裏暫時只顯示了最近50條記錄。
以上全部列表的數據項都是動態可配的。在設計之初,考慮到數據內容可能會根據須要動態調整,因此把全部內容都設計爲動態可配的了,又爲了在磁盤上的數據的可讀性,把全部數據都採用文本json保存,這樣也兼容了動態的數據,具體實現後面會詳細講解。
當選擇了一個目錄後,點擊導航欄的建立能夠建立一條新的數據,數據格式內容根據根目錄屬性配置。
點擊一行列表後的編輯按鈕進入編輯頁面,每次保存都會產生一條修改記錄。
可選的參數爲在根目錄爲參數內的全部內容,這樣設計的緣由是爲了將來可能對埋點數據的自動化驗證,從而須要一個格式化的參數列表,而不是一段文字描述。
爲了能夠對埋點的整理歸類,因此作了簡單的搜索功能,可搜索字段也是根據事件目錄的配置。
全部搜索字段都是使用正則表達式完成,因此若是須要更復雜精確的匹配,這裏也能夠輸入一段正則來匹配。
點擊編譯,會把全部事件和頁面數據自動生成一份代碼,這裏是根據須要定製的,因此我只作了iOS的一個樣例格式。這裏咱們從老數據轉化過來的時候有重複埋點,因此在轉化的邏輯中加入了去重,關於自定義和接入編譯系統以後會詳細描述。
以demo-data數據配置爲例。
在全部的數據中,概念都是節點Node,根據功能分爲兩類:
目錄節點DirNode,負責分級和歸類。
數據節點StatNode,負責記錄每一個數據的具體內容。
全部數據持久化經過json格式保存爲文本文件,因此能夠直接查看文件內容。
按照層級結構建立同樣的目錄層級結構,每一個DirNode下面都有一個config.json文件,包含該節點信息。
在最底層每一個StatNode會產生一個目錄,目錄下會根據歷史生成1.json,2.json,3.json名字依次遞增的文件,保存每次修改後的數據。這裏目錄名字使用id來命名是爲了解決數據埋點id可能存在重名的問題。
只能在目錄的最底層能夠建立數據,這是爲了解決展現時候的難以同時展現數據和目錄的問題。
每一個文件中都須要具有一些基礎屬性:
name外部顯示的名字,對於目錄節點則是目錄名字
id要求惟一的id,因爲DirNode個數比較少,並且固定,因此沒有設計建立的功能,本身修改時須要保證惟一。數據節點則會生成一個MD5來填充。
isDirectory表示是不是DirNode
包含一個columns數組,這是一個很是重要的配置,除了基礎屬性,全部StatNode裏的數據項都是根據該字段動態生成。
這裏是一個事件節點例子:
[
{
"type": "text", // 字段類型(暫時只支持text和param)
"required": false, // 是否必填
"title": "描述", // 展現的列名
"key": "description", // 對應於json中的key值
"visible": true, // 在主界面是否隱藏
"editable": true, // 是否可編輯,在編輯和建立界面是否可見
"searchable": true // 是否能夠做爲搜索參數,影響搜索界面 },
{
"type": "params",
"paramsKey": "params", // 若是是param類型,須要指定`DirNode`的id
"required": false,
"title": "參數",
"dataIndex": "params",
"key": "params",
"visible": true,
"editable": true,
"searchable": false
}
]
能夠動態增長或者修改數據項,這樣會很是靈活並且能夠不經過修改代碼就配置數據內容。
節點間的columns是能夠被繼承的,也就是說子目錄的columns一定包含父目錄的全部數據內容。惋惜目前的使用場景並無這個要求。
全部其餘目錄的配置都是相似的。
一樣看一個例子
{
"name": "點贊",
"statId": "onPraise",
"description": "包括3D touch頁面",
"version_iOS": "1.0",
"version_Android": "1.1",
"createTime": "2017-04-03T12:22:38.372Z",
"params": [
{
"name": "用戶ID",
"description": "",
"createTime": "2017-04-03T11:59:13.467Z",
"isDirectory": false,
"id": "814db1c837ac436ebb569d3554b51fb1",
"paramId": "userId"
},
{
"name": "朋友圈狀態",
"createTime": "2017-04-03T12:14:06.676Z",
"isDirectory": false,
"id": "866982e498224b15aa4602f2893f7995",
"paramId": "timelineId"
}
],
"isDirectory": false,
"id": "9b538d5bee1c40ed979e5a38143a9829"}
全部數據都是根據上述配置生成,其中param比較特殊,是把選擇的數據節點直接拷貝了一份,這樣作的緣由是怕其餘地方修改或者刪除了致使數據不一致的問題,這樣作更符合埋點這個需求。
目前編譯系統仍是作在了代碼中,因爲系統自己是有NodeJS實現的,因此要動態配置編譯系統仍是很是簡單的。
編譯系統比較開放,這樣能夠開放更多的功能,但同時也引入了數據風險,以後須要改進下,讓編譯系統能夠動態接入,而且屏蔽內部數據和編譯系統的直接聯繫。
目前代碼放在/script目錄下。
這裏對整個系統的代碼邏輯進行說明。
最基本的功能,須要可以在團隊內共享數據,其中最方便的就是利用git系統了,因此在每次修改數據的時候除了本地持久化之外,會自動同步git上的數據文件,這也是爲何要數據分離的一個緣由。
若是可以接上埋點系統,那麼能夠經過該系統去分析結果,這個工做量可能會比較大,是一個設想。
若是可以接上自動化測試或者設備,就可以驗證埋點數據是否正確,這個的工做量也可能會比較大。
目前完成了最基礎的管理埋點和生成代碼功能。
nodejs
Mac能夠經過brew install nodejs來安裝
須要electron和webpack
npm install -g electron webpack
首先npm install
而後須要連接本地庫
cd dd-statnpm linkcd ../statnpm link dd-stat
最後
npm run dev #開啓webpack -wnpm run app #啓動應用
dd-stat是系統的數據層,包含了數據結構和持久化。
stat是界面層,爲了實現簡單,目前全部邏輯都是在渲染層作的,由於咱們的數據量按照咱們的需求是不太可能達到如此大的數目,是不太可能出現性能問題的。
stat依賴支付寶的ant design框架來搭建,最初是用redux來組織(/lib),後來發現太過於複雜,應用自己就是個簡單的場景,因此後來改成react-router來組織(/lib2)。
/script是數據編譯的代碼,是導出編譯後代碼或者導出其餘格式的一個出口,能夠根據須要擴展。
最初的想法是讓程序來自動同步git,由於應用的使用場景比較簡單,不太可能出現多人同時編輯同一個數據的問題,因此讓程序來自動同步數據是最好的,因爲時間問題,暫時沒有加入。
如今編譯系統是和應用代碼捆綁在一塊兒的,最好可以脫離代碼,而且能夠動態配置編譯模板。
增長對bool,枚舉單選,枚舉多選,時間等的支持,項目暫時尚未這樣的需求。
網易雲新用戶大禮包:https://www.163yun.com/gift
本文來自網易雲社區,經做者段家順受權發佈。