thinkingdata-ruby 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +59 -0
- data/CHANGELOG.md +22 -14
- data/Gemfile +7 -7
- data/LICENSE +201 -201
- data/README.md +11 -202
- data/demo/demo.rb +104 -142
- data/lib/thinkingdata-ruby/td_analytics.rb +495 -0
- data/lib/thinkingdata-ruby/{batch_consumer.rb → td_batch_consumer.rb} +142 -120
- data/lib/thinkingdata-ruby/td_debug_consumer.rb +73 -0
- data/lib/thinkingdata-ruby/td_errors.rb +38 -0
- data/lib/thinkingdata-ruby/td_logger_consumer.rb +77 -0
- data/lib/thinkingdata-ruby/td_version.rb +3 -0
- data/lib/thinkingdata-ruby.rb +5 -5
- data/thinkingdata-ruby.gemspec +16 -16
- metadata +13 -12
- data/lib/thinkingdata-ruby/debug_consumer.rb +0 -61
- data/lib/thinkingdata-ruby/errors.rb +0 -35
- data/lib/thinkingdata-ruby/logger_consumer.rb +0 -57
- data/lib/thinkingdata-ruby/tracker.rb +0 -402
- data/lib/thinkingdata-ruby/version.rb +0 -3
data/README.md
CHANGED
@@ -1,202 +1,11 @@
|
|
1
|
-
# ThinkingData
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
```
|
13
|
-
#### 2. 创建 SDK 实例
|
14
|
-
首先在代码文件开头引入 `thinkingdata-ruby`:
|
15
|
-
```ruby
|
16
|
-
require 'thinkingdata-ruby'
|
17
|
-
```
|
18
|
-
|
19
|
-
使用 SDK 上传数据,需要首先创建 `TDAnalytics::Tracker` 对象. `TDAnalytics::Tracker` 是数据上报的核心类,使用此类上报事件数据和更新用户属性. 创建 `Tracker` 对象需要传入 consumer 对象,consumer 决定了如何处理格式化的数据(存储在本地日志文件还是上传到服务端).
|
20
|
-
|
21
|
-
```ruby
|
22
|
-
ta = TDAnalytics::Tracker.new(consumer)
|
23
|
-
ta.track('your_event', distinct_id: 'distinct_id_of_user')
|
24
|
-
```
|
25
|
-
TDAnalytics 提供了三种 consumer 实现:
|
26
|
-
|
27
|
-
**(1) LoggerConsumer**: 将数据实时写入本地文件,文件以 天/小时 切分,并需要与 LogBus 搭配使用进行数据上传.
|
28
|
-
```ruby
|
29
|
-
# 默认写入当前目录的文件,按日期命名(daily),例如: tda.log.2019-11-15
|
30
|
-
consumer = TDAnalytics::LoggerConsumer.new
|
31
|
-
|
32
|
-
# 也可以修改配置,如下配置会创建 LoggerConsumer,并将数据写入: /path/to/log/demolog.2019-11-15-18 (18 为小时)
|
33
|
-
consumer = TDAnalytics::LoggerConsumer.new('/path/to/log', 'hourly', prefix: 'demolog')
|
34
|
-
```
|
35
|
-
|
36
|
-
**(2) DebugConsumer**: 逐条实时向 TA 服务器传输数据,当数据格式错误时会返回详细的错误信息。建议先使用 DebugConsumer 校验数据格式。初始化传入项目 APP ID 和接收端地址.
|
37
|
-
```ruby
|
38
|
-
# 创建 DebugConsumer
|
39
|
-
consumer = TDAnalytics::DebugConsumer.new(SERVER_URL, YOUR_APPID)
|
40
|
-
```
|
41
|
-
|
42
|
-
**(3) BatchConsumer**: 批量实时地向 TA 服务器传输数据,不需要搭配传输工具。在网络条件不好的情况下有可能会导致数据丢失,因此不建议在生产环境中大量使用. 初始化传入项目 APP ID 和接收端地址.
|
43
|
-
|
44
|
-
BatchConsumer 会先将数据存放在缓冲区中,当数据条数超过设定的缓冲区最大值(max_buffer_length, 默认为20),触发上报. 您也可以在初始化 SDK 时传入整数类型的参数配置缓冲区大小:
|
45
|
-
```ruby
|
46
|
-
# BatchConsumer,数据将先存入缓冲区,达到指定条数时上报,默认为 20 条
|
47
|
-
consumer = TDAnalytics::BatchConsumer.new(SERVER_URL, YOUR_APPID)
|
48
|
-
|
49
|
-
# 创建指定缓冲区大小为 3 条的 BatchConsumer
|
50
|
-
consumer = TDAnalytics::BatchConsumer.new(SERVER_URL, YOUR_APPID, 3)
|
51
|
-
```
|
52
|
-
|
53
|
-
您也可以传入自己实现的 Consumer,只需实现以下接口:
|
54
|
-
- add(message): (必须) 接受 Hash 类型的数据对象
|
55
|
-
- flush: (可选) 将缓冲区的数据发送到指定地址
|
56
|
-
- close: (可选) 程序退出时用户可以主动调用此接口以保证安全退出
|
57
|
-
|
58
|
-
#### 3. 上报数据
|
59
|
-
SDK 初始化完成后,后续即可使用 ta 的接口来上报数据.
|
60
|
-
|
61
|
-
### 使用示例
|
62
|
-
|
63
|
-
#### a. 发送事件
|
64
|
-
您可以调用 track 来上传事件,建议您根据预先梳理的文档来设置事件的属性以及发送信息的条件。上传事件示例如下:
|
65
|
-
```ruby
|
66
|
-
# 定义事件数据
|
67
|
-
event = {
|
68
|
-
# 事件名称 (必填)
|
69
|
-
event_name: 'test_event',
|
70
|
-
# 账号 ID (可选)
|
71
|
-
account_id: 'ruby_test_aid',
|
72
|
-
# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
|
73
|
-
distinct_id: 'ruby_distinct_id',
|
74
|
-
# 事件时间 (可选) 如果不填,将以调用接口时的时间作为事件时间
|
75
|
-
time: Time.now,
|
76
|
-
# 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地
|
77
|
-
ip: '202.38.64.1',
|
78
|
-
# 事件属性 (可选)
|
79
|
-
properties: {
|
80
|
-
prop_date: Time.now,
|
81
|
-
prop_double: 134.1,
|
82
|
-
prop_string: 'hello world',
|
83
|
-
prop_bool: true,
|
84
|
-
},
|
85
|
-
# 跳过本地格式校验 (可选)
|
86
|
-
# skip_local_check: true,
|
87
|
-
}
|
88
|
-
|
89
|
-
# 上传事件
|
90
|
-
ta.track(event)
|
91
|
-
```
|
92
|
-
|
93
|
-
参数说明:
|
94
|
-
* 事件的名称只能以字母开头,可包含数字,字母和下划线“_”,长度最大为 50 个字符,对字母大小写不敏感
|
95
|
-
* 事件的属性是 Hash 类型,其中每个元素代表一个属性
|
96
|
-
* 事件属性的 Key 值为属性的名称,为 string 类型,规定只能以字母开头,包含数字,字母和下划线“_”,长度最大为 50 个字符,对字母大小写不敏感
|
97
|
-
* 事件属性的 Value 值为该属性的值,支持 String、数值类型、bool、Time
|
98
|
-
|
99
|
-
SDK 会在本地对数据格式做校验,如果希望跳过本地校验,可以在调用 track 接口的时候传入 skip_local_check 参数.
|
100
|
-
|
101
|
-
#### 2. 设置公共事件属性
|
102
|
-
公共事件属性是每个事件都会包含的属性. 也可以设置动态公共属性。如果有相同的属性,则动态公共属性会覆盖公共事件属性。
|
103
|
-
|
104
|
-
```ruby
|
105
|
-
# 定义公共属性
|
106
|
-
super_properties = {
|
107
|
-
super_string: 'super_string',
|
108
|
-
super_int: 1,
|
109
|
-
super_bool: false,
|
110
|
-
super_date: Time.rfc2822("Thu, 26 Oct 2019 02:26:12 +0545")
|
111
|
-
}
|
112
|
-
|
113
|
-
# 设置公共事件属性,公共事件属性会添加到每个事件中
|
114
|
-
ta.set_super_properties(super_properties)
|
115
|
-
|
116
|
-
# 清空公共事件属性
|
117
|
-
ta.clear_super_properties
|
118
|
-
```
|
119
|
-
|
120
|
-
#### 3. 设置用户属性
|
121
|
-
对于一般的用户属性,您可以调用 user_set 来进行设置. 使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性:
|
122
|
-
```ruby
|
123
|
-
# 定义用户属性数据
|
124
|
-
user_data = {
|
125
|
-
# 账号 ID (可选)
|
126
|
-
account_id: 'ruby_test_aid',
|
127
|
-
# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
|
128
|
-
distinct_id: 'ruby_distinct_id',
|
129
|
-
# 用户属性
|
130
|
-
properties: {
|
131
|
-
prop_date: Time.now,
|
132
|
-
prop_double: 134.12,
|
133
|
-
prop_string: 'hello',
|
134
|
-
prop_int: 666,
|
135
|
-
},
|
136
|
-
}
|
137
|
-
|
138
|
-
# 设置用户属性
|
139
|
-
ta.user_set(user_data);
|
140
|
-
```
|
141
|
-
如果您要上传的用户属性只要设置一次,则可以调用 user_set_once 来进行设置,当该属性之前已经有值的时候,将会忽略这条信息:
|
142
|
-
```ruby
|
143
|
-
# 设置用户属性,如果已有同名属性,则忽略新设置属性
|
144
|
-
ta.user_set_once(user_data);
|
145
|
-
```
|
146
|
-
当您要上传数值型的属性时,可以调用 user_add 来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算:
|
147
|
-
```ruby
|
148
|
-
# 对数值类型的属性进行累加操作
|
149
|
-
ta.user_add(distinct_id: 'ruby_distinct_id', properties: {prop_int: 10, prop_double: 15.88})
|
150
|
-
```
|
151
|
-
|
152
|
-
当您需要删除某个用户属性的值时,可以调用 user_unset.
|
153
|
-
```ruby
|
154
|
-
# 删除某个用户属性
|
155
|
-
ta.user_unset(distinct_id: 'ruby_distinct_id', property: :prop_string)
|
156
|
-
|
157
|
-
# 删除一组用户属性
|
158
|
-
ta.user_unset(distinct_id: 'ruby_distinct_id', property: Array.[](:prop_a, :prop_b, :prob_c))
|
159
|
-
```
|
160
|
-
|
161
|
-
如果您要删除某个用户,可以调用 user_del 将这名用户删除. 之后您将无法再查询该用户的用户属性,但该用户产生的事件仍然可以被查询到:
|
162
|
-
```ruby
|
163
|
-
# 删除用户
|
164
|
-
ta.user_del(
|
165
|
-
# 账号 ID (可选)
|
166
|
-
account_id: 'ruby_test_aid',
|
167
|
-
# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
|
168
|
-
distinct_id: 'ruby_distinct_id',
|
169
|
-
);
|
170
|
-
```
|
171
|
-
|
172
|
-
#### 4. 立即进行数据 IO
|
173
|
-
此操作与具体的 Consumer 实现有关. 在收到数据时, Consumer 可以先将数据存放在缓冲区, 并在特定情况下触发真正的数据 IO 操作, 以提高整体性能. 在某些情况下需要立即提交数据,可以调用 flush 接口:
|
174
|
-
```ruby
|
175
|
-
# 立即提交数据到相应的接收端
|
176
|
-
ta.flush
|
177
|
-
```
|
178
|
-
|
179
|
-
#### 5. 关闭 SDK
|
180
|
-
请在退出程序前调用本接口,以避免缓存内的数据丢失:
|
181
|
-
```ruby
|
182
|
-
# 关闭并退出 SDK
|
183
|
-
ta.close
|
184
|
-
```
|
185
|
-
|
186
|
-
#### 6 其他说明
|
187
|
-
默认情况下,除初始化参数不合法外,其他 Error 会被忽略,如果您希望自己处理接口调用中的 Error,可以传入自定义的 error handler.
|
188
|
-
|
189
|
-
```ruby
|
190
|
-
# (可选) 定义一个错误处理器,当出现 Error 时会调用
|
191
|
-
class MyErrorHandler < TDAnalytics::ErrorHandler
|
192
|
-
def handle(error)
|
193
|
-
puts error
|
194
|
-
raise error
|
195
|
-
end
|
196
|
-
end
|
197
|
-
my_error_handler = MyErrorHandler.new
|
198
|
-
|
199
|
-
# 创建 TA 实例, 第一个参数为任意一种 Consumer, 第二个参数可选,如果设定了会在出错时调用
|
200
|
-
ta = TDAnalytics::Tracker.new(consumer, my_error_handler, uuid: true)
|
201
|
-
```
|
202
|
-
uuid 如果为 true,每条数据都会被带上随机 UUID 作为 #uuid 属性的值上报,该值不会入库,仅仅用于后台做数据重复检测.
|
1
|
+
# ThinkingData SDK for Ruby
|
2
|
+
|
3
|
+
<img src="https://user-images.githubusercontent.com/53337625/205621683-ed9b97ef-6a52-4903-a2c0-a955dddebb7d.png" alt="logo" width="50%"/>
|
4
|
+
|
5
|
+
This is the [ThinkingData](https://www.thinkingdata.cn)™ SDK for Ruby. Documentation is available on our help center in the following languages:
|
6
|
+
|
7
|
+
- [English](https://docs.thinkingdata.cn/ta-manual/latest/en/installation/installation_menu/server_sdk/ruby_sdk_installation/ruby_sdk_installation.html)
|
8
|
+
- [中文](https://docs.thinkingdata.cn/ta-manual/latest/installation/installation_menu/server_sdk/ruby_sdk_installation/ruby_sdk_installation.html)
|
9
|
+
- [日本語](https://docs.thinkingdata.io/ta-manual/v4.0/ja/installation/installation_menu/server_sdk/ruby_sdk_installation/ruby_sdk_installation.html)
|
10
|
+
|
11
|
+
---
|
data/demo/demo.rb
CHANGED
@@ -1,142 +1,104 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
|
3
|
-
require 'thinkingdata-ruby'
|
4
|
-
require 'time'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
}
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# 设置用户属性, 覆盖同名属性
|
106
|
-
ta.user_set(user_data)
|
107
|
-
|
108
|
-
#追加user的一个或者多个列表的属性
|
109
|
-
user_data_arr = {
|
110
|
-
# 账号 ID (可选)
|
111
|
-
account_id: DEMO_ACCOUNT_ID,
|
112
|
-
# 访客 ID (可选),账号 ID 和访客 ID 不可以都为空
|
113
|
-
distinct_id: DEMO_DISTINCT_ID,
|
114
|
-
# 用户属性
|
115
|
-
properties: {
|
116
|
-
array: ["33", "44"],
|
117
|
-
},
|
118
|
-
}
|
119
|
-
|
120
|
-
ta.user_append(user_data_arr)
|
121
|
-
|
122
|
-
# 设置用户属性,不会覆盖已经设置的同名属性
|
123
|
-
user_data[:properties][:prop_int_new] = 800
|
124
|
-
ta.user_set_once(user_data)
|
125
|
-
|
126
|
-
# 累加用户属性
|
127
|
-
ta.user_add(distinct_id: DEMO_DISTINCT_ID, properties: {prop_int: 10, prop_double: 15.88})
|
128
|
-
|
129
|
-
|
130
|
-
# 删除某个用户属性
|
131
|
-
ta.user_unset(distinct_id: DEMO_DISTINCT_ID, property: [:prop_string, :prop_int])
|
132
|
-
|
133
|
-
|
134
|
-
# 删除用户。此操作之前的事件数据不会被删除
|
135
|
-
# ta.user_del(distinct_id: DEMO_DISTINCT_ID)
|
136
|
-
|
137
|
-
#binding.pry
|
138
|
-
|
139
|
-
# 退出前调用此接口
|
140
|
-
ta.close
|
141
|
-
end
|
142
|
-
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'thinkingdata-ruby'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
if __FILE__ == $0
|
7
|
+
|
8
|
+
class MyErrorHandler < ThinkingData::TDErrorHandler
|
9
|
+
def handle(error)
|
10
|
+
puts error
|
11
|
+
raise error
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def logger_consumer
|
16
|
+
ThinkingData::TDLoggerConsumer.new('./log', 'hourly')
|
17
|
+
end
|
18
|
+
|
19
|
+
def debug_consumer
|
20
|
+
ThinkingData::TDDebugConsumer.new("serverUrl", "appId", device_id: "123456789")
|
21
|
+
end
|
22
|
+
|
23
|
+
def batch_consumer
|
24
|
+
consumer = ThinkingData::TDBatchConsumer.new("serverUrl", "appId", 50)
|
25
|
+
consumer._set_compress(false)
|
26
|
+
consumer
|
27
|
+
end
|
28
|
+
|
29
|
+
ThinkingData::set_stringent(false)
|
30
|
+
ThinkingData::set_enable_log(true)
|
31
|
+
my_error_handler = MyErrorHandler.new
|
32
|
+
|
33
|
+
td_sdk = ThinkingData::TDAnalytics.new(logger_consumer, my_error_handler, uuid: false)
|
34
|
+
# td_sdk = ThinkingData::TDAnalytics.new(debug_consumer, my_error_handler, uuid: true)
|
35
|
+
# td_sdk = ThinkingData::TDAnalytics.new(batch_consumer, my_error_handler, uuid: true)
|
36
|
+
|
37
|
+
DEMO_ACCOUNT_ID = '123'
|
38
|
+
DEMO_DISTINCT_ID = 'aaa'
|
39
|
+
|
40
|
+
super_properties = {
|
41
|
+
super_string: 'super_string',
|
42
|
+
super_int: 1,
|
43
|
+
super_bool: false,
|
44
|
+
super_date: Time.rfc2822("Thu, 26 Oct 2019 02:26:12 +0545"),
|
45
|
+
'#app_id': "123123123123123"
|
46
|
+
}
|
47
|
+
|
48
|
+
td_sdk.set_super_properties(super_properties)
|
49
|
+
|
50
|
+
properties = {
|
51
|
+
array: ["str1", "11", Time.now, "2020-02-11 17:02:52.415"],
|
52
|
+
prop_date: Time.now,
|
53
|
+
prop_double: 134.1,
|
54
|
+
prop_string: 'hello world',
|
55
|
+
prop_bool: true,
|
56
|
+
'#ip': '123.123.123.123',
|
57
|
+
}
|
58
|
+
|
59
|
+
td_sdk.set_dynamic_super_properties do
|
60
|
+
{:dynamic_time => Time.now}
|
61
|
+
end
|
62
|
+
|
63
|
+
td_sdk.track(event_name: 'test_event', distinct_id: DEMO_DISTINCT_ID, account_id: DEMO_ACCOUNT_ID, properties: properties)
|
64
|
+
|
65
|
+
td_sdk.clear_dynamic_super_properties
|
66
|
+
td_sdk.clear_super_properties
|
67
|
+
|
68
|
+
td_sdk.track(event_name: 'test_event', distinct_id: DEMO_DISTINCT_ID, account_id: DEMO_ACCOUNT_ID, properties: properties)
|
69
|
+
|
70
|
+
user_data = {
|
71
|
+
array: ["str1", 11, 22.22],
|
72
|
+
prop_date: Time.now,
|
73
|
+
prop_double: 134.12,
|
74
|
+
prop_string: 'hello',
|
75
|
+
prop_int: 666,
|
76
|
+
}
|
77
|
+
td_sdk.user_set(distinct_id: DEMO_DISTINCT_ID, account_id: DEMO_ACCOUNT_ID, properties: user_data)
|
78
|
+
|
79
|
+
user_append_data = {
|
80
|
+
array: %w[33 44]
|
81
|
+
}
|
82
|
+
td_sdk.user_append(distinct_id: DEMO_DISTINCT_ID, account_id: DEMO_ACCOUNT_ID, properties: user_append_data)
|
83
|
+
|
84
|
+
user_uniq_append_data = {
|
85
|
+
array: %w[44 55]
|
86
|
+
}
|
87
|
+
td_sdk.user_uniq_append(distinct_id: DEMO_DISTINCT_ID, account_id: DEMO_ACCOUNT_ID, properties: user_uniq_append_data)
|
88
|
+
|
89
|
+
user_set_once_data = {
|
90
|
+
prop_int_new: 888,
|
91
|
+
}
|
92
|
+
td_sdk.user_set_once(distinct_id: DEMO_DISTINCT_ID, account_id: DEMO_ACCOUNT_ID, properties: user_set_once_data)
|
93
|
+
|
94
|
+
td_sdk.user_add(distinct_id: DEMO_DISTINCT_ID, properties: {prop_int: 10, prop_double: 15.88})
|
95
|
+
|
96
|
+
td_sdk.user_unset(distinct_id: DEMO_DISTINCT_ID, property: [:prop_string, :prop_int])
|
97
|
+
|
98
|
+
td_sdk.user_del(distinct_id: DEMO_DISTINCT_ID)
|
99
|
+
|
100
|
+
td_sdk.flush
|
101
|
+
|
102
|
+
td_sdk.close
|
103
|
+
end
|
104
|
+
|