# Ruby SDK 使用指南

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

最新版本为:1.2.0

更新时间为:2020-08-28

# 一、集成 SDK

# 1.1 安装 SDK

请使用gem命令获取 SDK 包

# 获取 SDK
gem install thinkingdata-ruby

# 1.2 创建 SDK 实例

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

require 'thinkingdata-ruby'

为使用 SDK 上传数据,需要首先创建 TDAnalytics::Tracker 对象。TDAnalytics::Tracker 是数据上报的核心类,通过使用该类能够上报事件数据与用户属性数据。创建 Tracker 对象需要传入 consumer 对象,consumer 决定了数据的上报方式(存储在本地日志文件还是上传到服务端)。

# 创建Tracker对象
ta = TDAnalytics::Tracker.new(consumer)

# 上报数据
ta.track('your_event', distinct_id: 'distinct_id_of_user')

TDAnalytics 提供了三种 consumer 实现:

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

# 默认写入当前目录的文件,按日期命名(daily),例如: tda.log.2019-11-15
consumer = TDAnalytics::LoggerConsumer.new

# 也可以修改配置,如下配置会创建 LoggerConsumer,并将数据写入: /path/to/log/demolog.2019-11-15-18 (18 为小时)
consumer = TDAnalytics::LoggerConsumer.new('/path/to/log', 'hourly', prefix: 'demolog')

(2) DebugConsumer: 逐条实时向 TA 服务器传输数据,当数据格式错误时会返回详细的错误信息。建议先使用 DebugConsumer 校验数据格式。初始化传入项目 APP ID 和接收端地址。注意不要在生产环境中使用

# 创建 DebugConsumer
consumer = TDAnalytics::DebugConsumer.new(SERVER_URL, YOUR_APPID)

如果您不想数据入库,只想校验数据格式,您可以初始化代码如下:

# 创建 DebugConsumer
consumer = TDAnalytics::DebugConsumer.new(SERVER_URL, DEMO_APPID,false)

SERVER_URL为传输数据的 URL,YOUR_APPID为您的项目的 APP ID

如果您使用的是云服务,请输入以下 URL:

http://receiver.ta.thinkingdata.cn/

如果您使用的是私有化部署的版本,请输入以下 URL:

http://数据采集地址

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

BatchConsumer 会先将数据存放在缓冲区中,当数据条数超过设定的缓冲区最大值(max_buffer_length, 默认为 20),触发上报. 您也可以在初始化 SDK 时传入整数类型的参数配置缓冲区大小:

 # BatchConsumer,数据将先存入缓冲区,达到指定条数时上报,默认为 20 条
 consumer = TDAnalytics::BatchConsumer.new(SERVER_URL, YOUR_APPID)

 # 创建指定缓冲区大小为 3 条的 BatchConsumer
 #consumer = TDAnalytics::BatchConsumer.new(SERVER_URL, YOUR_APPID, 3)

 #设置是否压缩数据,默认true代表gzip压缩,内网可以这样设置
 #consumer = TDAnalytics::BatchConsumer.new(SERVER_URL, YOUR_APPID)
 #consumer._set_compress(false)

SERVER_URL为传输数据的 URL,YOUR_APPID为您的项目的 APP ID

如果您使用的是云服务,请输入以下 URL:

http://receiver.ta.thinkingdata.cn/

如果您使用的是私有化部署的版本,请输入以下 URL:

http://数据采集地址/

注:1.0.0 版本输入以下 URL:

http://receiver.ta.thinkingdata.cn/logagent
http://数据采集地址/logagent

您也可以传入自己实现的 Consumer,只需实现以下接口:

  • add(message): (必须) 接受 Hash 类型的数据对象
  • flush: (可选) 将缓冲区的数据发送到指定地址
  • close: (可选) 程序退出时用户可以主动调用此接口以保证安全退出

# 二、上报数据

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

# 2.1 发送事件

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

# 定义事件数据
event = {
  # 事件名称 (必填)
  event_name: 'test_event',
  # 账号 ID (可选)
  account_id: 'ruby_test_aid',
  # 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
  distinct_id: 'ruby_distinct_id',
  # 事件时间 (可选) 如果不填,将以调用接口时的时间作为事件时间
  time: Time.now,
  # 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地
  ip: '202.38.64.1',
  # 事件属性 (可选)
  properties: {
    prop_date: Time.now,
    prop_double: 134.1,
    prop_string: 'hello world',
    prop_bool: true,
  },
  # 跳过本地格式校验 (可选)
  # skip_local_check: true,
}

# 上传事件
ta.track(event)

参数说明:

  • 事件的名称只能以字母开头,可包含数字,字母和下划线“_”,长度最大为 50 个字符,对字母大小写不敏感
  • 事件的属性是 Hash 类型,其中每个元素代表一个属性
  • 事件属性的 Key 值为属性的名称,为 String 类型,规定只能以字母开头,包含数字,字母和下划线“_”,长度最大为 50 个字符,对字母大小写不敏感
  • 事件属性的 Value 值为该属性的值,支持 String、数值类型、boolTime, 数组类型

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

# 2.2 设置公共事件属性

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

# 定义公共属性
super_properties = {
  super_string: 'super_string',
  super_int: 1,
  super_bool: false,
  super_date: Time.rfc2822("Thu, 26 Oct 2019 02:26:12 +0545")
}

# 设置公共事件属性,公共事件属性会添加到每个事件中
ta.set_super_properties(super_properties)

# 清空公共事件属性
ta.clear_super_properties

# 2.3 用户属性

# 2.3.1 user_set

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

# 定义用户属性数据
user_data = {
	# 账号 ID (可选)
	account_id: 'ruby_test_aid',
	# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
	distinct_id: 'ruby_distinct_id',
	# 用户属性
  properties: {
    prop_date: Time.now,
    prop_double: 134.12,
    prop_string: 'hello',
    prop_int: 666,
	},
}

# 设置用户属性
ta.user_set(user_data);

# 2.3.2 user_set_once

如果您要上传的用户属性只要设置一次,则可以调用 user_set_once 来进行设置,当该属性之前已经有值的时候,将会忽略这条信息,以此保证传入值是第一次接收到的值:

# 设置用户属性,如果该用户的该属性有值,则忽略新设置属性
ta.user_set_once(user_data);

# 2.3.3 user_add

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

# 对数值类型的属性进行累加操作
ta.user_add(distinct_id: 'ruby_distinct_id', properties: {prop_int: 10, prop_double: 15.88})

# 2.3.4 user_unset

当您需要清空某个用户的用户属性的值时,可以调用 user_unset 进行清空:

# 清空某个用户的某个用户属性
ta.user_unset(distinct_id: 'ruby_distinct_id', property: :prop_string)

# 清空某个用户的一组用户属性
ta.user_unset(distinct_id: 'ruby_distinct_id', property: Array.[](:prop_a, :prop_b, :prob_c))

# 2.3.5 user_append

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

 #追加user的一个或者多个列表的属性
 user_data_arr = {
     # 账号 ID (可选)
     account_id: ACCOUNT_ID,
     # 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
     distinct_id: DISTINCT_ID,
     # 用户属性
     properties: {//key-array形式上传,array里面数据最后都会toString
         array: ["11", "22"],
     },
 }
 ta.user_append(user_data_arr)

# 2.3.6 user_del

# 删除用户
ta.user_del(
	# 账号 ID (可选)
	account_id: 'ruby_test_aid',
	# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
	distinct_id: 'ruby_distinct_id',
);

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

# 删除用户
ta.user_del(
	# 账号 ID (可选)
	account_id: 'ruby_test_aid',
	# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
	distinct_id: 'ruby_distinct_id',
);

# 三、进阶功能

从 v1.2.0 开始,SDK 支持上报两种特殊类型事件: 可更新事件、可重写事件。这两种事件需要配合 TA 系统 2.8 及之后的版本使用。由于特殊事件只在某些特定场景下适用,所以请在数数科技的客户成功和分析师的帮助下使用特殊事件上报数据。

# 3.1 可更新事件

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

// 示例: 上报可被更新的事件,假设事件名为 event_update
event_name = 'event_update'
event_id = '123'
account_id = '123'
distinct_id: '65478cc0-275a-4aeb-9e6b-861155b5aca7'
prop = {
          price: 100,
          status: 3,
      }
      // 上报后事件属性 status 为 3, price 为 100
 event_update = {
      # 事件名称 (必填) string
      event_name:event_name,
      # 事件ID (必填) string
      event_id: event_id,
      # 账号 ID (可选)string
      account_id:account_id,
      # 访客 ID (可选),账号 ID 和访客 ID 不可以都为空 string
      distinct_id: distinct_id,
      # 事件时间 (可选) 如果不填,将以调用接口时的当前时间作为事件时间
      time: Time.now,
      # 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地
      ip: '202.38.64.1',
      # 事件属性 (可选)
      properties: prop,
  }
 ta.track_update(event_update)

// 上报后同样event_name + event_id 的事件属性 status 被更新为 5, price 不变
_new_proterties = {
  status: 5,
}
 event_update = {
      event_name:event_name,
      event_id: event_id,
      account_id:account_id,
      distinct_id: distinct_id,
      time: Time.now,
      ip: '202.38.64.1',
      properties: _new_proterties,
  }
ta.track_update(event_update)

# 3.2 可重写事件

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

// 示例: 上报可被重写的事件,假设事件名为 OVERWRITE_EVENT
event_name = 'event_overwrite'
event_id = '123'
account_id = '123'
distinct_id: '65478cc0-275a-4aeb-9e6b-861155b5aca7'
prop = {
          price: 100,
          status: 3,
      }
      // 上报后事件属性 status 为 3, price 为 100
 event_overwrite = {
      # 事件名称 (必填) string
      event_name:event_name,
      # 事件ID (必填) string
      event_id: event_id,
      # 账号 ID (可选)string
      account_id:account_id,
      # 访客 ID (可选),账号 ID 和访客 ID 不可以都为空 string
      distinct_id: distinct_id,
      # 事件时间 (可选) 如果不填,将以调用接口时的当前时间作为事件时间
      time: Time.now,
      # 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地
      ip: '202.38.64.1',
      # 事件属性 (可选)
      properties: prop,
  }
 ta.track_overwrite(event_overwrite)

// 上报后同样event_name + event_id 的事件属性 status 被更新为 5, price 属性被删除

_new_prop = {
  status: 5,
}
 event_overwrite = {
      event_name:event_name,
      event_id: event_id,
      account_id:account_id,
      distinct_id: distinct_id,
      time: Time.now,
      ip: '202.38.64.1',
      properties: _new_prop,
  }
ta.track_overwirte(event_overwrite)

# 四、其他操作

# 4.1 立即进行数据 IO

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

# 立即提交数据到相应的接收端
ta.flush

# 4.2 关闭 SDK

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

# 关闭并退出 SDK
ta.close

# 4.3 异常处理

默认情况下,除初始化参数不合法外,其他 Error 会被忽略,如果您希望自己处理接口调用中的 Error,可以传入自定义的 error handler.

# (可选) 定义一个错误处理器,当出现 Error 时会调用
class MyErrorHandler < TDAnalytics::ErrorHandler
  def handle(error)
      puts error
      raise error
  end
end
my_error_handler = MyErrorHandler.new

# 创建 TA 实例, 第一个参数为任意一种 Consumer, 第二个参数可选,如果设定了会在出错时调用
ta = TDAnalytics::Tracker.new(consumer, my_error_handler, uuid: true)

uuid 如果为 true,每条数据都会被带上随机 UUID 作为 #uuid 属性的值上报,该值不会入库,仅仅用于后台做数据重复检测.

# ChangeLog

# v1.2.0 (2020/08/28)

  • 新增 track_update 接口,支持可更新事件
  • 新增 track_overwrite 接口,支持可重写事件

# v1.1.0 (2020/02/11)

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

# v1.0.0 (2019-11-20)

  • 支持三种模式的上报: DebugConsumer, BatchConsumer, LoggerConsumer.
  • 支持事件上报和用户属性上报.
  • 支持公共事件属性.