1. Server SDK使用文档

1.1. 引入SDK(java)

1.1.1. maven项目

在pom中添加如下依赖

<dependency>
    <groupId>com.netease.da.sdk</groupId>
    <artifactId>HubbleDataSDK</artifactId>
    <version>1.1-SNAPSHOT</version>
</dependency>

1.1.2. 其他java项目

直接在官网链接下载相应的sdk jar包,引入到项目中

1.2. 初始化SDK

  • 方式1:只使用埋点功能
DATracker daTracker=DATracker.init("MA-6RWE-XXXXXXXXXXXX");//MA-6RWE-XXXXXXXXXXXX为产品对应的server端的appkey
  • 方式2:使用abtest功能(默认获取变量的超时时间为300ms,http建立连接时间2s)
DATracker daTracker=DATracker.init("MA-6RWE-QWHKHEKDF12",true);//打开abtest功能
//或
DATracker daTracker=DATracker.init("MA-6RWE-QWHKHEKDF12",true,300,500);//打开abtest功能,并配置获取变量的超时时间和http连接时间
//或
DATracker daTracker=DATracker.init("MA-6RWE-QWHKHEKDF12",true,true);//打开abtest功能并且缓存配置
//或
DATracker daTracker=DATracker.init("MA-6RWE-QWHKHEKDF12",true,true,300,500);//打开abtest功能并且缓存配置,并配置获取变量的超时时间和http连接时间

DATracker只需要init一次,以后每次获取DATracker实例,可以通过:

DATracker daTracker=DATracker.getDATrackInstance();

获取DATracker实例

1.2.1. Spring项目

建议spring的项目,通过在配置文件中配置bean,如:

<bean id="daTracker" class="com.netease.da.sdk.DATracker" factory-method="init">
    <constructor-arg type="java.lang.String" value="MA-6RWE-XXXXXXXXXXXX"/>
</bean>

在需要埋点的类中通过注解注入即可:

@Autowired
protected DATracker daTracker;

也可以通过

DATracker daTracker=DATracker.getDATrackInstance();

获取DATracker实例

1.3. 追踪事件接口

1.3.1. 事件类型

事件主要分为两种类型,预定义事件和普通事件

预定义事件

系统预定义了2种事件,用户只需要调用接口即可追踪,如下:

1. 用户id关联,将匿名id和用户id相关联,匿名id为非登录状态下用户的唯一id
public void trackSignUp(String oldUserId,String newUserId)
2. 用户属性设置
  • 设置用户属性,存在则覆盖
/**
* 设置用户属性,存在则覆盖
* @param userId 用户id
* @param property 用户属性名称
* @param value 用户属性值
*/
public void profileSet(String userId,String property,Object value)
  • 设置用户属性集合
/**
* 设置用户属性集合
* @param userId 用户id
* @param userProfile 用户属性集合
*/
public void profileSet(String userId,Map<String,Object>userProfile)
  • 设置用户属性,该属性如果存在则忽略
/**
* 设置用户属性,该属性如果存在则忽略
* @param userId 用户id
* @param property 用户属性名称
* @param value 用户属性值
*/
public void profileSetOnce(String userId,String property,Object value)
  • 删除一个用户的属性
/**
* 设置用户属性,该属性如果存在则忽略
* @param userId 用户id
* @param property 用户属性名称
* @param value 用户属性值
*/
public void profileDelete(String userId)
  • 设置用户年龄,存在则覆盖
/**
* 设置用户属性,该属性如果存在则忽略
* @param userId 用户id
* @param property 用户属性名称
* @param value 用户属性值
*/
public void profileSetAge(String userId,int age)
  • 设置用户名字,存在则覆盖
/**
* 设置用户名字,存在则覆盖
* @param userId 用户id
* @param name 用户真实姓名
*/
public void profileSetName(String userId,String name)
  • 设置用户性别,存在则覆盖,gender值:{"男"|"女"}
/**
* 设置用户性别,存在则覆盖
* @param userId 用户id
* @param gender 用户性别
*/
public void profileSetGender(String userId,String gender)
  • 设置用户生日,存在则覆盖,birthday格式:"YYYY-MM-DD"
/**
* 设置用户生日,存在则覆盖
* @param userId 用户id
* @param birthday 用户生日,格式"YYYY-MM-DD"
*/
public void profileSetBirthday(String userId,String birthday)
  • 设置用户账号,存在则覆盖 ``` /**
  • 设置用户账号,存在则覆盖
  • @param userId 用户id
  • @param account 用户账号 */ public void profileSetAccount(String userId,String account) ```
  • 设置用户位置信息,包括国家、省份、城市,存在则覆盖
/**
* 设置用户账号,存在则覆盖
* @param userId 用户id
* @param account 用户账号
*/
public void profileSetLocation(String userId,String country,String province,String city)

普通事件

用户自定义的事件通过调用:

/**
* 记录多个属性的事件
* @param userId 用户id
* @param eventId 事件名称
* @param properties 属性值
*/
public void trackEvent(String userId,String eventId,Map<String,Object>properties)
/**
 * 记录多个属性的事件
 * @param userId 用户id
 * @param eventId 事件名
 * @param ip 客户端ip
 * @param properties 属性值
*/
public void trackEvent(String userId,String eventId,String ip,Map<String,Object>properties
/**
  * 记录多个属性的事件,并记录事件耗时
  *
  * @param userId     用户id
  * @param eventId    事件名称
  * @param costTime   事件耗时
  * @param properties 属性值
*/
public void trackEvent(String userId, String eventId, long costTime, Map<String, Object> properties)
/**
  * 记录多个属性的事件,并记录事件耗时
  *
  * @param userId     用户id
  * @param eventId    事件名称
  * @param ip         客户端ip
  * @param costTime   事件耗时
  * @param properties 属性值
*/
public void trackEvent(String userId, String eventId, String ip, long costTime, Map<String, Object> properties)

获取abtest实验变量配置

/**
  * 根据用户id获取abtest实验变量
  * @param userId 用户id
  * @param variableName 变量名称
  * @return
*/
public String getAbTestVariable(String userId,String variableName)

/**
  * 根据用户id获取abtest实验变量
  * @param userId 用户id
  * @param variableName 变量名称
  * @param isCache 是否使用缓存
  * @return
*/
public String getAbTestVariable(String userId,String variableName,boolean isCache)

获取abtest用户参与的所有的实验配置

/**
  * 获取用户参与的所有实验
  * @param userId 用户id
  * @return
*/
public JSONObject getAbTestVariable(String userId)

/**
  * 获取用户参与的所有实验
  * @param userId 用户id
  * @param isCache 是否使用缓存
  * @return
*/
public JSONObject getAbTestVariable(String userId,boolean isCache)

返回数据类型格式:
  {
    "variables": {
        "aColor": "1111",
        "class": "C"
    },
    "experiments": [{
        "versionId": "282",
        "variables": ["aColor"],
        "experimentId": "128"
    }, {
        "versionId": "146",
        "variables": ["class"],
        "experimentId": "65"
    }]
  }

1.4. 使用Demo

在这个 Demo 中,我们以一个典型的电商产品为例,描述一个用户从匿名访问网站,到下单购买商品,再到申请售后服务,这样一个整个环节,使用 Hubble Data Server(DA)的埋点,应该如何记录日志。

//demo示例
        DATracker daTracker=DATracker.init("MA-6RWE-QWHKHEKDF12");
        // 特别需要注意的是,这个 Demo 只是描述 DA的数据记录能力,并不是说使用者要完全照搬这些 Event 和 Property
        // 的设计,使用者还是需要结合自己产品的实际需要,来做相应的设计和规划
        // 1. 用户匿名访问网站
        String cookieId = "ABCDEF123456789"; // 用户未登录时,可以使用产品自己生成的cookieId来标注用户
        Map<String, Object> properties = new HashMap<String, Object>();
        // 1.1 访问首页

        // 前面有开头的property字段,是DA提供给用户的预置字段
        // 对于预置字段,已经确定好了字段类型和字段的显示名
        properties.clear();
        daTracker.setSuperProperty("os","windows");
        daTracker.setSuperProperty("osVersion","10.1.3"); // 操作系统的具体版本


        properties.put("time", new Date());                // 这条event发生的时间,如果不设置的话,则默认是当前时间
        properties.put("ip", "123.123.123.123");           // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("Channel", "baidu");                 // 用户是通过baidu这个渠道过来的
        daTracker.trackEvent(cookieId, "ViewHomePage", properties); // 记录访问首页这个event

        // 1.2 搜索商品
        properties.clear();
        properties.put("ip", "123.123.123.123"); // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("KeyWord", "黑猪肉");      // 搜索引擎引流过来时使用的关键词
        daTracker.trackEvent(cookieId, "SearchProduct", properties);      // 记录搜索商品这个event

        // 1.3 浏览商品
        properties.clear();
        properties.put("ip", "123.123.123.123");         // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("ProductName", "网易黑猪肉");           // 商品名称
        properties.put("ProductType", "生鲜");         //  商品类别
        properties.put("ShopName", "四季生鲜");         // 店铺名称
        daTracker.trackEvent(cookieId, "ViewProduct", properties);      // 记录浏览商品这个event

        // 2. 用户决定注册了
        String registerId = "123456";       // 用户注册时,分配给用户的注册Id

        // 2.1 通过,trackSignUP,把匿名ID和注册ID贯通起来
        properties.clear();
        properties.put("RegisterChannel", "baidu");   // 用户的注册渠道
        daTracker.trackSignUp(registerId, cookieId);

        // 2.2 用户注册时,填充了一些个人信息,可以用Profile接口记录下来
        Map<String, Object> profiles = new HashMap<String, Object>();
        profiles.put("city", "杭州");      // 用户所在城市
        profiles.put("province", "浙江");  // 用户所在省份
        profiles.put("name", "隔壁王小二");   // 用户的昵称
        profiles.put("signup_time", new Date()); // 注册时间
        profiles.put("Gender", "男");     // 用户的性别
        profiles.put("Birthday", "1990-10-29"); // 用户的出生日期
        profiles.put("RegisterChannel", "baidu");  // 用户的注册渠道
        daTracker.profileSet(registerId, profiles);    // 此时传入的是注册ID了


        // 3. 用户注册后,进行后续行为
        // 3.1 提交订单和提交订单详情
        // 这个订单里面包含一2斤黑猪肉和2盒粽子
        // 订单的信息
        properties.clear();
        properties.put("ip", "123.123.123.123");  // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N23234234");   // 订单ID
        properties.put("ShipPrice", 18.0);             // 运费
        properties.put("OrderTotalPrice", 388.0);         // 订单的总价格,默认是元
        daTracker.trackEvent(registerId, "SubmitOrder", properties); // 注意,此时使用的已经是注册ID了
        daTracker.profileSetOnce(registerId,"name","lip");
        // 订单中黑猪肉这个商品的信息
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N123123123");  // 订单ID
        properties.put("ProductName", "网易黑猪肉");    // 商品名称
        properties.put("ProductType", "生鲜");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 68.0);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 136.0);  // 商品总价
        daTracker.trackEvent(registerId, "SubmitOrderDetail", properties);
        // 订单中黑猪肉粽这个商品的信息
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N223423423452");  // 订单ID
        properties.put("ProductName", "黑猪肉粽");    // 商品名称
        properties.put("ProductType", "零食");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 28.0);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 56.0);  // 商品总价
        daTracker.trackEvent(registerId, "SubmitOrderDetail", properties);

        // 3.2 支付订单和支付订单详情
        // 整个订单的支付情况
        properties.clear();
        properties.put("ip", "123.123.123.123");         // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N12234234234");   // 订单ID
        properties.put("ShipPrice", 18.0);             // 运费
        properties.put("OrderTotalPrice", 210.0);         // 订单的总价格,默认是元
        properties.put("PaymentMethod", "AliPay");              // 支付方式
        properties.put("AllowanceAmount", 30.0);                   // 补贴金额
        properties.put("AllowanceType", "首次下单立减");        // 补贴类型
        properties.put("PaymentAmount", 180);      // 实际支付的订单金额
        daTracker.trackEvent(registerId, "PayOrder", properties);

        // 黑猪肉这个商品的支付情况
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N234234234234");  // 订单ID
        properties.put("ProductName", "网易黑猪肉");    // 商品名称
        properties.put("ProductType", "生鲜");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 68.0);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 136.0);  // 商品总价
        properties.put("ProductAllowanceAmount", 30.0); // 假设这个补贴是在黑猪肉上的折扣
        properties.put("ProductAllowanceType", "首次下单红立减");        // 补贴类型
        properties.put("ProductPaymentAmount", 106.0); // 黑猪肉实际支付了这么多
        properties.put("PaymentMethod", "AliPay");      // 与订单保持一致
        daTracker.trackEvent(registerId, "PayOrderDetail", properties);

        // 黑猪肉粽这个商品的支付情况
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N1231242343");  // 订单ID
        properties.put("ProductName", "黑猪肉粽");    // 商品名称
        properties.put("ProductType", "零食");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 28.0);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 56.0);  // 商品总价
        properties.put("ProductAllowanceAmount", 0.0); // 黑猪肉粽上并没有补贴
        properties.put("ProductAllowanceType", "无补贴");        // 补贴类型
        properties.put("ProductPaymentAmount", 56.0); // 黑猪肉粽实际支付了这么多
        properties.put("PaymentMethod", "AliPay");      // 与订单保持一致
        daTracker.trackEvent(registerId, "PayOrderDetail", properties);

        // 3.3 假设这个用户支付后反悔了,要取消订单
        // 整个订单的取消情况
        properties.clear();
        properties.put("ip", "123.123.123.123");         // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N123791273492734");   // 订单ID
        properties.put("ShipPrice", 18.0);             // 运费
        properties.put("OrderTotalPrice", 210.0);         // 订单的总价格,默认是元
        properties.put("CancelReason", "地址填写错误"); // 取消订单的原因
        properties.put("CancelTiming", "AfterPay");   // 取消订单的时机
        daTracker.trackEvent(registerId, "CancelOrder", properties);
        // 黑猪肉这个商品的取消情况
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N1232134234");  // 订单ID
        properties.put("ProductName", "黑猪肉");    // 商品名称
        properties.put("ProductType", "生鲜");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 68);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 136.0);  // 商品总价
        properties.put("CancelReason", "地址填写错误"); // 取消订单的原因
        properties.put("CancelTiming", "AfterPay");   // 取消订单的时机
        daTracker.trackEvent(registerId, "CancelOrderDetail", properties);
        // 黑猪肉粽这个商品的取消情况
        properties.clear();
        properties.put("ip", "123.123.123.123");     //请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N223423423452");  // 订单ID
        properties.put("ProductName", "黑猪肉粽");    // 商品名称
        properties.put("ProductType", "零食");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 28.0);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 56.0);  // 商品总价
        properties.put("CancelReason", "地址填写错误"); // 取消订单的原因
        properties.put("CancelTiming", "AfterPay");   // 取消订单的时机
        daTracker.trackEvent(registerId, "CancelOrderDetail", properties);

        // 4. 假设用户并没有取消订单,然后成功完成了配送
        // 黑猪肉这个商品的配送情况
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N223423423452");  // 订单ID
        properties.put("ProductName", "黑猪肉");    // 商品名称
        properties.put("ProductType", "零食");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 1200.0);   // 商品单价
        properties.put("ProductAmount", 1.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 1200.0);  // 商品总价
        properties.put("ProductAllowanceAmount", 30.0); // 假设这个补贴是在黑猪肉上的折扣
        properties.put("ProductPaymentAmount", 1170.0); // 黑猪肉实际支付了这么多
        properties.put("PaymentMethod", "AliPay");      // 与订单保持一致
        properties.put("SupplyTime", 49.0);       // 订单运送用了49小时
        properties.put("SupplyMethod", "顺丰");   // 通过顺丰运送的
        daTracker.trackEvent(registerId, "ReceiveProduct", properties);
        // 黑猪肉粽这个商品的配送情况
        properties.clear();
        properties.put("ip", "123.123.123.123");     // 请求中能够拿到用户的IP,则把这个传递给DA,DA会自动根据这个解析省份、城市
        properties.put("OrderId", "N223423423452");  // 订单ID
        properties.put("ProductName", "黑猪肉粽");    // 商品名称
        properties.put("ProductType", "零食");   // 商品类别
        properties.put("ShopName", "四季生鲜");  // 店铺名称
        properties.put("ProductUnitPrice", 12.0);   // 商品单价
        properties.put("ProductAmount", 2.0);         // 商品数量,可以是个数,也可以是重量
        properties.put("ProductTotalPrice", 24.0);  // 商品总价
        properties.put("ProductAllowanceAmount", 0.0); // 黑猪肉粽上并没有补贴
        properties.put("ProductPaymentAmount", 24.0); // 黑猪肉粽实际支付了这么多
        properties.put("PaymentMethod", "AliPay");      // 与订单保持一致
        properties.put("SupplyTime", 98.0);       // 订单运送用了98小时
        properties.put("SupplyMethod", "圆通");   // 通过圆通运送的
        daTracker.trackEvent(registerId,"delivery",properties);
        daTracker.profileSetBirthday(registerId,null);

        //使用abTest功能,获取实验配置
        daTracker=DATracker.init("MA-6RWE-QWHKHEKDF12",true);
        String color=daTracker.getAbTestVariable("hzlibuyi","color");
        if("blue".equals(color))
        {
            //TODO
        }else if("green".equals(color))
        {
            //TODO
        }else {
            //TODO
        }

        //删除该用户
        daTracker.profileDelete(registerId);

1.5. 通过接口直接采集数据

1.5.1. 数据格式:

  • 用户id 关联 ``` { "eventId": "da_u_signup", "dataType": "ie", "ip": null, "sdkType": "server", "time": 1495855781045, "sdkVersion": "1.0.0", "appKey": "MA-TF52-SDDFE56U1233", "userId": "ABCDEF123456789", "attributes": {
      "newUserId": "ABCDEF123456789",
      "os": "windows",
      "osVersion": "10.1.3",
      "oldUserId": "123456"
    
    } }
+ 用户信息设置

{ "eventId": "da_user_profile", "dataType": "ie", "ip": null, "sdkType": "server", "time": 1495856262386, "sdkVersion": "1.0.0", "appKey": "MA-TF52-SDDFE56U1233", "userId": "ABCDEF123456789", "attributes": { "$userProfile": { "$account": "hubbletest@163.com", "$type": "profile_set" } } }

#### 自定义事件

{ "eventId": "SubmitOrderDetail", "dataType": "e", "ip": "123.123.123.123", "sdkType": "server", "time": 1495855791103, "sdkVersion": "1.0.0", "appKey": "MA-TF52-SDDFE56U1233", "userId": "123456", "attributes": { "ShopName": "四季生鲜", "ProductAmount": 2, "os": "windows", "osVersion": "10.1.3", "ProductName": "网易黑猪肉", "ProductUnitPrice": 68, "ip": "123.123.123.123", "ProductType": "生鲜", "OrderId": "N123123123", "ProductTotalPrice": 136 } }

### 数据发送格式,如下:

https://hubble.netease.com/track/s/?data=eyJldmVudElkIjoidGhyZWFkLXRlc3QiLCJkYXRhVHlwZSI6ImUiLCJpcCI6IjEyMy4xMjMuMTIzLjEyMyIsInNka1R5cGUiOiJzZXJ2ZXItamF2YSIsImF0dHJpYnV0ZXMiOnsiJHRpbWUiOjE1MDE2NjUwMjk5MTYsIm9zIjoid2luZG93cyIsIm9zVmVyc2lvbiI6IjEwLjEuMyIsImlwIjoiMTIzLjEyMy4xMjMuMTIzIiwiQ2hhbm5lbCI6ImJhaWR1In0sInNka1ZlcnNpb24iOiIxLjAuMCIsImFwcEtleSI6Ik1BLTZSV0UtUVdIS0hFS0RGMTIiLCJ0aW1lIjoxNTAxNjY1MDI5OTE2LCJ1c2VySWQiOiJsaWJ1eWktdGVzdCJ9

### 注意
+ 每一条数据都必须符合json格式
+ 需要将数据进行base64加密 
+ 请求通过get的方式发送,请求参数为data
+ 请求增加两个request header

1.X-SHA1-APPKEY 如 java发送请求: httpGet.addHeader("X-SHA1-APPKEY", SHA1Util.encryptSHA(appkey)); 其中appkey要经过sha1加密 2.X-CLIENT-IP 移动端ip,获取不到可以不填 ```

  • 自定义属性都需要放在attributes里
  • eventId,dataType,sdkType,sdkVersion,time,appKey,userId为第一层级的数据,且必填

results matching ""

    No results matching ""