前端埋点数据采集(二)mock应用系统10万条前端埋点数据

前端埋点数据采集(二)mock应用系统10万条前端埋点数据

上一期我们分享了前端埋点数据采集(一)采集系统架构设计

我们说应用系统的数据,采集到大数据平台来,然后再到数仓。但是很多实际场景是应用系统、大数据平台、数仓平台各自并没有完成系统的搭建和开发。

 

假设现在一个场景是应用系统javaweb并未开发完成,但是大数据平台刚刚完成搭建,就等应用系统上报埋点日志到大数据平台上了。而且由于业务变化较快,应用系统经常变更,上报的数据格式可能经常会变化。

 

这个时候怎么办?项目工期紧张,不能延期,而且没有额外资源给这个组。

这次我们将借这篇分享回答这个问题。

 

一、项目中遇到的问题和挑战

 

1、项目开发依赖性问题

 

项目在开发测试交付过程中经常遇到前后的工作存在很大的依懒性,其实“瀑布型开发模式下”这种依赖很难解决,必须要在项目开始阶段,项目详细计划书里面由产品经理、数据分析师、前后端应用架构师、大数据架构师、数仓架构师已经商议定义好了数据字段格式要求后,就可以各司其职做搭建开发工作了。大数据开发人员会根据商定的日志格式mock数据测试使用。这里要求日志格式不能太大变化,如果有变化需要项目经理发起变更申请审批流程。

 

2、业务不断变更带来的系统、数据不确定性

 

由于业务变化快,系统需要经常变更,数据格式不确定性。在VUCA时代这种场景很常见,项目充满着复杂性、不确定性、模糊性、异变性。特别是在互联网行业、快消、零售行业,业务变化很快,实时性、创新性要求高,传统的项目管理模式已经无法适应,需要的是打破部门之间、团队之间的竖井,打造“由灵活的小团队构建成灵活的大团队”场景。

 

3、引入敏捷项目管理

 

刚才的场景只是站在项目生命周期里面一个开发的环节角度来看,上下链路还没有跨部门,组织沟通还是通畅的。如果站在测试环节的角度看,难道项目一定要开发完成才能做测试吗?站在业务需求部门产品经理PM的角度看,难道只有完成整个开发流程,项目才能上线使用?其实项目一旦制定需求项目目标,测试项目内容都可以进行了,做TDD(Test Driver develop),不需要开发完成才做测试。TDD也是敏捷开发的一个重要特征。

作为一个Scrum Master,下次有机会分享敏捷开发各种topic。



二、埋点选型

 

我们在这里不介绍埋点基本常识(埋点是什么?为什么需要埋点?埋点分类等),可以另外开一篇分享。1、APP埋点工具

  • 友盟

  • talking data

  • 神策数据

  • 后羿采集器等

 优点:上手容易,基本不需要开发,开箱即用。
 缺点:第三方工具平台带来可能导致信息泄露风险。
2、公司自定义开发

  • 预先设定好想要获取的目标数据,

  • 撰写代码把“采集器”埋到相应的页面上,用于追踪和记录的用户的行为

  • 并把实时数据传送到后台数据库或者客户端。

优点:数量流向都在企业内部平台,能保证信息安全。缺点:需要根据业务自定义开发,有开发运维成本。我们这里选型的是公司自定义开发。这里主要是因为我们关注更多的是大数据平台数据的一个来源,所以定义埋点数据格式,然后通过java代码实现随机数据的mock,写到本地就OK。

三、定义埋点格式
在公司,埋点格式、字段指标、规范等一般都是业务部门(如产品经理)和开发部门(应用架构师)以及数据分析师(做数据分析),协定好的一些字段规范。根据项目计划书里面的附件规范实施就行了。我们这里以假设一个电商APP为案例,讲解最简单的埋点的上报数据基本格式。

1、公共字段

所有手机都包含于的字段。比如手机OS、品牌、经纬度等。2、业务字段具体业务字段,比如:商品ID、订单ID、优惠券、页面数据等。

3、事件内容

添加购物车,添加收藏、领取优惠券等4、日志格式埋点格式如下:这里以一个JSON字符串给出字段的组成形式。它包括

  •  数据来源数据源来源于PC、APP、H5、爬虫等等
  • 公共字段手机各种属性配置信息
  • 用户事件用户一系列动作事件的跟踪,界面加载、点击、浏览等

 

5、广告标签

根据业务需求,我们这里定义了多个标签。具体每个标签就不一一细讲了,重点标签讲解如下:

标签

含义

entry

入口

应用首页=1,

商品列表页=2 

商品详情页=3

action

动作

请求广告=1

取缓存广告=2 

广告展示=4

广告点击=5 

content

状态

成功=0

失败=1  




四、创建工程并对应封装javaBean


通过创建maven工程,把标签字段对应javaBean并且做封装
1、创建Maven工程
POM文件主要涉及

    • 依赖fastJson对json解析

    • logback日志框架

    • 编译打包maven插件

<!--阿里巴巴开源fastjson解析框架-->

<dependency>

  <groupId>com.alibaba</groupId>

  <artifactId>fastjson</artifactId>

  <version>1.2.51</version>

</dependency>



<!--日志生成框架logback-->

<!--把bean对象封装成json对象,存储到磁盘上-->

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

 
2、根据标签定义javaBean
根据业务标签定义一一对应定义javaBean

 

五、主函数编程即JSON解析

其实主函数就是对固定的JSON字符串进行解析
1、JSON字符串形式 

 "H5":"xxxxx",//表示前端方式是:APP,还有H5\PC等

  "common message": //公共字段common message

  {  

    cm包含以下字段

    "mid": "",   (String) machineId设备唯一标识?

    "os": "1.1.1",  // (String) Android系统版本

    "md": "HUAWEIPro35",   (String) 手机型号

    "ba": "xiaomi",   (String) 手机品牌

    "hw": "1920x1280",  // (String) heightXwidth,屏幕宽高

    "network": "4g",   (String) 网络模式

    "ln": 0,   (double) lng经度

    "la": 0   (double) lat 纬度

  },

  "et":  

  [  事件json数组

    {

      "ett": "1933047503125",  //客户端事件产生时间

      "en": "display",  事件名称

      "kv": 

      {  事件结果,以key-value形式自行定义

        "productsid": "1",

        "action": "1",

        "place": "1",

        "type": "1"

      }

    }

  ]

}

2、JSON字符串的解析流程

 3、主要核心代码

// 参数一:控制发送每条的延时时间,默认是0

Long delay = args.length > 0 ? Long.parseLong(args[0]) : 0L;

// 参数二:循环遍历次数,默认是100000

int loop_len = args.length > 1 ? Integer.parseInt(args[1]) : 100000;

// 生成日志数据

generateLog(delay, loop_len);

private static void generateLog(Long delay, int loop_len)

{

  for (int i = 0; i < loop_len; i++)

{

/**

 * 通过random控制2种状态

 * 1.是处理启动日志;case(0)

 * 2.是处理事件日志;case(1)

 *

 */

int flag = rand.nextInt(2);

switch (flag)

{

    case (0):

        /**

         * 处理启动日志

         * 1.创建启动日志bean对象并且赋值

         * 2.把bean对象封装成json对象(用fastjson对象)

         * 3.控制台打印json

         * 4.json写到磁盘中

         */

        1.创建启动日志bean对象并且赋值

        AppStart appStart = generateStart();

        2.把bean对象封装成json字符串

        String jsonString = JSON.toJSONString(appStart);

        /3.控制台打印

        logger.info(jsonString);

        break;

        //4.json写到磁盘中

    case (1):

        /**

         * 处理事件日志 

         * 1.创建json对象

         * 2.向json中添加put ap的值

         * 3.向json中添加put 公共属性的值

         * 4.随机向json添加ett的值(1个事件一个函数)(多个数组封装)

         * 5.控制台打印,拼接事件和“|”符号

         */

        //1.创建json对象

        JSONObject json = new JSONObject();

        //2.向json中添加put ap的值

        json.put("ap", "app");

        //3.向json中添加put comFields的值

        json.put("cm", generateComFields());

        //4.随机向json添加ett的值(1个事件一个函数)(多个数组封装)

        //json.put("et",jason数组)

        //4.1先创建一个JSONArray数组

        JSONArray eventsArray = new JSONArray();

        /**

         * 4.2一个事件一个函数,一共11个事件的jSON对象

         */

        //5.控制台打印,拼接事件和“|”符号

        long millis = System.currentTimeMillis();

        logger.info(millis + "|" + json.toJSONString());

        break;

}

// 延迟时间处理,,几秒就睡眠几秒

try

{

    Thread.sleep(delay);

} catch (InterruptedException e)

{

    e.printStackTrace();

}}}



六、LogBack框架日志生成打印

 

1、日志打印到控制台

我们先把参数改为1000条记录信息,然后运行程序,打印到控制台,检查日志符合JSON字段值,说明程序执行正常。

 

.在resource目录系添加LogBack.xml

 

我们把日志打印到服务器集群上,所以用LogBack框架配置LogBack.xml文件

  • 定义日志文件的存储地址、格式、保留天数、日志大小
  • 定义日志输出级别info
<!--定义日志文件的存储地址-->

<property name="LOG_HOME" value="/opt/module/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>

七、上传jar包服务器集群

 

1、通过Maven打出jar包

 

2、上传jar包至服务器集群上

 

  • 把生成的具有依赖jar包,上传到node01和02节点/opt/module/applog/路径下
  • 然后通过java -jar XXX.jar 运行,查看目录,发现已经有日志文件生成
  • 每次执行一次java -jar XXX.jar,都会输出10W条日志信息
  • 格式是app.XXXX-XX -XX.log
-rw-rw-r-- 1 qiusheng qiusheng  409236 Apr 30 22:26 app.2021-04-30.log
-rw-rw-r-- 1 qiusheng qiusheng 2067847 May 8 23:39 app.2021-05-08.log
-rw-rw-r-- 1 qiusheng qiusheng 818279 May 9 00:10 app.2021-05-09.log
-rw-rw-r-- 1 qiusheng qiusheng  425014 May 10 21:32 app.2021-05-10.log


3、编写脚本文件实现在node01和02上生成日志
我们不希望日志打印到控制台,也不希望把日志生成到linux服务器集群占用空间,我们利用linux系统标准输入输出,把它放到“黑洞”里面。编写脚本mock_create_log.sh来实现在node01和02服务器上面生成埋点日志数据输出到“黑洞”。

cd /home/qiusheng/bin
vim mock_create_log.sh
#!/bin/bash
for node in node01 node02;
do
echo "=============== $node ==============="
ssh $node " cd /opt/module/applog/;
java -jar gmall2020-mock-log-2020-05-10.jar 1>/dev/null 2&1 & "
done

 

查node01、node02均有日志生成了。

-rw-rw-r-- 1 qiusheng qiusheng 405243 Apr 30 22:26 app.2021-04-30.log
-rw-rw-r-- 1 qiusheng qiusheng 813751 May 8 23:40 app.2021-05-08.log
-rw-rw-r-- 1 qiusheng qiusheng 804511 May 9 00:10 app.2021-05-09.log
-rw-rw-r-- 1 qiusheng qiusheng 401642 May 10 21:32 app.2021-05-10.log
[qiusheng@node02 log]$ 

 


总结:

  1. java应用项目还未完成,大数据平台怎么样上报数据?
  2. 了解埋点、日志格式、事件、工具选型
  3. 埋点格式的解析实质上对JOSN字符串的解析
  4. 生成的日志需要拼接处理后上传到服务器集群
  5. 编写linux脚本文件来实现多台服务器的日志生成到“黑洞”以免占用磁盘空间。

 

>>>>

Q&A

 

Q:mock_create_log.sh里面的xxx.jar 1>/dev/null 2&1 & 无法理解

A:

    1. /dev/null代表linux的空设备文件,所有往这个文件里面写入的内容都会丢失,俗称“黑洞”。

    2. linux系统标准输入0:从键盘获得输入 /proc/self/fd/0 

      linux系统标准输出1:输出到屏幕(即控制台) /proc/self/fd/1

      linux系统错误输出2:输出到屏幕(即控制台) /proc/self/fd/2

    3. 1>/dev/null;标准输出到黑洞

      2>/dev/null;错误输出到黑洞

      1>/dev/null 2>/dev/null;2输出到黑洞,1也输出到黑洞

      等价于简写 1>/dev/null 2&1

    4. 最后一个&表示脚本在后台运行

    5.  

 

posted @ 2024-05-06 18:09  爵岚  阅读(136)  评论(0编辑  收藏  举报