數據埋點是一種良好的私有化部署數據採集方式。簡言之,數據埋點能夠粗淺的理解爲本身創造數據。這些數據能夠在私下幫助我的或企業完成針對特定用戶行爲或事件進行捕獲、處理和發送的相關技術及其實施過程。
業務字段:埋點上報的字段,有具體的業務類型。java
{ "ap": "xxxxx", //項目數據來源 app pc "cm": { //公共字段 "mid": "", // (String) 設備惟一標識 "uid": "", // (String) 用戶標識 "vc": "1", // (String) versionCode,程序版本號 "vn": "1.0", // (String) versionName,程序版本名 "l": "zh", // (String) 系統語言 "sr": "", // (String) 渠道號,應用從哪一個渠道來的。 "os": "7.1.1", // (String) Android系統版本 "ar": "CN", // (String) 區域 "md": "BBB100-1", // (String) 手機型號 "ba": "blackberry", // (String) 手機品牌 "sv": "V2.2.1", // (String) sdkVersion "g": "", // (String) gmail "hw": "1620x1080", // (String) heightXwidth,屏幕寬高 "t": "1506047606608", // (String) 客戶端日誌產生時的時間 "nw": "WIFI", // (String) 網絡模式 "ln": 0, // (double) lng經度 "la": 0 // (double) lat 緯度 }, "et": [ //事件 { "ett": "1506047605364", //客戶端事件產生時間 "en": "display", //事件名稱 "kv": { //事件結果,以key-value形式自行定義 "goodsid": "236", "action": "1", "extend1": "1", "place": "2", "category": "75" } } ] }
示例日誌(服務器時間|日誌)web
{ "ap": "gmall", "cm": { "uid": "1234", "vc": "2", "vn": "1.0", "la": "EN", "sr": "", "os": "7.1.1", "ar": "CN", "md": "BBB100-1", "ba": "blackberry", "sv": "V2.2.1", "g": "abc@gmail.com", "hw": "1620x1080", "t": "1506047606608", "nw": "WIFI", "ln": 0 }, "et": [{ "ett": "1506047605364", //客戶端事件產生時間 "en": "display", //事件名稱 "kv": { //事件結果,以key-value形式自行定義 "goodsid": "236", "action": "1", "extend1": "1", "place": "2", "category": "75" } }, { "ett": "1552352626835", "en": "active_background", "kv": { "active_source": "1" } }] } }
涉及的表。
商品列表頁:json
標籤 | 含義 |
---|---|
action | 動做:開始加載=1,加載成功=2,加載失敗=3 |
loading_time | 加載時長:計算下拉開始到接口返回數據的時間,(開始加載報0,加載成功或加載失敗才上報時間) |
loading_way | 加載類型:1-讀取緩存,2-從接口拉新數據(加載成功才上報加載類型) |
extend1 | 擴展字段 Extend1 |
extend2 | 擴展字段 Extend2 |
type | 加載類型:自動加載=1,用戶下拽加載=2,底部加載=3(底部條觸發點擊底部提示條/點擊返回頂部加載) |
type1 | 加載失敗碼:把加載失敗狀態碼報回來(報空爲加載成功,沒有失敗) |
商品點擊表:緩存
標籤 | 含義 |
---|---|
action | 動做:曝光商品=1,點擊商品=2,goodsid 商品ID(服務端下發的ID) |
place | 順序(第幾條商品,第一條爲0,第二條爲1,如此類推) |
extend1 | 曝光類型:1 - 首次曝光 2-重複曝光 |
category | 分類ID(服務端定義的分類ID) |
商品詳情頁:服務器
標籤 | 含義 |
---|---|
entry | 頁面入口來源:應用首頁=一、push=二、詳情頁相關推薦=3 |
action | 動做:開始加載=1,加載成功=2(pv),加載失敗=3, 退出頁面=4 |
goodsid | 商品ID(服務端下發的ID) |
show_style | 商品樣式:0、無圖、一、一張大圖、二、兩張圖、三、三張小圖、四、一張小圖、五、一張大圖兩張小圖 |
news_staytime | 頁面停留時長:從商品開始加載時開始計算,到用戶關閉頁面所用的時間。若中途用跳轉到其它頁面了,則暫停計時,待回到詳情頁時恢復計時。或中途劃出的時間超過10分鐘,則本次計時做廢,不上報本次數據。如未加載成功退出,則報空。 |
loading_time | 加載時長:計算頁面開始加載到接口返回數據的時間 (開始加載報0,加載成功或加載失敗才上報時間) |
type1 | 加載失敗碼:把加載失敗狀態碼報回來(報空爲加載成功,沒有失敗) |
category | 分類ID(服務端定義的分類ID) |
廣告網絡
標籤 | 含義 |
---|---|
entry | 入口:商品列表頁=1 應用首頁=2 商品詳情頁=3 |
action | 動做:請求廣告=1 取緩存廣告=2 廣告位展現=3 廣告展現=4 廣告點擊=5 |
content | 狀態:成功=1 失敗=2 |
detail | 失敗碼(沒有則上報空) |
source | 廣告來源:admob=1 facebook=2 ADX(百度)=3 VK(俄羅斯)=4 |
behavior | 用戶行爲:主動獲取廣告=1 被動獲取廣告=2 |
newstype | Type: 1- 圖文 2-圖集 3-段子 4-GIF 5-視頻 6-調查 7-純文 8-視頻+圖文 9-GIF+圖文 0-其餘 |
show_style | 內容樣式:無圖(純文字)=6 一張大圖=1 三站小圖+文=4 一張小圖=2 一張大圖兩張小圖+文=3 圖集+文 = 5 一張大圖+文=11 GIF大圖+文=12 視頻(大圖)+文 = 13 |
消息通知:app
標籤 | 含義 |
---|---|
action | 動做:通知產生=1,通知彈出=2,通知點擊=3,常駐通知展現(不重複上報,一天以內只報一次)=4 |
type | 通知id:預警通知=1,天氣預報(早=2,晚=3),常駐=4 |
ap_time | 客戶端彈出時間 |
content | 備用字段 |
用戶前臺活躍:框架
標籤 | 含義 |
---|---|
push_id | 推送的消息的id,若是不是從推送消息打開,傳空 |
access | 1.push 2.icon 3.其餘 |
用戶後臺活躍:dom
標籤 | 含義 |
---|---|
active_source | 1=upgrade,2=download(下載),3=plugin_upgrade |
評論:異步
序號 | 字段名稱 | 字段描述 | 字段類型 | 長度 | 容許空 | 缺省值 |
---|---|---|---|---|---|---|
1 | comment_id | 評論表 | int | 10,0 | ||
2 | userid | 用戶id | int | 10,0 | √ | 0 |
3 | p_comment_id | 父級評論id(爲0則是一級評論,不爲0則是回覆) | int | 10,0 | √ | |
4 | content | 評論內容 | string | √ | ||
5 | addtime | 建立時間 | string | √ | ||
6 | other_id | 評論的相關id | int | 10,0 | √ | |
7 | praise_count | 點贊數量 | int | 10,0 | √ | 0 |
8 | reply_count | 回覆數量 | int | 10,0 | √ | 0 |
收藏:
序號 | 字段名稱 | 字段描述 | 字段類型 | 長度 | 容許空 | 缺省值 |
---|---|---|---|---|---|---|
1 | id | 主鍵 | int | 10,0 | ||
2 | course_id | 商品id | int | 10,0 | √ | 0 |
3 | userid | 用戶ID | int | 10,0 | √ | 0 |
4 | add_time | 建立時間 | string | √ |
點贊:
序號 | 字段名稱 | 字段描述 | 字段類型 | 長度 | 容許空 | 缺省值 |
---|---|---|---|---|---|---|
1 | id | 主鍵id | int | 10,0 | ||
2 | userid | 用戶id | int | 10,0 | √ | |
3 | target_id | 點讚的對象id | int | 10,0 | √ | |
4 | type | 點贊類型 1問答點贊 2問答評論點贊 3 文章點贊數4 評論點贊 | int | 10,0 | √ | |
5 | add_time | 添加時間 | string | √ |
錯誤日誌:
字段 | 字段描述 |
---|---|
errorBrief | 錯誤摘要 |
errorDetail | 錯誤詳情 |
啓動日誌數據:
標籤 | 含義 |
---|---|
entry | 入口: push=1,widget=2,icon=3,notification=4, lockscreen_widget =5 |
open_ad_type | 開屏廣告類型: 開屏原生廣告=1, 開屏插屏廣告=2 |
action | 狀態:成功=1 失敗=2 |
loading_time | 加載時長:計算下拉開始到接口返回數據的時間,(開始加載報0,加載成功或加載失敗才上報時間) |
detail | 失敗碼(沒有則上報空) |
extend1 | 失敗的message(沒有則上報空) |
en | 日誌類型start |
在pom.xml文件中添加內容:
<!--版本號統一--> <properties> <slf4j.version>1.7.20</slf4j.version> <logback.version>1.0.7</logback.version> </properties> <dependencies> <!--阿里巴巴開源json解析框架--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.51</version> </dependency> <!--日誌生成框架--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> </dependencies> <!--編譯打包插件--> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin </artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.bbxy.appclient.AppMain</mainClass> <!-- 此處要和本身新建的類名一致 --> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
公共字段Bean:
package com.bbxy.bean; // 公共日誌 public class AppBase{ private String mid; // (String) 設備惟一標識 private String uid; // (String) 用戶uid private String vc; // (String) versionCode,程序版本號 private String vn; // (String) versionName,程序版本名 private String l; // (String) 系統語言 private String sr; // (String) 渠道號,應用從哪一個渠道來的。 private String os; // (String) Android系統版本 private String ar; // (String) 區域 private String md; // (String) 手機型號 private String ba; // (String) 手機品牌 private String sv; // (String) sdkVersion private String g; // (String) gmail private String hw; // (String) heightXwidth,屏幕寬高 private String t; // (String) 客戶端日誌產生時的時間 private String nw; // (String) 網絡模式 private String ln; // (double) lng經度 private String la; // (double) lat 緯度 public String getMid() { return mid; } public void setMid(String mid) { this.mid = mid; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getVc() { return vc; } public void setVc(String vc) { this.vc = vc; } public String getVn() { return vn; } public void setVn(String vn) { this.vn = vn; } public String getL() { return l; } public void setL(String l) { this.l = l; } public String getSr() { return sr; } public void setSr(String sr) { this.sr = sr; } public String getOs() { return os; } public void setOs(String os) { this.os = os; } public String getAr() { return ar; } public void setAr(String ar) { this.ar = ar; } public String getMd() { return md; } public void setMd(String md) { this.md = md; } public String getBa() { return ba; } public void setBa(String ba) { this.ba = ba; } public String getSv() { return sv; } public void setSv(String sv) { this.sv = sv; } public String getG() { return g; } public void setG(String g) { this.g = g; } public String getHw() { return hw; } public void setHw(String hw) { this.hw = hw; } public String getT() { return t; } public void setT(String t) { this.t = t; } public String getNw() { return nw; } public void setNw(String nw) { this.nw = nw; } public String getLn() { return ln; } public void setLn(String ln) { this.ln = ln; } public String getLa() { return la; } public void setLa(String la) { this.la = la; } }
啓動日誌Bean
package com.bbxy.bean; // 啓動日誌 public class AppStart extends AppBase { private String entry;//入口: push=1,widget=2,icon=3,notification=4, lockscreen_widget =5 private String open_ad_type;//開屏廣告類型: 開屏原生廣告=1, 開屏插屏廣告=2 private String action;//狀態:成功=1 失敗=2 private String loading_time;//加載時長:計算下拉開始到接口返回數據的時間,(開始加載報0,加載成功或加載失敗才上報時間) private String detail;//失敗碼(沒有則上報空) private String extend1;//失敗的message(沒有則上報空) private String en;//啓動日誌類型標記 public String getEntry() { return entry; } public void setEntry(String entry) { this.entry = entry; } public String getOpen_ad_type() { return open_ad_type; } public void setOpen_ad_type(String open_ad_type) { this.open_ad_type = open_ad_type; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getLoading_time() { return loading_time; } public void setLoading_time(String loading_time) { this.loading_time = loading_time; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public String getExtend1() { return extend1; } public void setExtend1(String extend1) { this.extend1 = extend1; } public String getEn() { return en; } public void setEn(String en) { this.en = en; } }
錯誤日誌Bean
package com.bbxy.bean; // 錯誤日誌 public class AppErrorLog { private String errorBrief; //錯誤摘要 private String errorDetail; //錯誤詳情 public String getErrorBrief() { return errorBrief; } public void setErrorBrief(String errorBrief) { this.errorBrief = errorBrief; } public String getErrorDetail() { return errorDetail; } public void setErrorDetail(String errorDetail) { this.errorDetail = errorDetail; } }
事件日誌Bean之商品點擊表
package com.bbxy.bean; // 商品點擊日誌 public class AppDisplay { private String action;//動做:曝光商品=1,點擊商品=2, private String goodsid;//商品ID(服務端下發的ID) private String place;//順序(第幾條商品,第一條爲0,第二條爲1,如此類推) private String extend1;//曝光類型:1 - 首次曝光 2-重複曝光(沒有使用) private String category;//分類ID(服務端定義的分類ID) public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getGoodsid() { return goodsid; } public void setGoodsid(String goodsid) { this.goodsid = goodsid; } public String getPlace() { return place; } public void setPlace(String place) { this.place = place; } public String getExtend1() { return extend1; } public void setExtend1(String extend1) { this.extend1 = extend1; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
事件日誌Bean之商品詳情頁
package com.bbxy.bean; // 商品詳情 public class AppNewsDetail { private String entry;//頁面入口來源:應用首頁=一、push=二、詳情頁相關推薦=3 private String action;//動做:開始加載=1,加載成功=2(pv),加載失敗=3, 退出頁面=4 private String goodsid;//商品ID(服務端下發的ID) private String showtype;//商品樣式:0、無圖一、一張大圖二、兩張圖三、三張小圖四、一張小圖五、一張大圖兩張小圖 來源於詳情頁相關推薦的商品,上報樣式都爲0(由於都是左文右圖) private String news_staytime;//頁面停留時長:從商品開始加載時開始計算,到用戶關閉頁面所用的時間。若中途用跳轉到其它頁面了,則暫停計時,待回到詳情頁時恢復計時。或中途劃出的時間超過10分鐘,則本次計時做廢,不上報本次數據。如未加載成功退出,則報空。 private String loading_time;//加載時長:計算頁面開始加載到接口返回數據的時間 (開始加載報0,加載成功或加載失敗才上報時間) private String type1;//加載失敗碼:把加載失敗狀態碼報回來(報空爲加載成功,沒有失敗) private String category;//分類ID(服務端定義的分類ID) public String getEntry() { return entry; } public void setEntry(String entry) { this.entry = entry; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getGoodsid() { return goodsid; } public void setGoodsid(String goodsid) { this.goodsid = goodsid; } public String getShowtype() { return showtype; } public void setShowtype(String showtype) { this.showtype = showtype; } public String getNews_staytime() { return news_staytime; } public void setNews_staytime(String news_staytime) { this.news_staytime = news_staytime; } public String getLoading_time() { return loading_time; } public void setLoading_time(String loading_time) { this.loading_time = loading_time; } public String getType1() { return type1; } public void setType1(String type1) { this.type1 = type1; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
事件日誌Bean之商品列表頁
package com.bbxy.bean; // 商品列表 public class AppLoading { private String action;//動做:開始加載=1,加載成功=2,加載失敗=3 private String loading_time;//加載時長:計算下拉開始到接口返回數據的時間,(開始加載報0,加載成功或加載失敗才上報時間) private String loading_way;//加載類型:1-讀取緩存,2-從接口拉新數據 (加載成功才上報加載類型) private String extend1;//擴展字段 Extend1 private String extend2;//擴展字段 Extend2 private String type;//加載類型:自動加載=1,用戶下拽加載=2,底部加載=3(底部條觸發點擊底部提示條/點擊返回頂部加載) private String type1;//加載失敗碼:把加載失敗狀態碼報回來(報空爲加載成功,沒有失敗) public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getLoading_time() { return loading_time; } public void setLoading_time(String loading_time) { this.loading_time = loading_time; } public String getLoading_way() { return loading_way; } public void setLoading_way(String loading_way) { this.loading_way = loading_way; } public String getExtend1() { return extend1; } public void setExtend1(String extend1) { this.extend1 = extend1; } public String getExtend2() { return extend2; } public void setExtend2(String extend2) { this.extend2 = extend2; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getType1() { return type1; } public void setType1(String type1) { this.type1 = type1; } }
事件日誌Bean之廣告
package com.bbxy.bean; // 廣告 public class AppAd { private String entry;//入口:商品列表頁=1 應用首頁=2 商品詳情頁=3 private String action;//動做:請求廣告=1 取緩存廣告=2 廣告位展現=3 廣告展現=4 廣告點擊=5 private String content;//狀態:成功=1 失敗=2 private String detail;//失敗碼(沒有則上報空) private String source;//廣告來源:admob=1 facebook=2 ADX(百度)=3 VK(俄羅斯)=4 private String behavior;//用戶行爲: 主動獲取廣告=1 被動獲取廣告=2 private String newstype;//Type: 1- 圖文 2-圖集 3-段子 4-GIF 5-視頻 6-調查 7-純文 8-視頻+圖文 9-GIF+圖文 0-其餘 private String show_style;//內容樣式:無圖(純文字)=6 一張大圖=1 三站小圖+文=4 一張小圖=2 一張大圖兩張小圖+文=3 圖集+文 = 5 //一張大圖+文=11 GIF大圖+文=12 視頻(大圖)+文 = 13 //來源於詳情頁相關推薦的商品,上報樣式都爲0(由於都是左文右圖) public String getEntry() { return entry; } public void setEntry(String entry) { this.entry = entry; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getBehavior() { return behavior; } public void setBehavior(String behavior) { this.behavior = behavior; } public String getNewstype() { return newstype; } public void setNewstype(String newstype) { this.newstype = newstype; } public String getShow_style() { return show_style; } public void setShow_style(String show_style) { this.show_style = show_style; } }
事件日誌Bean之消息通知
package com.bbxy.bean; // 消息通知日誌 public class AppNotification { private String action;//動做:通知產生=1,通知彈出=2,通知點擊=3,常駐通知展現(不重複上報,一天以內只報一次)=4 private String type;//通知id:預警通知=1,天氣預報(早=2,晚=3),常駐=4 private String ap_time;//客戶端彈出時間 private String content;//備用字段 public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getAp_time() { return ap_time; } public void setAp_time(String ap_time) { this.ap_time = ap_time; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
事件日誌Bean以前臺活躍
package com.bbxy.bean; // 用戶前臺活躍 public class AppActive_foreground { private String push_id;//推送的消息的id,若是不是從推送消息打開,傳空 private String access;//1.push 2.icon 3.其餘 public String getPush_id() { return push_id; } public void setPush_id(String push_id) { this.push_id = push_id; } public String getAccess() { return access; } public void setAccess(String access) { this.access = access; } }
事件日誌Bean以後臺活躍
package com.bbxy.bean; // 用戶後臺活躍 public class AppActive_background { private String active_source;//1=upgrade,2=download(下載),3=plugin_upgrade public String getActive_source() { return active_source; } public void setActive_source(String active_source) { this.active_source = active_source; } }
事件日誌Bean之用戶評論
package com.bbxy.bean; // 評論 public class AppComment { private int comment_id;//評論表 private int userid;//用戶id private int p_comment_id;//父級評論id(爲0則是一級評論,不爲0則是回覆) private String content;//評論內容 private String addtime;//建立時間 private int other_id;//評論的相關id private int praise_count;//點贊數量 private int reply_count;//回覆數量 public int getComment_id() { return comment_id; } public void setComment_id(int comment_id) { this.comment_id = comment_id; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public int getP_comment_id() { return p_comment_id; } public void setP_comment_id(int p_comment_id) { this.p_comment_id = p_comment_id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getAddtime() { return addtime; } public void setAddtime(String addtime) { this.addtime = addtime; } public int getOther_id() { return other_id; } public void setOther_id(int other_id) { this.other_id = other_id; } public int getPraise_count() { return praise_count; } public void setPraise_count(int praise_count) { this.praise_count = praise_count; } public int getReply_count() { return reply_count; } public void setReply_count(int reply_count) { this.reply_count = reply_count; } }
事件日誌Bean之用戶收藏
package com.bbxy.bean; // 收藏 public class AppFavorites { private int id;//主鍵 private int course_id;//商品id private int userid;//用戶ID private String add_time;//建立時間 public int getId() { return id; } public void setId(int id) { this.id = id; } public int getCourse_id() { return course_id; } public void setCourse_id(int course_id) { this.course_id = course_id; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getAdd_time() { return add_time; } public void setAdd_time(String add_time) { this.add_time = add_time; } }
事件日誌Bean之用戶點贊
package com.bbxy.bean; // 點贊 public class AppPraise { private int id; //主鍵id private int userid;//用戶id private int target_id;//點讚的對象id private int type;//點贊類型 1問答點贊 2問答評論點贊 3 文章點贊數4 評論點贊 private String add_time;//添加時間 public int getId() { return id; } public void setId(int id) { this.id = id; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public int getTarget_id() { return target_id; } public void setTarget_id(int target_id) { this.target_id = target_id; } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getAdd_time() { return add_time; } public void setAdd_time(String add_time) { this.add_time = add_time; } }
主函數
package com.bbxy.appclient; import java.io.UnsupportedEncodingException; import java.util.Random; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.bbxy.bean.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // 日誌行爲數據模擬 public class AppMain { private final static Logger logger = LoggerFactory.getLogger(AppMain.class); private static Random rand = new Random(); // 設備id private static int s_mid = 0; // 用戶id private static int s_uid = 0; // 商品id private static int s_goodsid = 0; public static void main(String[] args) { // 參數一:控制發送每條的延時時間,默認是0 Long delay = args.length > 0 ? Long.parseLong(args[0]) : 0L; // 參數二:循環遍歷次數 int loop_len = args.length > 1 ? Integer.parseInt(args[1]) : 1000; // 生成數據 generateLog(delay, loop_len); } private static void generateLog(Long delay, int loop_len) { for (int i = 0; i < loop_len; i++) { int flag = rand.nextInt(2); switch (flag) { case (0): //應用啓動 AppStart appStart = generateStart(); String jsonString = JSON.toJSONString(appStart); //控制檯打印 logger.info(jsonString); break; case (1): JSONObject json = new JSONObject(); json.put("ap", "app"); json.put("cm", generateComFields()); JSONArray eventsArray = new JSONArray(); // 事件日誌 // 商品點擊,展現 if (rand.nextBoolean()) { eventsArray.add(generateDisplay()); json.put("et", eventsArray); } // 商品詳情頁 if (rand.nextBoolean()) { eventsArray.add(generateNewsDetail()); json.put("et", eventsArray); } // 商品列表頁 if (rand.nextBoolean()) { eventsArray.add(generateNewList()); json.put("et", eventsArray); } // 廣告 if (rand.nextBoolean()) { eventsArray.add(generateAd()); json.put("et", eventsArray); } // 消息通知 if (rand.nextBoolean()) { eventsArray.add(generateNotification()); json.put("et", eventsArray); } // 用戶前臺活躍 if (rand.nextBoolean()) { eventsArray.add(generatbeforeground()); json.put("et", eventsArray); } // 用戶後臺活躍 if (rand.nextBoolean()) { eventsArray.add(generateBackground()); json.put("et", eventsArray); } //故障日誌 if (rand.nextBoolean()) { eventsArray.add(generateError()); json.put("et", eventsArray); } // 用戶評論 if (rand.nextBoolean()) { eventsArray.add(generateComment()); json.put("et", eventsArray); } // 用戶收藏 if (rand.nextBoolean()) { eventsArray.add(generateFavorites()); json.put("et", eventsArray); } // 用戶點贊 if (rand.nextBoolean()) { eventsArray.add(generatePraise()); json.put("et", eventsArray); } //時間 long millis = System.currentTimeMillis(); //控制檯打印 logger.info(millis + "|" + json.toJSONString()); break; } // 延遲 try { Thread.sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } } } // 公共字段設置 private static JSONObject generateComFields() { AppBase appBase = new AppBase(); //設備id appBase.setMid(s_mid + ""); s_mid++; // 用戶id appBase.setUid(s_uid + ""); s_uid++; // 程序版本號 5,6等 appBase.setVc("" + rand.nextInt(20)); //程序版本名 v1.1.1 appBase.setVn("1." + rand.nextInt(4) + "." + rand.nextInt(10)); // 安卓系統版本 appBase.setOs("8." + rand.nextInt(3) + "." + rand.nextInt(10)); // 語言 es,en,pt int flag = rand.nextInt(3); switch (flag) { case (0): appBase.setL("es"); break; case (1): appBase.setL("en"); break; case (2): appBase.setL("pt"); break; } // 渠道號 從哪一個渠道來的 appBase.setSr(getRandomChar(1)); // 區域 flag = rand.nextInt(2); switch (flag) { case 0: appBase.setAr("BR"); case 1: appBase.setAr("MX"); } // 手機品牌 ba ,手機型號 md,就取2位數字了 flag = rand.nextInt(3); switch (flag) { case 0: appBase.setBa("Sumsung"); appBase.setMd("sumsung-" + rand.nextInt(20)); break; case 1: appBase.setBa("Huawei"); appBase.setMd("Huawei-" + rand.nextInt(20)); break; case 2: appBase.setBa("HTC"); appBase.setMd("HTC-" + rand.nextInt(20)); break; } // 嵌入sdk的版本 appBase.setSv("V2." + rand.nextInt(10) + "." + rand.nextInt(10)); // gmail appBase.setG(getRandomCharAndNumr(8) + "@gmail.com"); // 屏幕寬高 hw flag = rand.nextInt(4); switch (flag) { case 0: appBase.setHw("640*960"); break; case 1: appBase.setHw("640*1136"); break; case 2: appBase.setHw("750*1134"); break; case 3: appBase.setHw("1080*1920"); break; } // 客戶端產生日誌時間 long millis = System.currentTimeMillis(); appBase.setT("" + (millis - rand.nextInt(99999999))); // 手機網絡模式 3G,4G,WIFI flag = rand.nextInt(3); switch (flag) { case 0: appBase.setNw("3G"); break; case 1: appBase.setNw("4G"); break; case 2: appBase.setNw("WIFI"); break; } // 拉丁美洲 西經34°46′至西經117°09;北緯32°42′至南緯53°54′ // 經度 appBase.setLn((-34 - rand.nextInt(83) - rand.nextInt(60) / 10.0) + ""); // 緯度 appBase.setLa((32 - rand.nextInt(85) - rand.nextInt(60) / 10.0) + ""); return (JSONObject) JSON.toJSON(appBase); } // 商品展現事件 private static JSONObject generateDisplay() { AppDisplay appDisplay = new AppDisplay(); boolean boolFlag = rand.nextInt(10) < 7; // 動做:曝光商品=1,點擊商品=2, if (boolFlag) { appDisplay.setAction("1"); } else { appDisplay.setAction("2"); } // 商品id String goodsId = s_goodsid + ""; s_goodsid++; appDisplay.setGoodsid(goodsId); // 順序 設置成6條吧 int flag = rand.nextInt(6); appDisplay.setPlace("" + flag); // 曝光類型 flag = 1 + rand.nextInt(2); appDisplay.setExtend1("" + flag); // 分類 flag = 1 + rand.nextInt(100); appDisplay.setCategory("" + flag); JSONObject jsonObject = (JSONObject) JSON.toJSON(appDisplay); return packEventJson("display", jsonObject); } // 商品詳情頁 private static JSONObject generateNewsDetail() { AppNewsDetail appNewsDetail = new AppNewsDetail(); // 頁面入口來源 int flag = 1 + rand.nextInt(3); appNewsDetail.setEntry(flag + ""); // 動做 appNewsDetail.setAction("" + (rand.nextInt(4) + 1)); // 商品id appNewsDetail.setGoodsid(s_goodsid + ""); // 商品來源類型 flag = 1 + rand.nextInt(3); appNewsDetail.setShowtype(flag + ""); // 商品樣式 flag = rand.nextInt(6); appNewsDetail.setShowtype("" + flag); // 頁面停留時長 flag = rand.nextInt(10) * rand.nextInt(7); appNewsDetail.setNews_staytime(flag + ""); // 加載時長 flag = rand.nextInt(10) * rand.nextInt(7); appNewsDetail.setLoading_time(flag + ""); // 加載失敗碼 flag = rand.nextInt(10); switch (flag) { case 1: appNewsDetail.setType1("102"); break; case 2: appNewsDetail.setType1("201"); break; case 3: appNewsDetail.setType1("325"); break; case 4: appNewsDetail.setType1("433"); break; case 5: appNewsDetail.setType1("542"); break; default: appNewsDetail.setType1(""); break; } // 分類 flag = 1 + rand.nextInt(100); appNewsDetail.setCategory("" + flag); JSONObject eventJson = (JSONObject) JSON.toJSON(appNewsDetail); return packEventJson("newsdetail", eventJson); } // 商品列表 private static JSONObject generateNewList() { AppLoading appLoading = new AppLoading(); // 動做 int flag = rand.nextInt(3) + 1; appLoading.setAction(flag + ""); // 加載時長 flag = rand.nextInt(10) * rand.nextInt(7); appLoading.setLoading_time(flag + ""); // 失敗碼 flag = rand.nextInt(10); switch (flag) { case 1: appLoading.setType1("102"); break; case 2: appLoading.setType1("201"); break; case 3: appLoading.setType1("325"); break; case 4: appLoading.setType1("433"); break; case 5: appLoading.setType1("542"); break; default: appLoading.setType1(""); break; } // 頁面加載類型 flag = 1 + rand.nextInt(2); appLoading.setLoading_way("" + flag); // 擴展字段1 appLoading.setExtend1(""); // 擴展字段2 appLoading.setExtend2(""); // 用戶加載類型 flag = 1 + rand.nextInt(3); appLoading.setType("" + flag); JSONObject jsonObject = (JSONObject) JSON.toJSON(appLoading); return packEventJson("loading", jsonObject); } // 廣告相關字段 private static JSONObject generateAd() { AppAd appAd = new AppAd(); // 入口 int flag = rand.nextInt(3) + 1; appAd.setEntry(flag + ""); // 動做 flag = rand.nextInt(5) + 1; appAd.setAction(flag + ""); // 狀態 flag = rand.nextInt(10) > 6 ? 2 : 1; appAd.setContent(flag + ""); // 失敗碼 flag = rand.nextInt(10); switch (flag) { case 1: appAd.setDetail("102"); break; case 2: appAd.setDetail("201"); break; case 3: appAd.setDetail("325"); break; case 4: appAd.setDetail("433"); break; case 5: appAd.setDetail("542"); break; default: appAd.setDetail(""); break; } // 廣告來源 flag = rand.nextInt(4) + 1; appAd.setSource(flag + ""); // 用戶行爲 flag = rand.nextInt(2) + 1; appAd.setBehavior(flag + ""); // 商品類型 flag = rand.nextInt(10); appAd.setNewstype("" + flag); // 展現樣式 flag = rand.nextInt(6); appAd.setShow_style("" + flag); JSONObject jsonObject = (JSONObject) JSON.toJSON(appAd); return packEventJson("ad", jsonObject); } // 啓動日誌 private static AppStart generateStart() { AppStart appStart = new AppStart(); //設備id appStart.setMid(s_mid + ""); s_mid++; // 用戶id appStart.setUid(s_uid + ""); s_uid++; // 程序版本號 5,6等 appStart.setVc("" + rand.nextInt(20)); //程序版本名 v1.1.1 appStart.setVn("1." + rand.nextInt(4) + "." + rand.nextInt(10)); // 安卓系統版本 appStart.setOs("8." + rand.nextInt(3) + "." + rand.nextInt(10)); //設置日誌類型 appStart.setEn("start"); // 語言 es,en,pt int flag = rand.nextInt(3); switch (flag) { case (0): appStart.setL("es"); break; case (1): appStart.setL("en"); break; case (2): appStart.setL("pt"); break; } // 渠道號 從哪一個渠道來的 appStart.setSr(getRandomChar(1)); // 區域 flag = rand.nextInt(2); switch (flag) { case 0: appStart.setAr("BR"); case 1: appStart.setAr("MX"); } // 手機品牌 ba ,手機型號 md,就取2位數字了 flag = rand.nextInt(3); switch (flag) { case 0: appStart.setBa("Sumsung"); appStart.setMd("sumsung-" + rand.nextInt(20)); break; case 1: appStart.setBa("Huawei"); appStart.setMd("Huawei-" + rand.nextInt(20)); break; case 2: appStart.setBa("HTC"); appStart.setMd("HTC-" + rand.nextInt(20)); break; } // 嵌入sdk的版本 appStart.setSv("V2." + rand.nextInt(10) + "." + rand.nextInt(10)); // gmail appStart.setG(getRandomCharAndNumr(8) + "@gmail.com"); // 屏幕寬高 hw flag = rand.nextInt(4); switch (flag) { case 0: appStart.setHw("640*960"); break; case 1: appStart.setHw("640*1136"); break; case 2: appStart.setHw("750*1134"); break; case 3: appStart.setHw("1080*1920"); break; } // 客戶端產生日誌時間 long millis = System.currentTimeMillis(); appStart.setT("" + (millis - rand.nextInt(99999999))); // 手機網絡模式 3G,4G,WIFI flag = rand.nextInt(3); switch (flag) { case 0: appStart.setNw("3G"); break; case 1: appStart.setNw("4G"); break; case 2: appStart.setNw("WIFI"); break; } // 拉丁美洲 西經34°46′至西經117°09;北緯32°42′至南緯53°54′ // 經度 appStart.setLn((-34 - rand.nextInt(83) - rand.nextInt(60) / 10.0) + ""); // 緯度 appStart.setLa((32 - rand.nextInt(85) - rand.nextInt(60) / 10.0) + ""); // 入口 flag = rand.nextInt(5) + 1; appStart.setEntry(flag + ""); // 開屏廣告類型 flag = rand.nextInt(2) + 1; appStart.setOpen_ad_type(flag + ""); // 狀態 flag = rand.nextInt(10) > 8 ? 2 : 1; appStart.setAction(flag + ""); // 加載時長 appStart.setLoading_time(rand.nextInt(20) + ""); // 失敗碼 flag = rand.nextInt(10); switch (flag) { case 1: appStart.setDetail("102"); break; case 2: appStart.setDetail("201"); break; case 3: appStart.setDetail("325"); break; case 4: appStart.setDetail("433"); break; case 5: appStart.setDetail("542"); break; default: appStart.setDetail(""); break; } // 擴展字段 appStart.setExtend1(""); return appStart; } // 消息通知 private static JSONObject generateNotification() { AppNotification appNotification = new AppNotification(); int flag = rand.nextInt(4) + 1; // 動做 appNotification.setAction(flag + ""); // 通知id flag = rand.nextInt(4) + 1; appNotification.setType(flag + ""); // 客戶端彈時間 appNotification.setAp_time((System.currentTimeMillis() - rand.nextInt(99999999)) + ""); // 備用字段 appNotification.setContent(""); JSONObject jsonObject = (JSONObject) JSON.toJSON(appNotification); return packEventJson("notification", jsonObject); } // 前臺活躍 private static JSONObject generatbeforeground() { AppActive_foreground appActive_foreground = new AppActive_foreground(); // 推送消息的id int flag = rand.nextInt(2); switch (flag) { case 1: appActive_foreground.setAccess(flag + ""); break; default: appActive_foreground.setAccess(""); break; } // 1.push 2.icon 3.其餘 flag = rand.nextInt(3) + 1; appActive_foreground.setPush_id(flag + ""); JSONObject jsonObject = (JSONObject) JSON.toJSON(appActive_foreground); return packEventJson("active_foreground", jsonObject); } // 後臺活躍 private static JSONObject generateBackground() { AppActive_background appActive_background = new AppActive_background(); // 啓動源 int flag = rand.nextInt(3) + 1; appActive_background.setActive_source(flag + ""); JSONObject jsonObject = (JSONObject) JSON.toJSON(appActive_background); return packEventJson("active_background", jsonObject); } // 錯誤日誌數據 private static JSONObject generateError() { AppErrorLog appErrorLog = new AppErrorLog(); String[] errorBriefs = {"at cn.lift.dfdf.web.AbstractBaseController.validInbound(AbstractBaseController.java:72)", "at cn.lift.appIn.control.CommandUtil.getInfo(CommandUtil.java:67)"}; //錯誤摘要 String[] errorDetails = {"java.lang.NullPointerException\\n " + "at cn.lift.appIn.web.AbstractBaseController.validInbound(AbstractBaseController.java:72)\\n " + "at cn.lift.dfdf.web.AbstractBaseController.validInbound", "at cn.lift.dfdfdf.control.CommandUtil.getInfo(CommandUtil.java:67)\\n " + "at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\\n" + " at java.lang.reflect.Method.invoke(Method.java:606)\\n"}; //錯誤詳情 //錯誤摘要 appErrorLog.setErrorBrief(errorBriefs[rand.nextInt(errorBriefs.length)]); //錯誤詳情 appErrorLog.setErrorDetail(errorDetails[rand.nextInt(errorDetails.length)]); JSONObject jsonObject = (JSONObject) JSON.toJSON(appErrorLog); return packEventJson("error", jsonObject); } // 爲各個事件類型的公共字段(時間、事件類型、Json數據)拼接 private static JSONObject packEventJson(String eventName, JSONObject jsonObject{ JSONObject eventJson = new JSONObject(); eventJson.put("ett", (System.currentTimeMillis() - rand.nextInt(99999999)) + ""); eventJson.put("en", eventName); eventJson.put("kv", jsonObject); return eventJson; } // 獲取隨機字母組合 // length 字符串長度 private static String getRandomChar(Integer length) { StringBuilder str = new StringBuilder(); Random random = new Random(); for (int i = 0; i < length; i++) { // 字符串 str.append((char) (65 + random.nextInt(26)));// 取得大寫字母 } return str.toString(); } // 獲取隨機字母數字組合 // length 字符串長度 private static String getRandomCharAndNumr(Integer length) { StringBuilder str = new StringBuilder(); Random random = new Random(); for (int i = 0; i < length; i++) { boolean b = random.nextBoolean(); if (b) { // 字符串 // int choice = random.nextBoolean() ? 65 : 97; 取得65大寫字母仍是97小寫字母 str.append((char) (65 + random.nextInt(26)));// 取得大寫字母 } else { // 數字 str.append(String.valueOf(random.nextInt(10))); } } return str.toString(); } // 收藏 private static JSONObject generateFavorites() { AppFavorites favorites = new AppFavorites(); favorites.setCourse_id(rand.nextInt(10)); favorites.setUserid(rand.nextInt(10)); favorites.setAdd_time((System.currentTimeMillis() - rand.nextInt(99999999)) + ""); JSONObject jsonObject = (JSONObject) JSON.toJSON(favorites); return packEventJson("favorites", jsonObject); } // 點贊 private static JSONObject generatePraise() { AppPraise praise = new AppPraise(); praise.setId(rand.nextInt(10)); praise.setUserid(rand.nextInt(10)); praise.setTarget_id(rand.nextInt(10)); praise.setType(rand.nextInt(4) + 1); praise.setAdd_time((System.currentTimeMillis() - rand.nextInt(99999999)) + ""); JSONObject jsonObject = (JSONObject) JSON.toJSON(praise); return packEventJson("praise", jsonObject); } // 評論 private static JSONObject generateComment() { AppComment comment = new AppComment(); comment.setComment_id(rand.nextInt(10)); comment.setUserid(rand.nextInt(10)); comment.setP_comment_id(rand.nextInt(5)); comment.setContent(getCONTENT()); comment.setAddtime((System.currentTimeMillis() - rand.nextInt(99999999)) + ""); comment.setOther_id(rand.nextInt(10)); comment.setPraise_count(rand.nextInt(1000)); comment.setReply_count(rand.nextInt(200)); JSONObject jsonObject = (JSONObject) JSON.toJSON(comment); return packEventJson("comment", jsonObject); } // 生成單個漢字 private static char getRandomChar() { String str = ""; int hightPos; // int lowPos; Random random = new Random(); //隨機生成漢子的兩個字節 hightPos = (176 + Math.abs(random.nextInt(39))); lowPos = (161 + Math.abs(random.nextInt(93))); byte[] b = new byte[2]; b[0] = (Integer.valueOf(hightPos)).byteValue(); b[1] = (Integer.valueOf(lowPos)).byteValue(); try { str = new String(b, "GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); System.out.println("錯誤"); } return str.charAt(0); } // 拼接成多個漢字 private static String getCONTENT() { StringBuilder str = new StringBuilder(); for (int i = 0; i < rand.nextInt(100); i++) { str.append(getRandomChar()); } return str.toString(); } }
配置日誌打印Logback
具體使用:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定義日誌文件的存儲地址 勿在 LogBack 的配置中使用相對路徑 --> <property name="LOG_HOME" value="/tmp/logs/" /> <!-- 控制檯輸出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符 --> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 按照天天生成日誌文件。存儲事件日誌 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- <File>${LOG_HOME}/app.log</File>設置日誌不超過${log.max.size}時的保存路徑,注意,若是是web項目會保存到Tomcat的bin目錄 下 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日誌文件輸出的文件名 --> <FileNamePattern>${LOG_HOME}/app-%d{yyyy-MM-dd}.log</FileNamePattern> <!--日誌文件保留天數 --> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%msg%n</pattern> </encoder> <!--日誌文件最大的大小 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!--異步打印日誌--> <appender name ="ASYNC_FILE" class= "ch.qos.logback.classic.AsyncAppender"> <!-- 不丟失日誌.默認的,若是隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日誌 --> <discardingThreshold >0</discardingThreshold> <!-- 更改默認的隊列的深度,該值會影響性能.默認值爲256 --> <queueSize>512</queueSize> <!-- 添加附加的appender,最多隻能添加一個 --> <appender-ref ref = "FILE"/> </appender> <!-- 日誌輸出級別 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="error" /> </root> </configuration>