# C SDK 使用指南
最新版本为:1.3.6
更新时间为:2022-06-22
# 一、集成并初始化 SDK
# 1.1 集成 SDK
下载C SDK (opens new window),进行解压后可将以下文件引入项目中。
(1)LoggerConsumer: 批量实时写本地文件,默认以天为分隔,需要与 LogBus 搭配使用进行数据上传。
./c-sdk_version/include/thinkingdata.h
./c-sdk_version/lib/libthinkingdata.a
(2)BatchConsumer: 批量实时向服务器传输数据,不需要搭配传输工具,有数据丢失的风险,请谨慎使用。
./c-sdk_version/include/thinkingdata.h
./c-sdk_version/lib/libthinkingdata_http.a
(3)AsyncBatchConsumer:批量异步实时向服务器传输数据,不需要搭配传输工具,有数据丢失的风险,请谨慎使用。
./c-sdk_version/include/thinkingdata.h
./c-sdk_version/lib/libthinkingdata_async_batch.a
(4)DebugConsumer: 逐条实时地向 TA 服务器传输数据,不需要搭配传输工具,如果数据出现错误,整条数据都将不会入库,并且返回详细的错误说明,不建议在生产环境中使用。
./c-sdk_version/include/thinkingdata.h
./c-sdk_version/lib/libthinkingdata_debug.a
注意,这里的静态库使用mac平台(clang编译器)进行打包,由于各平台特性不一致,建议将源代码下载后自行编译,推荐使用cmake打包,请参考 GitHub (opens new window) 。
# 1.2 初始化 SDK
您可以通过四种方法获得 SDK 实例:
(1)LoggerConsumer:
//生成config
TAConfig *config = ta_init_config();
//配置日志路径 YOUR_LOG_PATH 需要更改为日志存储的目录
TA_ASSERT(TA_OK == ta_add_string("file_path", "YOUR_LOG_PATH", strlen("YOUR_LOG_PATH"), config));
//配置日志前缀
TA_ASSERT(TA_OK == ta_add_string("file_prefix", "test", strlen("test"), config));
//按时间切分 默认按小时切分
//TA_ASSERT(TA_OK == ta_add_int("rotate_mode", DAILY, config)); //按天切分
TA_ASSERT(TA_OK == ta_add_int("rotate_mode", HOURLY, config)); //按小时切分
//按文件大小切分,单位是MB
//TA_ASSERT(TA_OK == ta_add_int("file_size", 1024, config));
//生成SDK实例
struct TAConsumer *consumer = NULL;
if (TA_OK != ta_init_logging_consumer(&consumer, config)) {
fprintf(stderr, "Failed to initialize the consumer.");
return 1;
}
ta_free_properties(config);
ThinkingdataAnalytics *ta = NULL;
if (TA_OK != ta_init(consumer, &ta)) {
fprintf(stderr, "Failed to initialize the SDK.");
return 1;
}
TALoggingConsumer
将会批量实时地生成日志文件,文件默认以小时切分,需要搭配 LogBus 进行上传。
YOUR_LOG_PATH
需要更改为日志存储的目录,您只需将 LogBus 的监听文件夹地址设置为此处的地址,即可使用 LogBus 进行数据的监听上传。
(2)BatchConsumer:
//生成config
TAConfig *config = ta_init_config();
// 配置appid和url
TA_ASSERT(TA_OK == ta_add_string("push_url", serverURL, strlen(serverURL), config));
TA_ASSERT(TA_OK == ta_add_string("appid", appid, strlen(appid), config));
//生成SDK实例
struct TAConsumer *consumer = NULL;
if (TA_OK != ta_init_consumer(&consumer, config)) {
fprintf(stderr, "Failed to initialize the consumer.");
return 1;
}
ta_free_properties(config);
ThinkingdataAnalytics *ta = NULL;
if (TA_OK != ta_init(consumer, &ta)) {
fprintf(stderr, "Failed to initialize the SDK.");
return 1;
}
serverURL
为传输数据的 URL,appid
为您的项目的 APP ID。
(3)AsyncBatchConsumer:
参考BatchConsumer
(4)DebugConsumer :
//生成config
TAConfig *config = ta_init_config();
// debug_mode,0入库,否则不入库
TA_ASSERT(TA_OK == ta_add_int("debug_mode", 0, config));
// 配置appid和url
TA_ASSERT(TA_OK == ta_add_string("push_url", serverURL, strlen(serverURL), config));
TA_ASSERT(TA_OK == ta_add_string("appid", appid, strlen(appid), config));
//生成SDK实例
struct TAConsumer *consumer = NULL;
if (TA_OK != ta_init_consumer(&consumer, config)) {
fprintf(stderr, "Failed to initialize the consumer.");
return 1;
}
ta_free_properties(config);
ThinkingdataAnalytics *ta = NULL;
if (TA_OK != ta_init(consumer, &ta)) {
fprintf(stderr, "Failed to initialize the SDK.");
return 1;
}
debug_mode为0时入库,否则不入库。
# 二、上报数据
在 SDK 初始化完成之后,您就可以调用track
来上传事件,一般情况下,您可能需要上传十几到上百个不同的事件,如果您是第一次使用 TA 后台,我们推荐您先上传几个关键事件。
如果您对需要发送什么样的事件有疑惑,可以查看快速使用指南了解更多信息。
# 2.1 发送事件
您可以调用track
来上传事件,建议您根据先前梳理的文档来设置事件的属性以及发送信息的条件,此处以用户付费作为范例:
const char* distinct_id = "ABC123";
const char* account_id = "TA_10001";
//上报不带自定义属性的事件数据,注意account_id 和 distinct_id 必须至少设置其中一个
TA_ASSERT(TA_OK == ta_track(NULL, distinct_id, "test", NULL, ta));
// 生成自定义属性
TAProperties *properties = ta_init_properties();
// 设置事件发生的时间,如果不设置的话,则默认使用为当前时间,**注意** #time的类型必须是time_t
TA_ASSERT(TA_OK == ta_add_date("#time", time(NULL), 0, properties));
// 设置用户的ip地址,TA系统会根据IP地址解析用户的地理位置信息,如果不设置的话,则默认不上报
TA_ASSERT(TA_OK == ta_add_string("#ip", "192.168.1.1", strlen("192.168.1.1"), properties));
// 添加自定义属性
TA_ASSERT(TA_OK == ta_add_string("product_name", "商品", strlen("商品"), properties));
TA_ASSERT(TA_OK == ta_add_number("price", 30.989, properties));
TA_ASSERT(TA_OK == ta_add_int("coin", -30, properties));
TA_ASSERT(TA_OK == ta_add_string("order_id", "abc_123", strlen("abc_123"), properties));
TA_ASSERT(TA_OK == ta_add_date("login_time", time(NULL), 0, properties));
TA_ASSERT(TA_OK == ta_add_bool("is_firstBuy", true, properties));
TA_ASSERT(TA_OK == ta_add_bool("is_test", false, properties));
// 从 v1.1.0版本 开始,您可以调用 `ta_append_array` 对 array 类型的属性进行追加操作。
TA_ASSERT(TA_OK == ta_append_array("product_buy", "product_name1", strlen("product_name1"), properties));
TA_ASSERT(TA_OK == ta_append_array("product_buy", "product_name2", strlen("product_name2"), properties));
//上报带有自定义属性的事件数据,同样account_id 和 distinct_id 必须至少设置其中一个
TA_ASSERT(TA_OK == ta_track(account_id, distinct_id, "test", properties, ta));
ta_free_properties(properties);
- 事件的名称是
string
类型,只能以字母开头,可包含数字,字母和下划线 “_”,长度最大为 50 个字符,对字母大小写不敏感。 - 事件的属性类型是
TAProperties
,可以通过ta_add_string
添加字符串型属性,ta_add_number
添加数值型属性,ta_add_int
添加int
属性,ta_add_bool
添加bool
值,ta_add_date
添加date
类型值,ta_append_array
添加数组类型。 - Key 的值为属性的名称,为 string 类型,规定只能以字母开头,包含数字,字母和下划线 “_”,长度最大为 50 个字符,对字母大小写不敏感。
- Value 为该属性的值,可以是
int
、number
、string
、bool
、date
、数组类型、对象、对象组。
从 v1.3.4 版本开始支持复杂数据类型,属性可传入对象和对象组:
TAProperties *properties = ta_init_properties();
TAProperties *json = ta_init_custom_properties("json");
TAProperties *json1 = ta_init_custom_properties("json1");
TAProperties *json2 = ta_init_custom_properties("json2");
/**
* 复杂数据类型 JSON对象
* */
TA_ASSERT(TA_OK == ta_add_string("a1", "b1", strlen("b1"), json));
TA_ASSERT(TA_OK == ta_add_string("product_name", "月卡", strlen("月卡"), json));
TA_ASSERT(TA_OK == ta_add_number("price", 30.989, json));
TA_ASSERT(TA_OK == ta_add_int("coin", -30, json));
TA_ASSERT(TA_OK == ta_add_string("order_id", "abc_123", strlen("abc_123"), json));
TA_ASSERT(TA_OK == ta_add_date("login_time", time(NULL), 0, json));
TA_ASSERT(TA_OK == ta_add_bool("is_firstBuy", TA_TRUE, json));
TA_ASSERT(TA_OK == ta_add_bool("is_test", TA_FALSE, json));
TA_ASSERT(TA_OK == ta_add_property(json, properties));
/**
* 复杂数据类型 JSON—Array
* */
TA_ASSERT(TA_OK == ta_add_string("a11", "b11", strlen("b11"), json1));
TA_ASSERT(TA_OK == ta_add_string("product_name", "月卡11", strlen("月卡11"), json1));
TA_ASSERT(TA_OK == ta_add_number("price", 3111, json1));
TA_ASSERT(TA_OK == ta_add_int("coin", -31, json1));
TA_ASSERT(TA_OK == ta_add_string("order_id", "abc_111", strlen("abc_111"), json1));
TA_ASSERT(TA_OK == ta_add_date("login_time", time(NULL), 0, json1));
TA_ASSERT(TA_OK == ta_add_bool("is_firstBuy", TA_TRUE, json1));
TA_ASSERT(TA_OK == ta_add_bool("is_test", TA_TRUE, json1));
TA_ASSERT(TA_OK == ta_add_string("a12", "b12", strlen("b12"), json2));
TA_ASSERT(TA_OK == ta_add_string("product_name", "月卡22", strlen("月卡22"), json2));
TA_ASSERT(TA_OK == ta_add_number("price", 3222, json2));
TA_ASSERT(TA_OK == ta_add_int("coin", -32, json2));
TA_ASSERT(TA_OK == ta_add_string("order_id", "abc_222", strlen("abc_222"), json2));
TA_ASSERT(TA_OK == ta_add_date("login_time", time(NULL), 0, json2));
TA_ASSERT(TA_OK == ta_add_bool("is_firstBuy", TA_FALSE, json2));
TA_ASSERT(TA_OK == ta_add_bool("is_test", TA_FALSE, json2));
TA_ASSERT(TA_OK == ta_append_properties("jsons", json1, properties));
TA_ASSERT(TA_OK == ta_append_properties("jsons", json2, properties));
# 三、用户属性
TA 平台目前支持的用户属性设置接口为ta_user_set
、ta_user_setOnce
、ta_user_add
、ta_user_del
、ta_user_append
。
# 3.1 ta_user_set
对于一般的用户属性,您可以调用ta_user_set
来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与传入属性的类型一致:
// 上传用户属性,"user_name"的值为"ABC"
TAProperties *user_properties = ta_init_properties();
TA_ASSERT(TA_OK == ta_add_string("user_name", "ABC", strlen("ABC"), user_properties));
TA_ASSERT(TA_OK == ta_user_set(account_id, distinct_id, user_properties,ta));
ta_free_properties(user_properties);
//上传用户属性,该用户的"user_name"被设置成"XYZ"
TAProperties *user_properties2 = ta_init_properties();
TA_ASSERT(TA_OK == ta_add_string("user_name", "XYZ", strlen("XYZ"), user_properties2));
TA_ASSERT(TA_OK == ta_user_set(account_id, distinct_id, user_properties2,ta));
ta_free_properties(user_properties2);
属性格式要求与事件属性保持一致。
# 3.2 ta_user_setOnce
如果您要上传的用户属性只要设置一次,则可以调用ta_user_setOnce
来进行设置,当该属性之前已经有值的时候,将会忽略这条信息:
// 上传用户属性,"user_name"的值为"ABC"
TAProperties *user_properties = ta_init_properties();
TA_ASSERT(TA_OK == ta_add_string("user_name", "ABC", strlen("ABC"), user_properties));
TA_ASSERT(TA_OK == ta_user_setOnce(account_id, distinct_id, user_properties,ta));
ta_free_properties(user_properties);
//上传用户属性,该用户的"user_name"已设置因此忽略该属性设置
//该用户的"user_age"没有被设置,因此设置值为18
TAProperties *user_properties2 = ta_init_properties();
TA_ASSERT(TA_OK == ta_add_string("user_name", "XYZ", strlen("XYZ"), user_properties2));
TA_ASSERT(TA_OK == ta_add_int("Age", 18, user_properties2));
TA_ASSERT(TA_OK == ta_user_setOnce(account_id, distinct_id, user_properties2,ta));
ta_free_properties(user_properties2);
属性格式要求与事件属性保持一致。
# 3.3 ta_user_add
当您要上传数值型的属性时,您可以调用ta_user_add
来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作。
//设置用户属性
TAProperties *user_properties = ta_init_properties();
TA_ASSERT(TA_OK == ta_add_int("Level", 3, user_properties));
//上传用户属性,给该用户的"Level"属性加上3
TA_ASSERT(TA_OK == ta_user_add(account_id, distinct_id, user_properties, ta));
ta_free_properties(user_properties);
设置的属性key为字符串,Value 只允许为数值。
# 3.4 ta_user_del
如果您要删除某个用户,可以调用ta_user_del
将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到
TA_ASSERT(TA_OK == ta_user_del(account_id, distinct_id, ta));
# 3.5 ta_user_append
从 v1.1.0 版本开始,您可以调用 ta_user_append
对 array 类型的用户属性进行追加操作。
TAProperties *array_properties = ta_init_properties();
TA_ASSERT(TA_OK == ta_append_array("product_buy", "product_name3", strlen("product_name3"), array_properties));
TA_ASSERT(TA_OK == ta_append_array("product_buy", "product_name4", strlen("product_name4"), array_properties));
TA_ASSERT(TA_OK == ta_user_append(account_id, distinct_id, array_properties, ta));
ta_free_properties(array_properties);
# 3.6 ta_user_unset
当您需要清空某个用户的用户属性的值时,可以调用 ta_user_unset
进行清空。
TA_ASSERT(TA_OK == ta_user_unset(account_id, distinct_id, "test", ta));
ta_user_unset: 的传入值为被清空属性的 Key 值。
# 3.7 ta_user_uniq_append
当您要为 list 类型追加用户属性值,但不希望出现重复值时,您可以调用 ta_user_uniq_append
来对指定属性进行追加操作,如果该属性还未在集群中被创建,则 ta_user_uniq_append
创建该属性
TAProperties *array_properties = ta_init_properties();
TA_ASSERT(TA_OK == ta_append_array("product_buy", "product_name3", strlen("product_name3"), array_properties));
TA_ASSERT(TA_OK == ta_append_array("product_buy", "product_name4", strlen("product_name4"), array_properties));
TA_ASSERT(TA_OK == ta_user_uniq_append(account_id, distinct_id, array_properties, ta));
# 四、其他操作
# 4.1 立即提交数据
ta_flush(ta);
立即提交数据到相应的接收器
# 4.2 关闭 sdk
ta_free(ta);
ta_consumer_free(consumer);
关闭并退出 sdk,请在关闭服务器前调用本接口,以避免缓存内的数据丢失
# 五、相关预置属性
# 5.1 所有事件带有的预置属性
以下预置属性,是 C SDK 中所有事件都会带有的预置属性
属性名 | 中文名 | 说明 |
---|---|---|
#ip | IP 地址 | 用户的 IP 地址,需要进行手动设置,TA 将以此获取用户的地理位置信息 |
#country | 国家 | 用户所在国家,根据 IP 地址生成 |
#country_code | 国家代码 | 用户所在国家的国家代码(ISO 3166-1 alpha-2,即两位大写英文字母),根据 IP 地址生成 |
#province | 省份 | 用户所在省份,根据 IP 地址生成 |
#city | 城市 | 用户所在城市,根据 IP 地址生成 |
#lib | SDK 类型 | 您接入 SDK 的类型,如 tga_c_sdk 等 |
#lib_version | SDK 版本 | 您接入 C SDK 的版本 |
# ChangeLog
# v1.3.6 2022/06/22
- 提升稳定性
# v1.3.5 2022/05/16
- 支持debug_consumer
- 支持async_batch_consumer
- 新增ta_user_uniq_append方法
# v1.3.4 2022/03/03
- 支持复杂数据类型
# v1.3.3 2022/02/18
- 修复 snprintf 可能导致的重名问题
# v1.3.2 2021/11/23
- 优化 windows 平台里的 snprintf 方法
# v1.3.1 2021/11/10
- malloc失败时不再直接exit
# v1.3.0 2021/10/13
- 增加支持batch consumer
# v1.2.3 2021-09-23
- 修复#first_check_id无法正常处理的问题
# v1.2.2 2021/07/01
- 适配windows环境
# v1.2.1 2021/06/09
- 不再使用stdbool库
# v1.2.0 2020/12/07
- 支持指定 log 前缀
- 增加自动创建目录
# v1.1.0 2020/02/12
- 支持 array 数据
- 新增 user_append 接口
- 支持动态公共属性设置
- 支持设置“#uuid”,配合后台使用
# v1.0.0 2019/09/29
- debug consumer
- logger consumer
- support track/user_set/user_setOnce/user_add/user_del
- support super properties