1. 数据生成模块

2. 埋点数据基本格式

  • 公共字段:基本所有安卓手机都包含的字段
  • 业务字段:埋点上报的字段,有具体的业务类型
  1. {
  2. "ap":"xxxxx",//项目数据来源 app pc
  3. "cm": { //公共字段
  4. "mid": "", // (String) 设备唯一标识
  5. "uid": "", // (String) 用户标识
  6. "vc": "1", // (String) versionCode,程序版本号
  7. "vn": "1.0", // (String) versionName,程序版本名
  8. "l": "zh", // (String) language系统语言
  9. "sr": "", // (String) 渠道号,应用从哪个渠道来的。
  10. "os": "7.1.1", // (String) Android系统版本
  11. "ar": "CN", // (String) area区域
  12. "md": "BBB100-1", // (String) model手机型号
  13. "ba": "blackberry", // (String) brand手机品牌
  14. "sv": "V2.2.1", // (String) sdkVersion
  15. "g": "", // (String) gmail
  16. "hw": "1620x1080", // (String) heightXwidth,屏幕宽高
  17. "t": "1506047606608", // (String) 客户端日志产生时的时间
  18. "nw": "WIFI", // (String) 网络模式
  19. "ln": 0, // (double) lng经度
  20. "la": 0 // (double) lat 纬度
  21. },
  22. "et": [ //事件
  23. {
  24. "ett": "1506047605364", //客户端事件产生时间
  25. "en": "display", //事件名称
  26. "kv": { //事件结果,以key-value形式自行定义
  27. "goodsid": "236",
  28. "action": "1",
  29. "extend1": "1",
  30. "place": "2",
  31. "category": "75"
  32. }
  33. }
  34. ]
  35. }

3. 事件日志数据

3.1. 商品列表页

事件名称:loading

标签 含义
action 动作:开始加载=1,加载成功=2,加载失败=3
loading_time 加载时长:计算下拉开始到接口返回数据的时间,(开始加载报0,加载成功或加载失败才上报时间)
loading_way 加载类型:1-读取缓存,2-从接口拉新数据 (加载成功才上报加载类型)
extend1 扩展字段 Extend1
extend2 扩展字段 Extend2
type 加载类型:自动加载=1,用户下拽加载=2,底部加载=3(底部条触发点击底部提示条/点击返回顶部加载)
type1 加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败)

3.2. 商品点击

事件标签:display

标签 含义
action 动作:曝光商品=1,点击商品=2,
goodsid 商品ID(服务端下发的ID)
place 顺序(第几条商品,第一条为0,第二条为1,如此类推)
extend1 曝光类型:1 - 首次曝光 2-重复曝光
category 分类ID(服务端定义的分类ID)

3.3. 商品详情页

事件标签:newsdetail

标签 含义
entry 页面入口来源:应用首页=1、push=2、详情页相关推荐=3
action 动作:开始加载=1,加载成功=2(pv),加载失败=3, 退出页面=4
goodsid 商品ID(服务端下发的ID)
show_style 商品样式:0、无图、1、一张大图、2、两张图、3、三张小图、4、一张小图、5、一张大图两张小图
news_staytime 页面停留时长:从商品开始加载时开始计算,到用户关闭页面所用的时间。若中途用跳转到其它页面了,则暂停计时,待回到详情页时恢复计时。或中途划出的时间超过10分钟,则本次计时作废,不上报本次数据。如未加载成功退出,则报空。
loading_time 加载时长:计算页面开始加载到接口返回数据的时间 (开始加载报0,加载成功或加载失败才上报时间)
type1 加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败)
category 分类ID(服务端定义的分类ID)

3.4. 广告

事件名称:ad

标签 含义
entry 入口:商品列表页=1 应用首页=2 商品详情页=3
action 动作: 广告展示=1 广告点击=2
contentType Type: 1 商品 2 营销活动
displayMills 展示时长 毫秒数
itemId 商品id
activityId 营销活动id

3.5. 消息通知

事件标签:notification

标签 含义
action 动作:通知产生=1,通知弹出=2,通知点击=3,常驻通知展示(不重复上报,一天之内只报一次)=4
type 通知id:预警通知=1,天气预报(早=2,晚=3),常驻=4
ap_time 客户端弹出时间
content 备用字段

3.6. 用户后台活跃

事件标签: active_background

标签 含义
active_source 1=upgrade,2=download(下载),3=plugin_upgrade

3.7. 评论

描述:评论表

序号 字段名称 字段描述 字段类型 长度 允许空 缺省值
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 1000
5 addtime 创建时间 string
6 other_id 评论的相关id int 10,0
7 praise_count 点赞数量 int 10,0 0
8 reply_count 回复数量 int 10,0 0

3.8. 收藏

描述:收藏

序号 字段名称 字段描述 字段类型 长度 允许空 缺省值
1 id 主键 int 10,0
2 course_id 商品id int 10,0 0
3 userid 用户ID int 10,0 0
4 add_time 创建时间 string

3.9. 点赞

描述:所有的点赞表

序号 字段名称 字段描述 字段类型 长度 允许空 缺省值
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

3.10. 错误日志

errorBrief 错误摘要
errorDetail 错误详情

4. 启动日志

事件标签: start

标签 含义
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
  1. {
  2. "action":"1",
  3. "ar":"MX",
  4. "ba":"HTC",
  5. "detail":"",
  6. "en":"start",
  7. "entry":"2",
  8. "extend1":"",
  9. "g":"43R2SEQX@gmail.com",
  10. "hw":"640*960",
  11. "l":"en",
  12. "la":"20.4",
  13. "ln":"-99.3",
  14. "loading_time":"2",
  15. "md":"HTC-2",
  16. "mid":"995",
  17. "nw":"4G",
  18. "open_ad_type":"2",
  19. "os":"8.1.2",
  20. "sr":"B",
  21. "sv":"V2.0.6",
  22. "t":"1561472502444",
  23. "uid":"995",
  24. "vc":"10",
  25. "vn":"1.3.4"
  26. }

5. 数据生成脚本

03. 数据生成模块 - 图1

5.1. 工程准备

创建maven项目 名为 log-collector

导入依赖

  1. <!--版本号统一-->
  2. <properties>
  3. <slf4j.version>1.7.20</slf4j.version>
  4. <logback.version>1.0.7</logback.version>
  5. </properties>
  6. <dependencies>
  7. <!--阿里巴巴开源json解析框架-->
  8. <dependency>
  9. <groupId>com.alibaba</groupId>
  10. <artifactId>fastjson</artifactId>
  11. <version>1.2.51</version>
  12. </dependency>
  13. <!--日志生成框架-->
  14. <dependency>
  15. <groupId>ch.qos.logback</groupId>
  16. <artifactId>logback-core</artifactId>
  17. <version>${logback.version}</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>ch.qos.logback</groupId>
  21. <artifactId>logback-classic</artifactId>
  22. <version>${logback.version}</version>
  23. </dependency>
  24. </dependencies>
  25. <!--编译打包插件-->
  26. <build>
  27. <plugins>
  28. <plugin>
  29. <artifactId>maven-compiler-plugin</artifactId>
  30. <version>2.3.2</version>
  31. <configuration>
  32. <source>1.8</source>
  33. <target>1.8</target>
  34. </configuration>
  35. </plugin>
  36. <plugin>
  37. <artifactId>maven-assembly-plugin </artifactId>
  38. <configuration>
  39. <descriptorRefs>
  40. <descriptorRef>jar-with-dependencies</descriptorRef>
  41. </descriptorRefs>
  42. <archive>
  43. <manifest>
  44. <mainClass>com.atguigu.appclient.AppMain</mainClass>
  45. </manifest>
  46. </archive>
  47. </configuration>
  48. <executions>
  49. <execution>
  50. <id>make-assembly</id>
  51. <phase>package</phase>
  52. <goals>
  53. <goal>single</goal>
  54. </goals>
  55. </execution>
  56. </executions>
  57. </plugin>
  58. </plugins>
  59. </build>

创建 com.atguigu.appclient 包,在包下创建一个类AppMain

5.2. 公共字段Bean

创建 com.atguigu.bean 包 并创建以下bean类

AppBase

  1. package com.atguigu.bean;
  2. /**
  3. * 公共日志
  4. */
  5. public class AppBase{
  6. private String mid; // (String) 设备唯一标识
  7. private String uid; // (String) 用户uid
  8. private String vc; // (String) versionCode,程序版本号
  9. private String vn; // (String) versionName,程序版本名
  10. private String l; // (String) 系统语言
  11. private String sr; // (String) 渠道号,应用从哪个渠道来的。
  12. private String os; // (String) Android系统版本
  13. private String ar; // (String) 区域
  14. private String md; // (String) 手机型号
  15. private String ba; // (String) 手机品牌
  16. private String sv; // (String) sdkVersion
  17. private String g; // (String) gmail
  18. private String hw; // (String) heightXwidth,屏幕宽高
  19. private String t; // (String) 客户端日志产生时的时间
  20. private String nw; // (String) 网络模式
  21. private String ln; // (double) lng经度
  22. private String la; // (double) lat 纬度
  23. public String getMid() {
  24. return mid;
  25. }
  26. public void setMid(String mid) {
  27. this.mid = mid;
  28. }
  29. public String getUid() {
  30. return uid;
  31. }
  32. public void setUid(String uid) {
  33. this.uid = uid;
  34. }
  35. public String getVc() {
  36. return vc;
  37. }
  38. public void setVc(String vc) {
  39. this.vc = vc;
  40. }
  41. public String getVn() {
  42. return vn;
  43. }
  44. public void setVn(String vn) {
  45. this.vn = vn;
  46. }
  47. public String getL() {
  48. return l;
  49. }
  50. public void setL(String l) {
  51. this.l = l;
  52. }
  53. public String getSr() {
  54. return sr;
  55. }
  56. public void setSr(String sr) {
  57. this.sr = sr;
  58. }
  59. public String getOs() {
  60. return os;
  61. }
  62. public void setOs(String os) {
  63. this.os = os;
  64. }
  65. public String getAr() {
  66. return ar;
  67. }
  68. public void setAr(String ar) {
  69. this.ar = ar;
  70. }
  71. public String getMd() {
  72. return md;
  73. }
  74. public void setMd(String md) {
  75. this.md = md;
  76. }
  77. public String getBa() {
  78. return ba;
  79. }
  80. public void setBa(String ba) {
  81. this.ba = ba;
  82. }
  83. public String getSv() {
  84. return sv;
  85. }
  86. public void setSv(String sv) {
  87. this.sv = sv;
  88. }
  89. public String getG() {
  90. return g;
  91. }
  92. public void setG(String g) {
  93. this.g = g;
  94. }
  95. public String getHw() {
  96. return hw;
  97. }
  98. public void setHw(String hw) {
  99. this.hw = hw;
  100. }
  101. public String getT() {
  102. return t;
  103. }
  104. public void setT(String t) {
  105. this.t = t;
  106. }
  107. public String getNw() {
  108. return nw;
  109. }
  110. public void setNw(String nw) {
  111. this.nw = nw;
  112. }
  113. public String getLn() {
  114. return ln;
  115. }
  116. public void setLn(String ln) {
  117. this.ln = ln;
  118. }
  119. public String getLa() {
  120. return la;
  121. }
  122. public void setLa(String la) {
  123. this.la = la;
  124. }
  125. }

将代码下的bean全部复制到项目中即可

5.3. 主函数

03. 数据生成模块 - 图2

AppMain类

  1. package com.atguigu.appclient;
  2. import java.io.UnsupportedEncodingException;
  3. import java.util.Random;
  4. import com.alibaba.fastjson.JSON;
  5. import com.alibaba.fastjson.JSONArray;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.atguigu.bean.*;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. /**
  11. * 日志行为数据模拟
  12. */
  13. public class AppMain {
  14. private final static Logger logger = LoggerFactory.getLogger(AppMain.class);
  15. private static Random rand = new Random();
  16. // 设备id
  17. private static int s_mid = 0;
  18. // 用户id
  19. private static int s_uid = 0;
  20. // 商品id
  21. private static int s_goodsid = 0;
  22. public static void main(String[] args) {
  23. // 参数一:控制发送每条的延时时间,默认是0
  24. Long delay = args.length > 0 ? Long.parseLong(args[0]) : 0L;
  25. // 参数二:循环遍历次数
  26. int loop_len = args.length > 1 ? Integer.parseInt(args[1]) : 1000;
  27. // 生成数据
  28. generateLog(delay, loop_len);
  29. }
  30. private static void generateLog(Long delay, int loop_len) {
  31. for (int i = 0; i < loop_len; i++) {
  32. int flag = rand.nextInt(2);
  33. switch (flag) {
  34. case (0):
  35. //应用启动
  36. AppStart appStart = generateStart();
  37. String jsonString = JSON.toJSONString(appStart);
  38. //控制台打印
  39. logger.info(jsonString);
  40. break;
  41. case (1):
  42. JSONObject json = new JSONObject();
  43. json.put("ap", "app");
  44. json.put("cm", generateComFields());
  45. JSONArray eventsArray = new JSONArray();
  46. // 事件日志
  47. // 商品点击,展示
  48. if (rand.nextBoolean()) {
  49. eventsArray.add(generateDisplay());
  50. json.put("et", eventsArray);
  51. }
  52. // 商品详情页
  53. if (rand.nextBoolean()) {
  54. eventsArray.add(generateNewsDetail());
  55. json.put("et", eventsArray);
  56. }
  57. // 商品列表页
  58. if (rand.nextBoolean()) {
  59. eventsArray.add(generateNewList());
  60. json.put("et", eventsArray);
  61. }
  62. // 广告
  63. if (rand.nextBoolean()) {
  64. eventsArray.add(generateAd());
  65. json.put("et", eventsArray);
  66. }
  67. // 消息通知
  68. if (rand.nextBoolean()) {
  69. eventsArray.add(generateNotification());
  70. json.put("et", eventsArray);
  71. }
  72. // 用户后台活跃
  73. if (rand.nextBoolean()) {
  74. eventsArray.add(generateBackground());
  75. json.put("et", eventsArray);
  76. }
  77. //故障日志
  78. if (rand.nextBoolean()) {
  79. eventsArray.add(generateError());
  80. json.put("et", eventsArray);
  81. }
  82. // 用户评论
  83. if (rand.nextBoolean()) {
  84. eventsArray.add(generateComment());
  85. json.put("et", eventsArray);
  86. }
  87. // 用户收藏
  88. if (rand.nextBoolean()) {
  89. eventsArray.add(generateFavorites());
  90. json.put("et", eventsArray);
  91. }
  92. // 用户点赞
  93. if (rand.nextBoolean()) {
  94. eventsArray.add(generatePraise());
  95. json.put("et", eventsArray);
  96. }
  97. //时间
  98. long millis = System.currentTimeMillis();
  99. //控制台打印
  100. logger.info(millis + "|" + json.toJSONString());
  101. break;
  102. }
  103. // 延迟
  104. try {
  105. Thread.sleep(delay);
  106. } catch (InterruptedException e) {
  107. e.printStackTrace();
  108. }
  109. }
  110. }
  111. /**
  112. * 公共字段设置
  113. */
  114. private static JSONObject generateComFields() {
  115. AppBase appBase = new AppBase();
  116. //设备id
  117. appBase.setMid(s_mid + "");
  118. s_mid++;
  119. // 用户id
  120. appBase.setUid(s_uid + "");
  121. s_uid++;
  122. // 程序版本号 5,6等
  123. appBase.setVc("" + rand.nextInt(20));
  124. //程序版本名 v1.1.1
  125. appBase.setVn("1." + rand.nextInt(4) + "." + rand.nextInt(10));
  126. // 安卓系统版本
  127. appBase.setOs("8." + rand.nextInt(3) + "." + rand.nextInt(10));
  128. // 语言 es,en,pt
  129. int flag = rand.nextInt(3);
  130. switch (flag) {
  131. case (0):
  132. appBase.setL("es");
  133. break;
  134. case (1):
  135. appBase.setL("en");
  136. break;
  137. case (2):
  138. appBase.setL("pt");
  139. break;
  140. }
  141. // 渠道号 从哪个渠道来的
  142. appBase.setSr(getRandomChar(1));
  143. // 区域
  144. flag = rand.nextInt(2);
  145. switch (flag) {
  146. case 0:
  147. appBase.setAr("BR");
  148. case 1:
  149. appBase.setAr("MX");
  150. }
  151. // 手机品牌 ba ,手机型号 md,就取2位数字了
  152. flag = rand.nextInt(3);
  153. switch (flag) {
  154. case 0:
  155. appBase.setBa("Sumsung");
  156. appBase.setMd("sumsung-" + rand.nextInt(20));
  157. break;
  158. case 1:
  159. appBase.setBa("Huawei");
  160. appBase.setMd("Huawei-" + rand.nextInt(20));
  161. break;
  162. case 2:
  163. appBase.setBa("HTC");
  164. appBase.setMd("HTC-" + rand.nextInt(20));
  165. break;
  166. }
  167. // 嵌入sdk的版本
  168. appBase.setSv("V2." + rand.nextInt(10) + "." + rand.nextInt(10));
  169. // gmail
  170. appBase.setG(getRandomCharAndNumr(8) + "@gmail.com");
  171. // 屏幕宽高 hw
  172. flag = rand.nextInt(4);
  173. switch (flag) {
  174. case 0:
  175. appBase.setHw("640*960");
  176. break;
  177. case 1:
  178. appBase.setHw("640*1136");
  179. break;
  180. case 2:
  181. appBase.setHw("750*1134");
  182. break;
  183. case 3:
  184. appBase.setHw("1080*1920");
  185. break;
  186. }
  187. // 客户端产生日志时间
  188. long millis = System.currentTimeMillis();
  189. appBase.setT("" + (millis - rand.nextInt(99999999)));
  190. // 手机网络模式 3G,4G,WIFI
  191. flag = rand.nextInt(3);
  192. switch (flag) {
  193. case 0:
  194. appBase.setNw("3G");
  195. break;
  196. case 1:
  197. appBase.setNw("4G");
  198. break;
  199. case 2:
  200. appBase.setNw("WIFI");
  201. break;
  202. }
  203. // 拉丁美洲 西经34°46′至西经117°09;北纬32°42′至南纬53°54′
  204. // 经度
  205. appBase.setLn((-34 - rand.nextInt(83) - rand.nextInt(60) / 10.0) + "");
  206. // 纬度
  207. appBase.setLa((32 - rand.nextInt(85) - rand.nextInt(60) / 10.0) + "");
  208. return (JSONObject) JSON.toJSON(appBase);
  209. }
  210. /**
  211. * 商品展示事件
  212. */
  213. private static JSONObject generateDisplay() {
  214. AppDisplay appDisplay = new AppDisplay();
  215. boolean boolFlag = rand.nextInt(10) < 7;
  216. // 动作:曝光商品=1,点击商品=2,
  217. if (boolFlag) {
  218. appDisplay.setAction("1");
  219. } else {
  220. appDisplay.setAction("2");
  221. }
  222. // 商品id
  223. String goodsId = s_goodsid + "";
  224. s_goodsid++;
  225. appDisplay.setGoodsid(goodsId);
  226. // 顺序 设置成6条吧
  227. int flag = rand.nextInt(6);
  228. appDisplay.setPlace("" + flag);
  229. // 曝光类型
  230. flag = 1 + rand.nextInt(2);
  231. appDisplay.setExtend1("" + flag);
  232. // 分类
  233. flag = 1 + rand.nextInt(100);
  234. appDisplay.setCategory("" + flag);
  235. JSONObject jsonObject = (JSONObject) JSON.toJSON(appDisplay);
  236. return packEventJson("display", jsonObject);
  237. }
  238. /**
  239. * 商品详情页
  240. */
  241. private static JSONObject generateNewsDetail() {
  242. AppNewsDetail appNewsDetail = new AppNewsDetail();
  243. // 页面入口来源
  244. int flag = 1 + rand.nextInt(3);
  245. appNewsDetail.setEntry(flag + "");
  246. // 动作
  247. appNewsDetail.setAction("" + (rand.nextInt(4) + 1));
  248. // 商品id
  249. appNewsDetail.setGoodsid(s_goodsid + "");
  250. // 商品来源类型
  251. flag = 1 + rand.nextInt(3);
  252. appNewsDetail.setShowtype(flag + "");
  253. // 商品样式
  254. flag = rand.nextInt(6);
  255. appNewsDetail.setShowtype("" + flag);
  256. // 页面停留时长
  257. flag = rand.nextInt(10) * rand.nextInt(7);
  258. appNewsDetail.setNews_staytime(flag + "");
  259. // 加载时长
  260. flag = rand.nextInt(10) * rand.nextInt(7);
  261. appNewsDetail.setLoading_time(flag + "");
  262. // 加载失败码
  263. flag = rand.nextInt(10);
  264. switch (flag) {
  265. case 1:
  266. appNewsDetail.setType1("102");
  267. break;
  268. case 2:
  269. appNewsDetail.setType1("201");
  270. break;
  271. case 3:
  272. appNewsDetail.setType1("325");
  273. break;
  274. case 4:
  275. appNewsDetail.setType1("433");
  276. break;
  277. case 5:
  278. appNewsDetail.setType1("542");
  279. break;
  280. default:
  281. appNewsDetail.setType1("");
  282. break;
  283. }
  284. // 分类
  285. flag = 1 + rand.nextInt(100);
  286. appNewsDetail.setCategory("" + flag);
  287. JSONObject eventJson = (JSONObject) JSON.toJSON(appNewsDetail);
  288. return packEventJson("newsdetail", eventJson);
  289. }
  290. /**
  291. * 商品列表
  292. */
  293. private static JSONObject generateNewList() {
  294. AppLoading appLoading = new AppLoading();
  295. // 动作
  296. int flag = rand.nextInt(3) + 1;
  297. appLoading.setAction(flag + "");
  298. // 加载时长
  299. flag = rand.nextInt(10) * rand.nextInt(7);
  300. appLoading.setLoading_time(flag + "");
  301. // 失败码
  302. flag = rand.nextInt(10);
  303. switch (flag) {
  304. case 1:
  305. appLoading.setType1("102");
  306. break;
  307. case 2:
  308. appLoading.setType1("201");
  309. break;
  310. case 3:
  311. appLoading.setType1("325");
  312. break;
  313. case 4:
  314. appLoading.setType1("433");
  315. break;
  316. case 5:
  317. appLoading.setType1("542");
  318. break;
  319. default:
  320. appLoading.setType1("");
  321. break;
  322. }
  323. // 页面 加载类型
  324. flag = 1 + rand.nextInt(2);
  325. appLoading.setLoading_way("" + flag);
  326. // 扩展字段1
  327. appLoading.setExtend1("");
  328. // 扩展字段2
  329. appLoading.setExtend2("");
  330. // 用户加载类型
  331. flag = 1 + rand.nextInt(3);
  332. appLoading.setType("" + flag);
  333. JSONObject jsonObject = (JSONObject) JSON.toJSON(appLoading);
  334. return packEventJson("loading", jsonObject);
  335. }
  336. /**
  337. * 广告相关字段
  338. */
  339. private static JSONObject generateAd() {
  340. AppAd appAd = new AppAd();
  341. // 入口
  342. int flag = rand.nextInt(3) + 1;
  343. appAd.setEntry(flag + "");
  344. // 动作
  345. flag = rand.nextInt(5) + 1;
  346. appAd.setAction(flag + "");
  347. // 内容类型类型
  348. flag = rand.nextInt(6)+1;
  349. appAd.setContentType(flag+ "");
  350. // 展示样式
  351. flag = rand.nextInt(120000)+1000;
  352. appAd.setDisplayMills(flag+"");
  353. flag=rand.nextInt(1);
  354. if(flag==1){
  355. appAd.setContentType(flag+"");
  356. flag =rand.nextInt(6);
  357. appAd.setItemId(flag+ "");
  358. }else{
  359. appAd.setContentType(flag+"");
  360. flag =rand.nextInt(1)+1;
  361. appAd.setActivityId(flag+ "");
  362. }
  363. JSONObject jsonObject = (JSONObject) JSON.toJSON(appAd);
  364. return packEventJson("ad", jsonObject);
  365. }
  366. /**
  367. * 启动日志
  368. */
  369. private static AppStart generateStart() {
  370. AppStart appStart = new AppStart();
  371. //设备id
  372. appStart.setMid(s_mid + "");
  373. s_mid++;
  374. // 用户id
  375. appStart.setUid(s_uid + "");
  376. s_uid++;
  377. // 程序版本号 5,6等
  378. appStart.setVc("" + rand.nextInt(20));
  379. //程序版本名 v1.1.1
  380. appStart.setVn("1." + rand.nextInt(4) + "." + rand.nextInt(10));
  381. // 安卓系统版本
  382. appStart.setOs("8." + rand.nextInt(3) + "." + rand.nextInt(10));
  383. //设置日志类型
  384. appStart.setEn("start");
  385. // 语言 es,en,pt
  386. int flag = rand.nextInt(3);
  387. switch (flag) {
  388. case (0):
  389. appStart.setL("es");
  390. break;
  391. case (1):
  392. appStart.setL("en");
  393. break;
  394. case (2):
  395. appStart.setL("pt");
  396. break;
  397. }
  398. // 渠道号 从哪个渠道来的
  399. appStart.setSr(getRandomChar(1));
  400. // 区域
  401. flag = rand.nextInt(2);
  402. switch (flag) {
  403. case 0:
  404. appStart.setAr("BR");
  405. case 1:
  406. appStart.setAr("MX");
  407. }
  408. // 手机品牌 ba ,手机型号 md,就取2位数字了
  409. flag = rand.nextInt(3);
  410. switch (flag) {
  411. case 0:
  412. appStart.setBa("Sumsung");
  413. appStart.setMd("sumsung-" + rand.nextInt(20));
  414. break;
  415. case 1:
  416. appStart.setBa("Huawei");
  417. appStart.setMd("Huawei-" + rand.nextInt(20));
  418. break;
  419. case 2:
  420. appStart.setBa("HTC");
  421. appStart.setMd("HTC-" + rand.nextInt(20));
  422. break;
  423. }
  424. // 嵌入sdk的版本
  425. appStart.setSv("V2." + rand.nextInt(10) + "." + rand.nextInt(10));
  426. // gmail
  427. appStart.setG(getRandomCharAndNumr(8) + "@gmail.com");
  428. // 屏幕宽高 hw
  429. flag = rand.nextInt(4);
  430. switch (flag) {
  431. case 0:
  432. appStart.setHw("640*960");
  433. break;
  434. case 1:
  435. appStart.setHw("640*1136");
  436. break;
  437. case 2:
  438. appStart.setHw("750*1134");
  439. break;
  440. case 3:
  441. appStart.setHw("1080*1920");
  442. break;
  443. }
  444. // 客户端产生日志时间
  445. long millis = System.currentTimeMillis();
  446. appStart.setT("" + (millis - rand.nextInt(99999999)));
  447. // 手机网络模式 3G,4G,WIFI
  448. flag = rand.nextInt(3);
  449. switch (flag) {
  450. case 0:
  451. appStart.setNw("3G");
  452. break;
  453. case 1:
  454. appStart.setNw("4G");
  455. break;
  456. case 2:
  457. appStart.setNw("WIFI");
  458. break;
  459. }
  460. // 拉丁美洲 西经34°46′至西经117°09;北纬32°42′至南纬53°54′
  461. // 经度
  462. appStart.setLn((-34 - rand.nextInt(83) - rand.nextInt(60) / 10.0) + "");
  463. // 纬度
  464. appStart.setLa((32 - rand.nextInt(85) - rand.nextInt(60) / 10.0) + "");
  465. // 入口
  466. flag = rand.nextInt(5) + 1;
  467. appStart.setEntry(flag + "");
  468. // 开屏广告类型
  469. flag = rand.nextInt(2) + 1;
  470. appStart.setOpen_ad_type(flag + "");
  471. // 状态
  472. flag = rand.nextInt(10) > 8 ? 2 : 1;
  473. appStart.setAction(flag + "");
  474. // 加载时长
  475. appStart.setLoading_time(rand.nextInt(20) + "");
  476. // 失败码
  477. flag = rand.nextInt(10);
  478. switch (flag) {
  479. case 1:
  480. appStart.setDetail("102");
  481. break;
  482. case 2:
  483. appStart.setDetail("201");
  484. break;
  485. case 3:
  486. appStart.setDetail("325");
  487. break;
  488. case 4:
  489. appStart.setDetail("433");
  490. break;
  491. case 5:
  492. appStart.setDetail("542");
  493. break;
  494. default:
  495. appStart.setDetail("");
  496. break;
  497. }
  498. // 扩展字段
  499. appStart.setExtend1("");
  500. return appStart;
  501. }
  502. /**
  503. * 消息通知
  504. */
  505. private static JSONObject generateNotification() {
  506. AppNotification appNotification = new AppNotification();
  507. int flag = rand.nextInt(4) + 1;
  508. // 动作
  509. appNotification.setAction(flag + "");
  510. // 通知id
  511. flag = rand.nextInt(4) + 1;
  512. appNotification.setType(flag + "");
  513. // 客户端弹时间
  514. appNotification.setAp_time((System.currentTimeMillis() - rand.nextInt(99999999)) + "");
  515. // 备用字段
  516. appNotification.setContent("");
  517. JSONObject jsonObject = (JSONObject) JSON.toJSON(appNotification);
  518. return packEventJson("notification", jsonObject);
  519. }
  520. /**
  521. * 后台活跃
  522. */
  523. private static JSONObject generateBackground() {
  524. AppActive_background appActive_background = new AppActive_background();
  525. // 启动源
  526. int flag = rand.nextInt(3) + 1;
  527. appActive_background.setActive_source(flag + "");
  528. JSONObject jsonObject = (JSONObject) JSON.toJSON(appActive_background);
  529. return packEventJson("active_background", jsonObject);
  530. }
  531. /**
  532. * 错误日志数据
  533. */
  534. private static JSONObject generateError() {
  535. AppErrorLog appErrorLog = new AppErrorLog();
  536. String[] errorBriefs = {"at cn.lift.dfdf.web.AbstractBaseController.validInbound(AbstractBaseController.java:72)", "at cn.lift.appIn.control.CommandUtil.getInfo(CommandUtil.java:67)"}; //错误摘要
  537. 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"}; //错误详情
  538. //错误摘要
  539. appErrorLog.setErrorBrief(errorBriefs[rand.nextInt(errorBriefs.length)]);
  540. //错误详情
  541. appErrorLog.setErrorDetail(errorDetails[rand.nextInt(errorDetails.length)]);
  542. JSONObject jsonObject = (JSONObject) JSON.toJSON(appErrorLog);
  543. return packEventJson("error", jsonObject);
  544. }
  545. /**
  546. * 为各个事件类型的公共字段(时间、事件类型、Json数据)拼接
  547. */
  548. private static JSONObject packEventJson(String eventName, JSONObject jsonObject) {
  549. JSONObject eventJson = new JSONObject();
  550. eventJson.put("ett", (System.currentTimeMillis() - rand.nextInt(99999999)) + "");
  551. eventJson.put("en", eventName);
  552. eventJson.put("kv", jsonObject);
  553. return eventJson;
  554. }
  555. /**
  556. * 获取随机字母组合
  557. *
  558. * @param length 字符串长度
  559. */
  560. private static String getRandomChar(Integer length) {
  561. StringBuilder str = new StringBuilder();
  562. Random random = new Random();
  563. for (int i = 0; i < length; i++) {
  564. // 字符串
  565. str.append((char) (65 + random.nextInt(26)));// 取得大写字母
  566. }
  567. return str.toString();
  568. }
  569. /**
  570. * 获取随机字母数字组合
  571. * @param length 字符串长度
  572. */
  573. private static String getRandomCharAndNumr(Integer length) {
  574. StringBuilder str = new StringBuilder();
  575. Random random = new Random();
  576. for (int i = 0; i < length; i++) {
  577. boolean b = random.nextBoolean();
  578. if (b) { // 字符串
  579. // int choice = random.nextBoolean() ? 65 : 97; 取得65大写字母还是97小写字母
  580. str.append((char) (65 + random.nextInt(26)));// 取得大写字母
  581. } else { // 数字
  582. str.append(String.valueOf(random.nextInt(10)));
  583. }
  584. }
  585. return str.toString();
  586. }
  587. /**
  588. * 收藏
  589. */
  590. private static JSONObject generateFavorites() {
  591. AppFavorites favorites = new AppFavorites();
  592. favorites.setCourse_id(rand.nextInt(10));
  593. favorites.setUserid(rand.nextInt(10));
  594. favorites.setAdd_time((System.currentTimeMillis() - rand.nextInt(99999999)) + "");
  595. JSONObject jsonObject = (JSONObject) JSON.toJSON(favorites);
  596. return packEventJson("favorites", jsonObject);
  597. }
  598. /**
  599. * 点赞
  600. */
  601. private static JSONObject generatePraise() {
  602. AppPraise praise = new AppPraise();
  603. praise.setId(rand.nextInt(10));
  604. praise.setUserid(rand.nextInt(10));
  605. praise.setTarget_id(rand.nextInt(10));
  606. praise.setType(rand.nextInt(4) + 1);
  607. praise.setAdd_time((System.currentTimeMillis() - rand.nextInt(99999999)) + "");
  608. JSONObject jsonObject = (JSONObject) JSON.toJSON(praise);
  609. return packEventJson("praise", jsonObject);
  610. }
  611. /**
  612. * 评论
  613. */
  614. private static JSONObject generateComment() {
  615. AppComment comment = new AppComment();
  616. comment.setComment_id(rand.nextInt(10));
  617. comment.setUserid(rand.nextInt(10));
  618. comment.setP_comment_id(rand.nextInt(5));
  619. comment.setContent(getCONTENT());
  620. comment.setAddtime((System.currentTimeMillis() - rand.nextInt(99999999)) + "");
  621. comment.setOther_id(rand.nextInt(10));
  622. comment.setPraise_count(rand.nextInt(1000));
  623. comment.setReply_count(rand.nextInt(200));
  624. JSONObject jsonObject = (JSONObject) JSON.toJSON(comment);
  625. return packEventJson("comment", jsonObject);
  626. }
  627. /**
  628. * 生成单个汉字
  629. */
  630. private static char getRandomChar() {
  631. String str = "";
  632. int hightPos; //
  633. int lowPos;
  634. Random random = new Random();
  635. //随机生成汉子的两个字节
  636. hightPos = (176 + Math.abs(random.nextInt(39)));
  637. lowPos = (161 + Math.abs(random.nextInt(93)));
  638. byte[] b = new byte[2];
  639. b[0] = (Integer.valueOf(hightPos)).byteValue();
  640. b[1] = (Integer.valueOf(lowPos)).byteValue();
  641. try {
  642. str = new String(b, "GBK");
  643. } catch (UnsupportedEncodingException e) {
  644. e.printStackTrace();
  645. System.out.println("错误");
  646. }
  647. return str.charAt(0);
  648. }
  649. /**
  650. * 拼接成多个汉字
  651. */
  652. private static String getCONTENT() {
  653. StringBuilder str = new StringBuilder();
  654. for (int i = 0; i < rand.nextInt(100); i++) {
  655. str.append(getRandomChar());
  656. }
  657. return str.toString();
  658. }
  659. }

5.4. 配置日志打印Logback

Logback主要用于在磁盘和控制台打印日志。

在resources文件夹下创建logback.xml文件。

<?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>

5.5. 打包

Maven对程序打包

03. 数据生成模块 - 图3

打包会会生成两个jar包 一个是不带依赖的 和 一个带依赖的

03. 数据生成模块 - 图4

我们使用带依赖的jar包