目录
此内容是否有帮助?

# Node.js SDK 使用指南

本指南将会为您介绍如何使用 Node.js SDK 接入您的项目。您可以在访问GitHub (opens new window)获取 Node.js SDK 的源代码。

最新版本为:1.3.0

更新时间为:2022-04-27

# 一、集成 SDK

# 1.1 安装 SDK

请使用npm获取 Node.js SDK:

# 获取 SDK
npm install thinkingdata-node --save

# 更新 SDK
npm i thinkingdata-node@{版本号}

# 1.2 创建 SDK 实例

首先在代码文件开头引入 thinkingdata-node

var ThinkingAnalytics = require("thinkingdata-node");

为使用 SDK 上传数据,需首先创建 SDK 实例. 我们提供了三种 SDK 实例的初始化方法:

// Debug Mode: 逐条发送,并返回详细的错误信息
var ta = ThinkingAnalytics.initWithDebugMode("APP-ID", "https://SERVER_URL");

//如果希望仅仅校验数据格式而不真正入库,可以通过 config 传入:
//config = {
//    dryRun: true
//};
//var ta = ThinkingAnalytics.initWithDebugMode('APP-ID', 'https://SERVER_URL',config);
// Batch Mode:批量发送到接收端
var ta = ThinkingAnalytics.initWithBatchMode("APP-ID", "https://SERVER_URL");

//也可配置初始化发送:
//config = {
//    batchSize: 2,//设置flush数据
//    compress :false//默认true 代表gzip压缩,false适合在内网设置
//}
//var ta = ThinkingAnalytics.initWithBatchMode('APP-ID', 'https://SERVER_URL',config);
//
// Logging Mode: 将数据写入本地日志文件,需要配合 LogBus 使用
var ta = ThinkingAnalytics.initWithLoggingMode("/PATH/TO/DATA");

三种模式说明如下:

(1) Debug Mode: 逐条实时向 TA 服务器传输数据,当数据格式错误时会返回详细的错误信息。建议先使用 DebugConsumer 校验数据格式。初始化传入项目 APP ID 和接收端地址。仅限于调试模式,生产环境请使用下面两种模式。

(2) Batch Mode: 批量实时地向 TA 服务器传输数据,不需要搭配传输工具。在网络条件不好的情况下有可能会导致数据丢失,因此不建议在生产环境中大量使用。初始化传入项目 APP ID 和接收端地址。

Batch Mode 会先将数据存放在缓冲区中,当数据条数超过设定的值(batchSize, 默认为 20),触发上报. 您也可以在初始化 SDK 的时候指定传入配置:

// 初始化 SDK, 指定接收端地址、APP ID、缓冲区大小
var ta = ThinkingAnalytics.initWithBatchMode("APP-ID", "https://SERVER_URL", {
  batchSize: 10, // 缓存数据到达 10 条时触发上报
  enableLog: true // 允许打印发送数据. 当开启日志的时候会打印详细的发送日志
});

(3) Logging Mode: 将数据实时写入本地文件,文件以天/小时切分,并需要与 LogBus 搭配使用进行数据上传,建议在生产环境使用。

Logging Mode 使用 log4js 将数据实时保存为本地日志文件,后续需要配合 LogBus 将日志文件导入到 TA 数据库中:

// 日志数据存放目录
var logPath = "/home/app/logs/";

// 初始化 SDK 实例
var ta = ThinkingAnalytics.initWithLoggingMode(logPath);

日志文件默认按天切分,您可以在初始化 SDK 的时候传入配置对象将日志切分模式改为按小时切分:

// 初始化 SDK,按小时切分日志文件.
var ta = ThinkingAnalytics.initWithLoggingMode(logPath, { rotateHourly: true });

TIP

如果您使用 pm2 来管理您 Node.js 应用,则需要根据以下步骤设置启动参数:

  1. 安装 pm2-intercom:
pm2 install pm2-intercom
  1. 初始化 SDK 时传入 pm2 参数
// 初始化 SDK,按小时切分日志文件,指定 pm2 模式
var ta = ThinkingAnalytics.initWithLoggingMode(logPath, {
  rotateHourly: true,
  pm2: true
});

WARNING

如果您在 pm2 配置中指定了 instance_var, 则需要在初始化配置中传入该参数。假设在 pm2 配置中指定了 instance_var 为 'INSTANCE_ID', 初始化 SDK 时应传入以下参数:

// 初始化 SDK,按小时切分日志文件,指定 pm2 模式,指定 pm2InstanceVar
var ta = ThinkingAnalytics.initWithLoggingMode(logPath, {
  rotateHourly: true,
  pm2: true,
  pm2InstanceVar: "INSTANCE_ID"
});

(4) AsyncBatchConsumer Mode: 批量实时地向 TA 服务器传输数据(异步非阻塞),不需要搭配传输工具。在网络条件不好的情况下有可能会导致数据丢失,因此不建议在生产环境中大量使用。初始化传入项目 APP ID 和接收端地址。

AsyncBatch Mode 会先将数据存放在缓冲区中,当数据条数超过设定的值(batchSize, 默认为 20)或者定时(默认3秒),触发上报. 您也可以在初始化 SDK 的时候指定传入配置:

let taAsyncBatch = ThinkingAnalytics.initWithAsyncBatchMode('cf918051b394495ca85d1b7787ad7243', 'https://global-receiver-ta.thinkingdata.cn', {
    batchSize: 10,
    enableLog: true,
    interval: 5000,// 触发上报时间间隔
    compress: false//默认true 代表gzip压缩,false适合在内网设置
});

# 二、上报数据

SDK 初始化完成后,后续即可使用 ta 的接口来上报数据。

# 2.1 发送事件

您可以调用 track 来上传事件,建议您根据预先梳理的文档来设置事件的属性以及发送信息的条件。上传事件示例如下:

// 定义事件数据
var event = {
  // 账号 ID (可选)
  accountId: "node_test",
  // 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
  distinctId: "node_distinct_id",
  // 事件名称 (必填)
  event: "test_event",
  // 事件时间 (可选) 如果不填,将以调用接口时的时间作为事件时间
  time: new Date(),
  // 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地
  ip: "202.38.64.1",
  // 事件属性 (可选)
  properties: {
    prop_date: new Date(),
    prop_double: 134.1,
    prop_string: "hello world",
    prop_int: 67
  },
  // 出错时回调 (可选)
  callback(e) {
    if (e) {
      console.log(e);
    }
  }
};

// 上传事件
ta.track(event);

参数说明:

  • 事件的名称只能以字母开头,可包含数字,字母和下划线“_”,长度最大为 50 个字符,对字母大小写不敏感
  • 事件的属性是 map 类型,其中每个元素代表一个属性
  • 事件属性的 Key 值为属性的名称,为 string 类型,规定只能以字母开头,包含数字,字母和下划线“_”,长度最大为 50 个字符,对字母大小写不敏感
  • 事件属性的Value 为该属性的值,支持 StringNumberBooleanDateObjectArray;Object中的内容可以为StringNumberBooleanDateArray(内容为字符串);Array中的内容可以为ObjectString

SDK 会在本地对数据格式做校验,如果希望跳过本地校验,可以在调用 track 接口的时候传入 skipLocalCheck 参数:

// 跳过本地数据校验
ta.track(event, true);

# 2.2 设置公共事件属性

公共事件属性是每个事件都会包含的属性,普通的公共属性是定值,您也可以设置动态公共属性,该属性将会在事件上报时取值并加入到事件中。如果有相同的属性,则动态公共属性会覆盖公共事件属性。

// 设置动态公共属性
ta.setDynamicSuperProperties(() => {
  var date = new Date();
  date.setYear(2018);
  return {
    super_date: date,
    super_int: 5
  };
});

// 设置公共事件属性
ta.setSuperProperties({
  super_int: 8, // 不会出现在最终上报数据,因为会被动态公共属性覆盖.
  super_debug_string: "hahahaha"
});

// 清空公共事件属性
ta.clearSuperProperties();

# 三、设置用户属性

# 3.1 userSet

对于一般的用户属性,您可以调用 userSet 来进行设置. 使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性:

// 用户属性数据
var userData = {
  // 账号 ID (可选)
  accountId: "node_test",
  // 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
  distinctId: "node_distinct_id",
  // 用户属性
  properties: {
    prop_date: new Date(),
    prop_double: 134.12,
    prop_string: "hello",
    prop_int: 666
  },
  // 出错时回调 (可选)
  callback(e) {
    if (e) {
      console.log(e);
    }
  }
};

// 设置用户属性
ta.userSet(userData);

属性格式要求与事件属性保持一致。

# 3.2 userSetOnce

如果您要上传的用户属性只要设置一次,则可以调用 userSetOnce 来进行设置,当该属性之前已经有值的时候,将会忽略这条信息:

ta.userSetOnce(userData);

属性格式要求与事件属性保持一致。

# 3.3 userAdd

当您要上传数值型的属性时,可以调用 userAdd 来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算:

// 累加用户属性
ta.userAdd({
  accountId: "node_test",
  properties: {
    Amount: 222
  }
});

设置的属性key为字符串,Value 只允许为数值。

# 3.4 userDel

如果您要删除某个用户,可以调用 userDel 将这名用户删除. 之后您将无法再查询该用户的用户属性,但该用户产生的事件仍然可以被查询到:

// 删除用户
ta.userDel({
  // 账号 ID (可选)
  accountId: "node_test",
  // 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
  distinctId: "node_distinct_id"
});

# 3.5 userAppend

当您要为 array 类型追加用户属性值时,您可以调用user_append来对指定属性进行追加操作,如果该属性还未在集群中被创建,则user_append创建该属性

// 为用户列表类型追加属性 key - array ,array 为string数组
ta.userAppend({
  accountId: "node_test",
  properties: {
    prop_array: ["str3", "str4"]
  }
});

# 3.6 userUnset

当您要清空用户的用户属性值时,您可以调用user_unset来对指定属性进行清空操作,如果该属性还未在集群中被创建,则user_unset不会创建该属性

//删除用户某一个属性
ta.userUnset({
  accountId: "node_test",
  property: "prop_double"
});

userUnset: 的传入值为被清空属性的 Key 值。

# 3.7 userUniqAppend

v1.3.0开始,您可以通过user_uniq_appendArray添加元素,和user_append不同的是,user_uniq_append会对Array内元素进行去重处理。

ta.userUniqAppend({
    accountId: 'node_test',
    properties: {
        prop_array: ['str3', 'str4']
    }
});

# 四、其他操作

# 4.1 立即进行数据 IO

此操作与具体的 Consumer 实现有关. 在收到数据时, Consumer 可以先将数据存放在缓冲区, 并在一定情况下触发真正的数据 IO 操作, 以提高整体性能. 在某些情况下需要立即提交数据,可以调用 Flush 接口:

// 立即提交数据到相应的接收端
ta.flush();

# 4.2 关闭 SDK

请在退出程序前调用本接口,以避免缓存内的数据丢失:

// 关闭并退出 SDK
ta.close();

# 4.3 打开日志

设置环境变量 NODE_DEBUG=tda, 可以打开日志.

# 五、进阶功能

# 5.1 可更新事件

您可以通过可更新事件实现特定场景下需要修改事件数据的需求。可更新事件需要指定标识该事件的 ID,并在创建可更新事件对象时传入。TA 后台将根据事件名和事件 ID 来确定需要更新的数据。

let updateProperties = {
    event_id: 1,
    price: 100,
    status: 3,
}
ta.trackUpdate(updateProperties)

// 上报后同样event_id 事件属性 status 被更新为 5, price 不变
let updatePropertiesNew = {
    event_id: 1,
    price: 100,
    status: 5,
}
ta.trackUpdate(updateProperties)

# 5.2 可重写事件

可重写事件与可更新事件类似,区别在于可重写事件会用最新的数据完全覆盖历史数据,从效果上看相当于删除前一条数据,并入库最新的数据。TA 后台将根据事件名和事件 ID 来确定需要更新的数据。

let overwriteProperties = {
    event_id: 1,
    price: 100,
    status: 3,
}
ta.trackUpdate(updateProperties)

// 上报后事件属性 status 被更新为 5, price 属性被删除
let overwriteProperties = {
    event_id: 1,
    price: 100,
    status: 5,
}
ta.trackOverWrite(overwriteProperties)

# 5.3 首次事件

使用”首次事件校验“特性,需要在properties中设置#first_check_id字段,类型为字符串,该字段是校验首次事件的标识 ID,该 ID 首条出现的数据将入库,之后出现的都无法入库。不同事件的#first_check_id互相独立,因此每个事件的首次校验互不干扰

let firstProperties = {
    first_check_id: 12345,
    price: 100,
    status: 3,
}
ta.trackFirst(updateProperties)

# ChangeLog

# v1.2.2 2021/10/14

  • 可以上传预置属性
  • 取消字段名长度限制

# v1.2.1 2021/08/31

  • LoggingConsumer 优化: 支持指定文件前缀

# v1.2.0 2020/10/16

  • 支持首次事件上报
  • 支持可更新和可重写事件上报

# v1.1.2 2020/09/08

  • 解决只传入 distinctId 不生效的问题

# v1.1.1 2020/04/14

  • 修复上报地址不支持端口号的 bug

# v1.1.0 2020/02/12

  • 支持上报数组类型
  • 新增 user_append 接口,支持用户的数组类型的属性追加
  • DebugConsumer 优化: 在服务端对数据进行更完备准确地校验
  • BatchConsumer 性能优化:支持配置压缩模式;移除 Base64 编码

# v1.0.1 2019/11/07

  • 支持三种模式的上报: Debug, Batch, Logging.
  • 支持事件上报和用户属性上报.
  • 支持公共事件属性和动态公共事件属性.