集成SDK插件到App后,您只需启动App,网络质量分析器就会自动进行网络探测。本文介绍SDK插件的使用说明。
集成操作步骤
上线前测试阶段,请检查以下几项:
在控制台配置的网络探测规则是否成功触发,以控制台中看到对应的探测数据为准。
检查客户端主动发起的探测是否成功上报,以控制台中看到对应的探测数据为准,建议和控制台配置的探测规则的探测目标不同,以便区分。
针对上述步骤1、2分别检查不同平台,如Android、iOS和Windows等。
有条件的话,海外和中国内地不同终端都验证下是否能成功上报数据。
iOS SDK接入
在Podfile文件中添加以下配置。
source 'https://gitee.com/aliyun-sls/Specs.git' pod 'AliyunLogProducer', '4.3.2' # 建议使用最新版本 pod 'AliyunLogNetworkDiagnosis', '4.3.2' # 建议使用最新版本
更多版本信息,请参见aliyun-log-ios-sdk。
在AppDelegate类中引入如下头文件。
#import <AliyunLogNetworkDiagnosis/AliyunLogNetworkDiagnosis.h>
在AppDelegate类的
application: didFinishLaunchingWithOptions:
方法中添加如下SDK初始化代码。重要上报日志到日志服务时需使用阿里云账号或RAM用户的AccessKey,用于鉴权及防篡改。为避免将AccessKey保存在移动端应用中,造成安全风险,推荐您使用移动端日志直传服务配置AccessKey。具体操作,请参见采集-搭建移动端日志直传服务。
SLSCredentials *credentials = [SLSCredentials credentials]; // endpoint和project不支持动态更新,请在初始化SDK时指定 credentials.endpoint = @"<your endpoint>"; credentials.project = @"<your project>"; // AccessKey建议通过STS方式获取,参考下面的文档: // https://help.aliyun.com/zh/sls/user-guide/build-a-service-to-upload-logs-from-mobile-apps-to-log-service // AccessKey在初始化时可以先不填,后续通过[[SLSCocoa sharedInstance] setCredentials:credentials];方法可以更新,参考后面的updateSDK方法实现 credentials.accessKeyId = @"<your accessKeyId>""; credentials.accessKeySecret = @"<your accessKeySecret>"; credentials.securityToken = @"<your accessKey securityToken>"; // 仅当AccessKey是通过STS服务获取时需要 SLSNetworkDiagnosisCredentials *networkCredentials = [credentials createNetworkDiagnosisCredentials]; //secretKey不支持动态更新,请在初始化时指定 networkCredentials.secretKey = self.secretKey; // (可选)设置业务扩展字段。仅对新产生的探测数据生效。 // 不支持动态更新,请在SDK初始化时设置。 [networkCredentials putExtension:@"custom_value" forKey:@"custom_key"]; // 用户接受隐私协议之前,先调用preInit完成SDK初始化。 [[SLSCocoa sharedInstance] preInit:credentials configuration:^(SLSConfiguration * _Nonnull configuration) { configuration.enableNetworkDiagnosis = YES; }]; // 用户接受隐私协议之后,再调用initialize完成SDK的完整初始化。 [[SLSCocoa sharedInstance] initialize:credentials configuration:^(SLSConfiguration * _Nonnull configuration) { configuration.enableNetworkDiagnosis = YES; }]; // (可选)设置设备ID,可在任何时机调用,仅对新产生的探测数据生效。 [SLSUtdid setUtdid:@"<your device id"]; // (可选)配置用户信息,可在任何时机调用。仅对新产生的探测数据生效。 SLSUserInfo *userInfo = [SLSUserInfo userInfo]; userInfo.uid = @"<your user id>"; userInfo.channel = @"<your user channel"; [userInfo addExt:@"ext_value" key:@"ext_key"]; [[SLSCocoa sharedInstance] setUserInfo:userInfo];
更多SDK使用示例请参考:Demo示例。
重要参数说明如下表所示。
字段
是否必填
说明
secretKey
是
接入端应用的密钥。更多信息,请参见创建接入端应用。
putExtension
否
设置自定义信息,支持设置多个键值对。设置后,探测数据中将附加这些信息。
endpoint
是
日志服务Project所属的Endpoint,必须以https://开头。如何获取,请参见公网。
project
是
您在创建接入端应用时指定的Project。更多信息,请参见创建接入端应用。
Android SDK接入
在根build.gradle文件中添加以下配置。
repositories { google() jcenter() mavenCentral() maven { url 'https://maven.aliyun.com/repository/public/' } }
添加如下依赖。
implementation 'io.github.aliyun-sls:aliyun-log-android-sdk:2.7.1@aar' // 建议使用最新版本 implementation 'io.github.aliyun-sls:sls-android-core:1.0.10@aar' // 建议使用最新版本 implementation 'io.github.aliyun-sls:sls-android-ot:1.0.8.1@aar' // 建议使用最新版本 implementation 'io.github.aliyun-sls:sls-android-network-diagnosis:2.2.2@aar' // 建议使用最新版本 implementation 'com.squareup.okhttp3:okhttp:3.11.0' // (可选)最低兼容3.10.0版本,HTTP探测时必须
更多版本信息,请参见aliyun-log-android-sdk。
添加如下初始化代码。
Credentials credentials = new Credentials(); // (必填)endpoint和project不支持动态更新,请在初始化SDK时指定 credentials.endpoint = "<your endpoint>"; credentials.project = "<your project>"; // AccessKey建议通过STS方式获取,参考下面的文档: // https://help.aliyun.com/zh/sls/user-guide/build-a-service-to-upload-logs-from-mobile-apps-to-log-service // AccessKey在初始化时可以先不填,后续通过SLSAndroid.setCredentials(credentials);方法可以更新,参考后面的updateSDK方法实现 credentials.accessKeyId = "<your accessKeyId>"; credentials.accessKeySecret = "<your accessKeySecret>"; //credentials.securityToken = "<your accessKey securityToekn>"; // 仅当AccessKey是通过STS服务获取时需要 NetworkDiagnosisCredentials networkDiagnosisCredentials = credentials.getNetworkDiagnosisCredentials(); // (必填)secretKey不支持动态更新,请在初始化时设置。 networkDiagnosisCredentials.secretKey = secretKey; // (可选)设置业务扩展字段。仅对新产生的探测数据生效。 // 不支持动态更新,请在SDK初始化时设置。 networkDiagnosisCredentials.extension.put("custom_key", "custom_value"); SLSAndroid.initialize( getApplicationContext(), credentials, configuration -> configuration.enableNetworkDiagnosis = true ); // (建议)注册探测数据上报回调 SLSAndroid.registerCredentialsCallback((feature, result) -> { if (LogProducerResult.LOG_PRODUCER_SEND_UNAUTHORIZED == result || LogProducerResult.LOG_PRODUCER_PARAMETERS_INVALID == result) { // 处理AccessKey过期、失效等鉴权问题 Credentials credentials = new Credentials(); credentials.accessKeyId = "<your accessKeyId>"; credentials.accessKeySecret = "<your accessKeySecret>"; credentials.securityToken = "<your accessKey securityToekn>"; SLSAndroid.setCredentials(credentials); } }); // (可选)设置设备ID,可在任何时机调用,仅对新产生的探测数据生效。 SLSAndroid.setUtdid(getApplicationContext(), "<your device id"); // (可选)配置用户信息,可在任何时机调用。仅对新产生的探测数据生效。 UserInfo userInfo = new UserInfo(); userInfo.uid = "<your user id>"; userInfo.channel = "<your user channel>"; userInfo.addExt("ext_key", "ext_value"); SLSAndroid.setUserInfo(userInfo);
更多SDK使用示例请参考:Demo示例。
字段
是否必填
说明
secretKey
是
接入端应用的密钥。更多信息,请参见创建接入端应用。
extension.put
否
设置自定义信息,支持设置多个键值对。设置后,探测数据中将附加这些信息。
endpoint
是
日志服务Project所属的Endpoint,必须以https://开头。如何获取,请参见公网。
project
是
您在创建接入端应用时指定的Project。更多信息,请参见创建接入端应用。
accessKeyId
是
具备访问日志服务Logstore权限的AccessKey ID。如何获取,请参见访问密钥。
accessKeySecret
是
具备访问日志服务Logstore权限的AccessKey Secret。如何获取,请参见访问密钥。
securityToken
否
访问密钥的Token。使用STS方式接入时,需要配置。如何获取,请参见AssumeRole - 获取扮演角色的临时身份凭证。
Unity插件接入
下载并导入Unity插件到您的Unity工程。
下载最新版本的Unity插件,双击
.unitypackage
文件,导入插件相关的文件到您的Unity工程中。插件包目录说明:
Assets/Plugins/Unity4SLS: Plugin脚本。
Assets/Plugins/Unity4SLS/Android/libs:Android平台依赖的SDK和NDK。
Assets/Plugins/Unity4SLS/iOS/:iOS平台依赖的Framework和静态库。
Assets/Plugins/Unity4SLS/Windows/:Windows平台依赖的库。
Assets/Scenes/:示例Scenes,实际集成时可以删除。
Assets/Scripts/:示例Scripts,实际集成时可以删除。
初始化插件。
重要上报日志到日志服务时需使用阿里云账号或RAM用户的AccessKey,用于鉴权及防篡改。为避免将AccessKey保存在移动端应用中,造成安全风险,推荐您使用移动端日志直传服务配置AccessKey。具体操作,请参见采集-搭建移动端日志直传服务。
using AliyunSLS; Credentials credentials = new Credentials(); // (必填)endpoint和project不支持动态更新,请在初始化SDK时指定 credentials.endpoint = "<your endpoint>"; credentials.project = "<your project>"; credentials.secretKey = "<your secretKey>"; // (可选)AccessKey建议通过STS方式获取,参考下面的文档: // https://help.aliyun.com/zh/sls/user-guide/build-a-service-to-upload-logs-from-mobile-apps-to-log-service // AccessKey在初始化时可以先不填,后续通过SLSAndroid.setCredentials(credentials);方法可以更新,参考后面的updateSDK方法实现 credentials.accessKeyId = accessKeyId; credentials.accessKeySecret = accessKeySecret; //credentials.securityToken = "<your accessKey securityToekn>"; // 仅当AccessKey是通过STS服务获取时需要 // (可选)设置业务扩展字段。仅对新产生的探测数据生效。 credentials.extension = new Dictionary<string, string>(); extensions.Add("key_from_unity", "value_from_unity"); // (可选)设置设备ID credentials.deviceId = "<your device id>"; // 初始化SDK。 Unity4SLS.Initialize(credentials); //(可选)配置用户信息,可在任何时机调用,仅对新产生的探测数据生效。 UserInfo info = new UserInfo(); info.uid = "12312123123123"; info.channel = "dev_debug"; info.ext.Add("u_key1", "u_value1"); Unity4SLS.SetUserInfo(info);
字段
是否必填
说明
secretKey
是
接入端应用的密钥。更多信息,请参见创建接入端应用。
extensions.Add
否
设置自定义信息,支持设置多个键值对。设置后,探测数据中将附加这些信息。
endpoint
是
日志服务Project所属的Endpoint,必须以https://开头。如何获取,请参见公网。
project
是
您在创建接入端应用时指定的Project。更多信息,请参见创建接入端应用。
Windows SDK接入
集成方式
SDK以MD动态库的形式提供,您可按照集成动态库的形式进⾏Windows SDK接入。
将
/lib
目录下的库文件和/include
目录下的头文件添加到项目中。配置附加库目录路径。
将alinetworkdiagnosis.dll库同步到⽣成⽬录。
使⽤时,使用
#include "api.h"
指令。
MD模式下,发布应用前请检查项目中是否缺少VCRuntime系列dll和Visual C++ Redistributable for Visual Studio相关动态库文件,网络质量分析器 Windows SDK所需的动态库文件参考以下目录:
msvcp140.dll
msvcp140_codecvt_ids.dll
ucrtbase.dll
vcruntime140.dll
vcruntime140_1.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-core-localization-l1-2-0.dll
api-ms-win-core-processthreads-l1-1-1.dll
api-ms-win-core-file-l1-2-0.dll
api-ms-win-core-timezone-l1-1-0.dll
api-ms-win-core-file-l2-1-0.dll
api-ms-win-core-synch-l1-2-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-core-string-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-locale-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
下载地址
单击Windows SDK,下载Windows SDK包。
WindowsSDK支持x64/x86模式下多种集成方式,请根据项目需求选择对应的文件夹:
DLL-MD:动态库,运行时库MD;
DLL-MT:动态库,运行时库MT;
LIB-MD:静态库,运行时库MD;
LIB-MT:静态库,运行时库MT;
SDK初始化
上报日志到日志服务时需使用阿里云账号或RAM用户的AccessKey,用于鉴权及防篡改。为避免将AccessKey保存在代码中,造成安全风险,推荐您使用移动端日志直传服务配置AccessKey。具体操作,请参见采集-搭建移动端日志直传服务。
void logcallback(const char* s) {
printf("[demo-logcallback] %s", (char*)s);
}
void on_token_ex() {
printf("[demo-token-expired-callback] ----------------------token expired callback excited----------------\n");
}
void on_token_ex_ctx(void* ctx) {
printf("[demo-token-expired-callback] ----------------------context : %s ----------------------\n",(char*)ctx);
printf("[demo-token-expired-callback] ----------------------token expired callback excited----------------\n");
}
void demoInit(){
//开始初始化。
printf("start init sdk\n");
AliNetworkDiagConfig& config = AliNetworkDiagConfig::getNetworkDiagConfig();
//必填,接入端应用的密钥。
config.setSecKey("{your_secret_key}");
//可选,设置设备ID。
config.setDeviceId("{your_device_id}");
//可选,设置用户自定义拓展信息,用于业务自定义标识。
std::map<std::string, std::string> mp;
mp.insert(make_pair("key", "value"));
config.setExtension(mp);
//设置最大并发线程数。
config.setThreadPool(20);
//设置日志回调。
config.setLogback(logcallback);//默认输出log_debug及以上等级的日志
config.setLogCallback(logcallback, Log_Level::log_error);//设置日志输出最低等级
//设置token失效回调,支持携带自定义参数
config.setTokenExpiredCallback(on_token_ex);
//或
const char* s = "it's user's context";
config.setTokenExpiredCallback(on_token_ex_ctx, (void*)s);
//初始化SDK。
config.init();
//或者预初始化SDK。
config.preInit();
//初始化完成。
printf("end init sdk\n");
}
// 请求AccessKey信息。
void requestAccessKey() {
// 推荐您先使用移动端日志直传服务配置AccessKey信息。
// ...
// 获取AccessKey信息后,完成更新。
updateAccessKey(accessKeyId, accessKeySecret, securityToken);
}
// 更新AccessKey信息。
void updateAccessKey(std::string accessKeyId, std::string accessKeySecret, std::string securityToken) {
// 通过STS服务获取的AccessKey包含securitToken,需要使用以下方式更新。
config.setSlsCredential(accessKeyId, accessKeySecret, securityToken);
}
重要参数说明如下表所示。
字段 | 是否必填 | 说明 |
SecKey | 是 | 接入端应用的密钥。更多信息,请参见创建接入端应用。 |
扩展功能
AccessKey自定义策略最佳实践
提供给SDK用于上报日志的凭证:AccessKey或者STS Token,需要分配SLS LogStore的访问策略。按照最小权限原则,我们需要指定凭证的访问策略范围为对应logstore的只写权限。请参考如下代码:
代码块中your-project
和your-logstore
分别替换为应用详情中的project和原始探测数据Logstore,关于应用详情,请参见查看应用详情。
{
"Effect":"Allow",
"Action":[
"log:PostLogStoreLogs"
],
"Resource":[
"acs:log:*:*:project/your-project/logstore/your-logstore"
]
}
处理AccessKey失效
在初始化SDK配置AccessKey时,如果AccessKey是通过STS方式获取到的,则AccessKey可能会面临失效的问题。在AccessKey失效时,SDK支持通过配置回调的方式来接收AccessKey失效信息。
iOS SDK
[[SLSCocoa sharedInstance] registerCredentialsCallback:^(NSString * _Nonnull feature, NSString * result) {
if ([@"LogProducerSendUnauthorized" isEqualToString:result] ||
[@"LogProducerParametersInvalid" isEqualToString:result]) {
//处理token过期,AccessKey失效等鉴权类型问题。
//获取到新的token后,调用如下代码更新token。
SLSCredentials *credentials = [SLSCredentials credentials];
credentials.accessKeyId = accessKeyId;
credentials.accessKeySecret = accessKeySecret;
credentials.securityToken = securityToken; //可选,STS方式获取的token必须要填。
//更新凭证信息。
[[SLSCocoa sharedInstance] setCredentials:credentials];
}
}];
Android SDK
SLSAndroid.registerCredentialsCallback((feature, result) -> {
if (LogProducerResult.LOG_PRODUCER_SEND_UNAUTHORIZED == result ||
LogProducerResult.LOG_PRODUCER_PARAMETERS_INVALID == result) {
// 处理token过期,AccessKey失效等鉴权类问题。
Credentials credentials = new Credentials();
credentials.accessKeyId = accessKeyId;
credentials.accessKeySecret = accessKeySecret;
credentials.securityToken = securityToken;
SLSAndroid.setCredentials(credentials1);
}
});
Unity
/// <summary>
/// 设置回调。
/// </summary>
public void setCredentialsCallback()
{
callback_delegate callback = new callback_delegate(credentialsCallback);
Unity4SLS.RegisterCredentialsCallback(callback);
}
// 处理AccessKey过期或无效。
public void credentialsCallback(string feature, string result)
{
if ("LogProducerSendUnauthorized" == result ||
"LogProducerParametersInvalid" == result ||
"LOG_PRODUCER_SEND_UNAUTHORIZED" == result ||
"LOG_PRODUCER_PARAMETERS_INVALID" == result)
{
Credentials credentials = new Credentials();
credentials.accessKeyId = accessKeyId;
credentials.accessKeySecret = accessKeySecret;
Unity4SLS.SetCredentials(credentials);
}
}
Windows SDK
void on_token_ex() {
//获取配置类。
AliNetworkDiagConfig& config = AliNetworkDiagConfig::getNetworkDiagConfig();
//设置AccessKeyId、AccessKeySecret、Token。
config.setSlsCredential(accessKeyId, accessKeySecret, securityToken);
printf("[token-expired-callback] token expired callback excited\n");
}
主动探测
SDK 支持 PING、TCPPING、HTTP、MTR、DNS等多种探测方式的主动发起。您可以调用以下API发起主动探测。
PING
iOS SDK
SLSPingRequest *request = [[SLSPingRequest alloc] init];
request.domain = @"www.example.com";
//可选参数。
request.context = @"<your ping context id>";
request.parallel = YES;
//可选参数。
request.extention = @{
@"custom_key": @"custom_value_ios"
};
[[SLSNetworkDiagnosis sharedInstance] ping2:request callback:^(SLSResponse * _Nonnull response) {
NSLog(@"ping result: %@", response.content);
}];
Android SDK
PingRequest request = new PingRequest();
request.domain = "www.example.com";
//可选参数。
request.multiplePortsDetect = true; //启用多网卡探测。
request.context = "<your ping context id>";
//可选参数,设置当次网络探测的扩展业务参数。
request.extension = new HashMap<String, String>() {
{
put("custom_key", "custom_value");
}
};
NetworkDiagnosis.getInstance().ping(request, response -> {
SLSLog.d(TAG, String.format("ping result: %s", response.content));
});
Unity
PingRequest request = new PingRequest();
request.domain = "www.example.com";
//可选参数。
request.context = "your ping request context id";
Unity4SLS.Ping(request);
Windows SDK
//必选,初始化探测参数(任务ID(可为空字符串)、探测目标、DNS解析(0~3分别代表v4优先、v6优先、v4 only、v6 only)、探测端口)。
PingConfig* pingConfig = new PingConfig("0", "www.example.com", 0, 80);
//可选,修改探测目标。
pingConfig->setTarget("www.example.com");
//可选,修改探测任务ID。
pingConfig->setTraceId("fdadf-daa-dadadad-okokok23");
//可选,修改探测时间间隔,单位:ms。
pingConfig->setInterval(100);
//可选,修改探测超时时间。
pingConfig->setTimeout(2000);
//可选,设置探测结束时的回调
pingConfig->setCallback(demo_ping_callback);
//发起探测。
pingConfig->Detect();
//另:demo_ping_callback 范例:
void demo_ping_callback(void* context, char* json_result) {
std::string* ctx = static_cast<std::string*>(context);
printf("[探测结果回调 demo-ping-callback] %s, context : %s\n", json_result, ctx->c_str());
}
TCPPING
iOS SDK
SLSTcpPingRequest *request = [[SLSTcpPingRequest alloc] init];
request.domain = @"www.example.com";
request.port = 80;
//可选参数。
request.context = @"<your tcpping context id>";
//可选参数。
request.extention = @{
@"custom_key": @"custom_value_ios"
};
[[SLSNetworkDiagnosis sharedInstance] tcpPing2:request callback:^(SLSResponse * _Nonnull response) {
NSLog(@"ping result: %@", response.content);
}];
Android SDK
TcpPingRequest request = new TcpPingRequest();
request.domain = "www.example.com";
request.port = 80;
//可选参数。
request.context = "<your tcp ping context id>";
//可选参数,设置当次网络探测的扩展业务参数。
request.extension = new HashMap<String, String>() {
{
put("custom_key", "custom_value");
}
};
NetworkDiagnosis.getInstance().tcpPing(request, response -> {
SLSLog.d(TAG, String.format("tcp ping result: %s", response.content));
});
Unity
TcpPingRequest request = new TcpPingRequest();
request.domain = "www.example.com";
request.port = 80;
//可选参数。
request.context = "your tcpping request context id";
Unity4SLS.TcpPing(request);
Windows SDK
//必选,初始化探测参数(任务ID(可为空字符串)、探测目标、DNS解析(0~3分别代表v4优先、v6优先、v4 only、v6 only)、探测端口)
TcppingConfig* tcppingConfig = new TcppingConfig("", "www.example.com", 1, 80);
//可选,修改探测目标。
tcppingConfig->setTarget("www.example.com");
//可选,修改探测任务ID。
tcppingConfig->setTraceId("fdadf-daa-dadadad-okokok23");
//可选,修改探测时间间隔,单位:ms。
tcppingConfig->setInterval(100);
//可选,修改探测超时时间。
tcppingConfig->setTimeout(2000);
//可选,设置探测结束时的回调
tcppingConfig->setCallback(demo_tcpping_callback);
//发起探测。
tcppingConfig->Detect();
//另:demo_tcpping_callback 范例:
void demo_tcpping_callback(void* context, char* json_result) {
std::string* ctx = static_cast<std::string*>(context);
printf("[探测结果回调 demo-tcpping-callback] %s, context : %s\n", json_result, ctx->c_str());
}
HTTP
iOS SDK
SLSHttpRequest *request = [[SLSHttpRequest alloc] init];
request.domain = @"https://demo.ne.aliyuncs.com";
//可选参数。
request.context = @"<your http context id>";
request.headerOnly = YES;
request.downloadBytesLimit = 128 * 1024; // 128KB
//可选参数,证书检验回调。getHttpCredential的配置参考下文。
request.credential = ^NSURLCredential * _Nullable(NSString * _Nonnull url) {
return [self getHttpCredential:url];
};
//可选参数。
request.extention = @{
@"custom_key": @"custom_value_ios"
};
[[SLSNetworkDiagnosis sharedInstance] http2:request callback:^(SLSResponse * _Nonnull response) {
NSLog(@"ping result: %@", response.content);
}];
Android SDK
HttpRequest request = new HttpRequest();
//可选参数。
request.context = "<your http context id>";
request.headerOnly = true;
request.downloadBytesLimit = 1024;
//可选参数,证书检验回调。getSSLContext的配置参考下文。
request.credential = new HttpCredential(getSSLContext(context), null);
//可选参数,设置当次网络探测的扩展业务参数。
request.extension = new HashMap<String, String>() {
{
put("custom_key", "custom_value");
}
};
request.domain = "https://www.example.com";
NetworkDiagnosis.getInstance().http(request, response -> {
SLSLog.d(TAG, String.format("http result: %s", response.content));
});
Unity
HttpRequest request = new HttpRequest();
request.domain = "https://www.example.com";
//可选参数。
request.context = "<your http context id>";
request.headerOnly = true;
request.downloadBytesLimit = 1024;
Unity4SLS.Http(request);
Windows SDK
//必选,初始化探测参数(任务ID,探测目标,DNS解析(0~3分别代表v4优先、v6优先、v4 only、v6 only))
HttpDetectionConfig* httpConfig = new HttpDetectionConfig("", "http://www.example.com", 1);
//可选,修改探测目标。
httpConfig->setTarget("http://www.example.com");
//可选,修改探测任务ID。
httpConfig->setTraceId("fdadf-daa-dadadad-okokok23");
//可选,修改探测时间间隔,单位:ms。
httpConfig->setInterval(100);
//可选,修改探测超时时间。
httpConfig->setTimeout(2000);
//可选,设置探测结束时的回调
httpConfig->setCallback(demo_http_callback);
//发起探测。
httpConfig->Detect();
//demo_http_callback 范例:
void demo_http_callback(void* context, char* json_result) {
std::string* ctx = static_cast<std::string*>(context);
printf("[探测结果回调 demo-http-callback] %s, context : %s\n", json_result, ctx->c_str());
}
MTR
iOS SDK
SLSMtrRequest *request = [[SLSMtrRequest alloc] init];
request.domain = @"www.example.com";
//可选参数。
request.context = @"<your mtr context id>";
request.parallel = YES;
request.protocol = SLS_MTR_PROROCOL_ALL;
//可选参数。
request.extention = @{
@"custom_key": @"custom_value_ios"
};
[[SLSNetworkDiagnosis sharedInstance] mtr2:request callback:^(SLSResponse * _Nonnull response) {
NSLog(@"ping result: %@", response.content);
}];
Android SDK
MtrRequest request = new MtrRequest();
request.domain = "www.example.com";
//可选参数。
request.protocol = Protocol.ICMP;
request.context = "<your mtr context id>";
//可选参数,设置当次网络探测的扩展业务参数。
request.extension = new HashMap<String, String>() {
{
put("custom_key", "custom_value");
}
};
NetworkDiagnosis.getInstance().mtr(request, response -> {
SLSLog.d(TAG, String.format("mtr result: %s", response.content));
});
Unity
MtrRequest request = new MtrRequest();
request.domain = "www.example.com";
//可选参数。
request.context = "your mtr request context id";
Unity4SLS.Mtr(request);
Windows SDK
//必选,初始化探测参数。
MtrDetectionConfig* mtrConfig = new MtrDetectionConfig("", "www.example.com", "ICMP", 1);
//可选,修改探测目标。
mtrConfig->setTarget("www.example.com");
//可选,修改探测任务ID。
mtrConfig->setTraceId("fdadf-daa-dadadad-okokok23");
//可选,修改探测时间间隔,单位:ms。
mtrConfig->setInterval(100);
//可选,修改探测超时时间。
mtrConfig->setTimeout(2000);
//可选,设置探测结束时的回调
mtrConfig->setCallback(demo_mtr_callback);
//发起探测。
mtrConfig->Detect();
//demo_mtr_callback 范例:
void demo_mtr_callback(void* context, char* json_result) {
std::string* ctx = static_cast<std::string*>(context);
printf("[探测结果回调 demo-mtr-callback] %s, context : %s\n", json_result, ctx->c_str());
}
DNS
iOS SDK
SLSDnsRequest *request = [[SLSDnsRequest alloc] init];
request.domain = @"www.example.com";
//可选参数。
request.context = @"<your dns context id>";
//可选参数。
request.extention = @{
@"custom_key": @"custom_value_ios"
};
[[SLSNetworkDiagnosis sharedInstance] dns2:request callback:^(SLSResponse * _Nonnull response) {
NSLog(@"ping result: %@", response.content);
}];
Android SDK
DnsRequest request = new DnsRequest();
request.domain = "www.example.com";
//可选参数。
request.context = "<your dns context id>";
//可选参数,设置当次网络探测的扩展业务参数。
request.extension = new HashMap<String, String>() {
{
put("custom_key", "custom_value");
}
};
NetworkDiagnosis.getInstance().dns(request, response -> {
SLSLog.d(TAG, String.format("dns result: %s", response.content));
});
Unity
DnsRequest request = new DnsRequest();
request.domain = "www.example.com";
// 可选参数。
request.context = "your dns request context id";
Unity4SLS.Dns(request);
Windows SDK
//必选,初始化探测参数。
DnsDetectionConfig* dnsConfig = new DnsDetectionConfig("", "www.example.com", 2000, 0, "223.5.5.5", "A");
//可选,修改探测目标。
dnsConfig->setTarget("www.example.com");
//可选,修改探测任务ID。
dnsConfig->setTraceId("fdadf-daa-dadadad-okokok23");
//可选,修改探测时间间隔,单位:ms。
dnsConfig->setInterval(100);
//可选,修改探测超时时间。
dnsConfig->setTimeout(2000);
//可选,修改DNS服务器。
dnsConfig->setServers("30.30.XX.XX");
//可选,修改DNS解析选项。
dnsConfig->setType(1);
//可选,设置探测结束时的回调
dnsConfig->setCallback(demo_dns_callback);
//发起探测。
dnsConfig->Detect();
//demo_mtr_callback 范例:
void demo_dns_callback(void* context, char* json_result) {
std::string* ctx = static_cast<std::string*>(context);
printf("[探测结果回调 demo-dns-callback] %s, context : %s\n", json_result, ctx->c_str());
}
UDP
Windows SDK
//必选,初始化探测参数,"7564"为UDP报文负载,为十六进制字符串(Hex String)格式,
UdpConfig* udpConfig = new UdpConfig("0", "www.example.com", 0, 4000, "7564");
//可选,修改探测目的
udpConfig->setTarget("www.example.com");
//可选,修改探测任务id
udpConfig->setTraceId("fdadf-daa-dadadad-okokok23");
//可选,修改探测时间间隔(ms)
udpConfig->setInterval(100);
//可选,修改探测超时时间
udpConfig->setTimeout(2000);
//可选,设置探测结束时的回调
udpConfig->setCallback(demo_udp_callback);
//发起探测。
udpConfig->Detect();
//demo_udp_callback 范例:
void demo_udp_callback(void* context, char* json_result) {
std::string* ctx = static_cast<std::string*>(context);
printf("[探测结果回调 demo-udp-callback] %s, context : %s\n", json_result, ctx->c_str());
}
更新扩展业务字段
SDK支持在任何时机更新扩展业务字段。更新后的扩展业务字段仅对新产生的探测数据生效。
例如,应用初始化的时候可能未获取到用户ID,可以在用户登录成功后通过此接口更新,传入的key需设置为userId
。
iOS SDK
[[SLSNetworkDiagnosis sharedInstance] updateExtensions:@{
@"key1": @"value1",
@"key2": @"value2"
}];
Android SDK
NetworkDiagnosis.getInstance().updateExtensions(new HashMap<String, String>(){
{
put("key1", "value1");
put("key2", "value2");
}
});
Unity
Dictionary<string, string> extensions = new Dictionary<string, string>();
extensions.Add("key_from_unity", "value_from_unity");
Unity4SLS.UpdateExtensions(extensions);
Windows SDK
//获取配置类。
AliNetworkDiagConfig& config = AliNetworkDiagConfig::getNetworkDiagConfig();
//自定义Extension信息。
std::map<std::string, std::string> mp;
mp.insert(make_pair("key1", "value1"));
mp.insert(make_pair("key2", "value2"));
mp.insert(make_pair("key3", "value3"));
//更新扩展信息。
config.updateExtension(mp);
配置策略下发域名
一般情况下无需调用此接口,仅当不希望直连阿里云IP地址时,通过这个接口可以套一层域名。
如果要使用该功能,需在SDK初始化之前完成设置。
iOS SDK
[[SLSNetworkDiagnosis sharedInstance] setPolicyDomain:@"your custom domain"];
Android SDK
NetworkDiagnosis.getInstance().setPolicyDomain("your custom domain");
Unity
Unity4SLS.SetPolicyDomain("your custom domain");
Windows SDK
config.setPolicyDomain("yourpolicydomain");
配置证书校验全局回调
当时HTTP探测,且为控制台下发的策略出发的探测时,支持通过全局回调函数来获取凭证。
iOS SDK
//注册HTTP探测证书校验回调。
[[SLSNetworkDiagnosis sharedInstance] registerHttpCredentialDelegate:^NSURLCredential * _Nullable(NSString * _Nonnull url) {
return [self getHttpCredential:url];
}];
//处理证书校验。
-(NSURLCredential*) getHttpCredential:(NSString*)url {
if (![url containsString:@"demo.ne.aliyuncs.com"]) {
return nil;
}
NSString *p12WithBase64 = @"your p12 infomation";
NSData *p12Data = [[NSData alloc] initWithBase64EncodedString:p12WithBase64 options:0];
CFDataRef inPKCS12Data = (__bridge CFDataRef)p12Data;
SecIdentityRef identity = NULL;
NSString *pass = @"123";
OSStatus status = [self extractIdentity:inPKCS12Data identity:&identity pass:pass];
if(status != 0 || identity == NULL) {
return nil;
}
SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate (identity, &certificate);
const void *certs[] = {certificate};
CFArrayRef arrayOfCerts = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);
//NSURLCredentialPersistenceForSession:创建URL证书,在会话期间有效。
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)arrayOfCerts persistence:NSURLCredentialPersistenceForSession];
if(certificate) {
CFRelease(certificate);
}
if (arrayOfCerts) {
CFRelease(arrayOfCerts);
}
if (credential) {
return [credential copy];
}
return nil;
}
Android SDK
//注册HTTP探测证书校验回调。
final HttpCredential credential = new HttpCredential(getSSLContext(context), null);
NetworkDiagnosis.getInstance().registerHttpCredentialCallback((url, context) -> credential);
//处理证书校验。
@RequiresApi(api = VERSION_CODES.O)
private SSLContext getSSLContext(Context context) {
try {
//服务器端需要验证的客户端证书。
String KEY_STORE_TYPE_P12 = "PKCS12";
KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
String p12Str = "your p12 infomation";
byte[] p12Data = Base64.getDecoder().decode(p12Str);
InputStream ksIn = new ByteArrayInputStream(p12Data);
try {
keyStore.load(ksIn, "your password".toCharArray());
} catch (Exception e) {
Log.e("Exception", e.getMessage(), e);
} finally {
try {
ksIn.close();
} catch (Exception ignore) {
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore)null);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
keyManagerFactory.init(keyStore, "your password".toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
return sslContext;
} catch (Exception e) {
Log.e("tag", e.getMessage(), e);
}
return null;
}
隐私合规
通过SDK发起网络探测请求后,SDK会采集网络信息、App信息、设备信息等。这些信息中主要包含:
用户设备出口IP、设备私网IP
App版本号信息
系统类型及版本号信息
设备型号
为了保障您的App顺利通过监管机构的合规检测,SDK提供了合规使用方案。
第一步:确保您的App有《隐私政策》,并且在用户首次启动App时弹出《隐私政策》取得用户同意。
第二步:务必告知用户您选择使用日志服务(SLS)SDK,请在《隐私政策》增加如下参考条款:
使用SDK名称:日志服务(SLS)SDK。
服务类型:网络质量数据分析。
手机个人信息类型:设备出口IP、私网 IP,App版本号信息,系统类型及版本号信息,设备型号信息等。
隐私权政策链接:日志服务(SLS)SDK隐私权政策
第三步:务必做SDK延迟初始化配置,确保用户同意《隐私政策》之后,再初始化SDK。
为保证您正在集成SDK之后,能够满足工信部相关合规要求,您应确保在App安装后首次冷启动时按照如下方式进行SDK的初始化。
在合适的位置调用预初始化函数(可参考上文SDK接入章节)。预初始化函数不会采集设备信息。
iOS SDK
// 预初始化,功能可正常使用,但敏感信息不会采集 [[SLSCocoa sharedInstance] preInit:credentials configuration:configuration];
Android SDK
// 预初始化,功能可正常使用,但敏感信息不会采集 SLSAndroid.preInit(this, credentials, optionConfiguration);
Windows SDK
void demoPreInit(){ //开始初始化。 printf("start preInit sdk\n"); AliNetworkDiagConfig& config = AliNetworkDiagConfig::getNetworkDiagConfig(); //设置其他参数... //预初始化SDK,功能可正常使用,但敏感信息不会采集 config.preInit(); //初始化完成。 printf("end preInit sdk\n"); }
确保App首次冷启动时,在用户阅读您的《隐私政策》 并取得用户授权之后,才调用正式初始化函数。正式初始化函数调用后,SDK会采集设备IP、设备型号等相关信息。如果用户不同意《隐私政策》授权,则不能调用正式初始化函数。
iOS SDK
[[SLSCocoa sharedInstance] initialize:credentials configuration:configuration];
Android SDK
SLSAndroid.initialize(context, credentials, optionConfiguration)
- 本页导读 (1)