产品动态
公告
-keep class net.jpountz.lz4.** { *; }。config.debuggable = NO;Android:config.debuggable = false),避免日志泄露。参数名 | 类型 | 说明 | 默认值 |
endpoint | String | - | |
accessKeyId(secretId) | String | - | |
accessKeySecret(secretKey) | String | - | |
topicId | String | - | |
token | String | 临时密钥(可选)。 | - |
sendLogInterval | Int | 日志发送逗留时间,单位:秒。 | 5 |
maxMemorySize | Int | 内存缓存上限,单位:字节。 | 32MB(3210241024) |
batchSize | Int | 批处理日志条数阈值。 | 默认适配平台特性,可自定义。 |
maxDatabaseSize | Long | 数据库最大体积限制,单位:字节。 | 适配设备存储,可自定义。 |
debuggable | BOOL | 调试模式开关,发布时需关闭。 | NO |
pod 'TencentCloudLogProducer/Core', '2.0.0'pod 'TencentCloudLogProducer/NetWorkDiagnosis'#import "TencentCloudLogProducer/ClsLogSender.h"#import "TencentCloudLogProducer/CLSLogStorage.h"// 配置初始化ClsLogSenderConfig *config = [ClsLogSenderConfig configWithEndpoint:@"your_endpoint"accessKeyId:@"your_accessKeyId"accessKey:@"your_accessKey"];// 设置可选参数(示例)config.sendLogInterval = 5; // 日志发送逗留时间,默认5秒config.maxMemorySize = 32 * 1024 * 1024; // 内存上限,默认32MBconfig.token = @"your_temp_token"; // 临时密钥(可选)// 启动SDK_sender = [LogSender sharedSender];[_sender setConfig:config];[_sender start];
import TencentCloudLogProducer// 配置初始化let config = ClsLogSenderConfig(endpoint: "your_endpoint" ?? "",accessKeyId: "your_accessKeyId" ?? "",accessKey: "your_accessKey" ?? "")config.sendLogInterval = 5 // 日志发送逗留时间,默认5秒config.maxMemorySize = 32 * 1024 * 1024 // 内存上限,默认32MBconfig.token = "your_temp_token" // 临时密钥(可选)// 启动SDKlet sender = LogSender.shared()sender.setConfig(config)sender.start()
#import "ClsNetworkDiagnosis.h"#import "ClsAdapter.h"#import "ClsNetDiag.h"// 配置初始化ClsConfig *config = [[ClsConfig alloc] init];config.debuggable = YES; // 调试模式,发布时建议关闭config.endpoint = @"ap-guangzhou.cls.tencentcs.com";config.accessKeyId = @"your_accessKeyId";config.accessKeySecret = @"your_accessKeySecret";config.topicId = @"your_topicId";config.pluginAppId = @"your_pluginAppId";// 添加自定义参数(可选)[config setUserId:@"user1"];[config setChannel:@"channel1"];[config setChannelName:@"官方渠道"];[config setUserNick:@"测试用户"];[config setLongLoginNick:@"常用昵称"];[config setLongLoginUserId:@"long_login_user1"];[config setLoginType:@"wechat"];[config addCustomWithKey:@"customKey" andValue:@"testValue"];// 初始化插件管理器ClsAdapter *clsAdapter = [ClsAdapter sharedInstance];[clsAdapter addPlugin:[[CLSNetworkDiagnosisPlugin alloc] init]];[clsAdapter initWithCLSConfig:config];
import UIKitimport TencentCloudLogProducer// 实现 CLSOutputDelegate 协议的输出类class CLSWriter: NSObject, CLSOutputDelegate {func write(_ line: String!) {print("CLSWriter output: \\(line ?? "")")}}// 初始化配置func initNetworkDiagnosis() {let config = ClsConfig()config.endpoint = "ap-guangzhou.cls.tencentcs.com"config.accessKeyId = "your_access_key_id"config.accessKeySecret = "your_access_key_secret"config.topicId = "your_topic_id"config.pluginAppId = "your_plugin_id"// 可选:自定义参数config.userId = "user1"config.channel = "channel1"config.addCustom(withKey: "customKey1", andValue: "testValue")// 添加网络探测插件let clsAdapter = ClsAdapter.sharedInstance()let plugin = CLSNetworkDiagnosisPlugin()clsAdapter.add(unsafeBitCast(plugin, to: baseClsPlugin.self))clsAdapter.initWith(config)}
#import "TencentCloudLogProducer/ClsLogSender.h"#import "TencentCloudLogProducer/CLSLogStorage.h"#import "TencentCloudLogProducer/ClsLogs.pbobjc.h"// 构建日志内容Log_Content *logContent = [Log_Content message];logContent.key = @"user_behavior";logContent.value = @"click_submit_button";// 构建日志项(时间戳为秒级)Log *logItem = [Log message];[logItem.contentsArray addObject:logContent];logItem.time = [@(System.currentTimeMillis() / 1000) longLongValue];// 写入本地数据库(自动触发批处理发送)[[CLSLogStorage sharedInstance] writeLog:logItemtopicId:@"your_topicId"completion:^(BOOL success, NSError *error) {if (success) {NSLog(@"日志写入成功,等待发送");} else {NSLog(@"日志写入失败:%@", error.localizedDescription);}}];
import TencentCloudLogProducer// 构建日志内容let logContent = Log_Content()logContent.key = "user_behavior"logContent.value = "click_submit_button"// 构建日志项(时间戳为秒级)let logItem = Log()logItem.contentsArray.add(logContent)logItem.time = Int64(Date().timeIntervalSince1970)// 写入本地数据库(自动触发批处理发送)ClsLogStorage.sharedInstance().write(logItem, topicId: "your_topicId") { success, error inif success {print("日志写入成功,等待发送")} else {print("日志写入失败:error.debugDescription)")}}
// 方法1:基础 Ping 探测[[CLSNetworkDiagnosisPlugin sharedInstance] ping:@"cloud.tencent.com"size:64output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"Ping 探测结果:%@", result);}];// 方法2:指定超时时间和探测次数的 Ping 探测[[CLSNetworkDiagnosisPlugin sharedInstance] ping:@"cloud.tencent.com"size:64task_timeout:3000output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"Ping 探测结果:%@", result);} count:10];// 方法3:带自定义字段的 Ping 探测NSMutableDictionary *customFields = [NSMutableDictionary dictionary];customFields[@"detect_scene"] = @"log_upload_failure";[[CLSNetworkDiagnosisPlugin sharedInstance] ping:@"cloud.tencent.com"size:64output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"Ping 探测结果:%@", result);} customFiled:customFields];
//方法一:基础 Ping 探测ClsNetworkDiagnosis.sharedInstance().ping("cloud.tencent.com",size: 64,output: CLSWriter()) { result inprint("Ping 探测结果:\\(result?.description ?? "无结果")")}// 方法 2:指定超时时间和探测次数的 Ping 探测ClsNetworkDiagnosis.sharedInstance().ping("cloud.tencent.com",size: 64,task_timeout: 3000, // 超时时间:3000毫秒output: CLSWriter(),complete: { result inprint("Ping 探测结果:\\(result?.description ?? "无结果")")},count: 10 // 探测次数)//方法 3:带自定义字段的 Ping 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"customFields["app_version"] = "1.0.0"ClsNetworkDiagnosis.sharedInstance().ping("cloud.tencent.com",size: 64,output: CLSWriter(),complete: { result inprint("Ping 探测结果:\\(result?.description ?? "无结果")")},customFiled: customFields)//方法 4:完整参数的 Ping 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"ClsNetworkDiagnosis.sharedInstance().ping("cloud.tencent.com",size: 64,task_timeout: 3000,output: CLSWriter(),complete: { result inguard let result = result else {print("Ping 探测失败")return}print("Ping 探测结果:")print("- 平均延迟:\\(result.avgRtt ?? "") ms")print("- 丢包率:\\(result.loss_rate ?? "") %")print("- 完整结果:\\(result.description)")},count: 10,customFiled: customFields)
// 方法1:基础 TCPPing 探测[[CLSNetworkDiagnosisPlugin sharedInstance] tcpPing:@"cloud.tencent.com"output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"TCPPing 探测结果:%@", result);}];// 方法2:指定端口、超时时间和探测次数的 TCPPing 探测[[CLSNetworkDiagnosisPlugin sharedInstance] tcpPing:@"cloud.tencent.com"port:80task_timeout:3000count:10output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"TCPPing 探测结果:%@", result);}];// 方法3:带自定义字段的 TCPPing 探测NSMutableDictionary *customFields = [NSMutableDictionary dictionary];customFields[@"detect_scene"] = @"log_upload_failure";[[CLSNetworkDiagnosisPlugin sharedInstance] tcpPing:@"cloud.tencent.com"output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"TCPPing 探测结果:%@", result);} customFiled:customFields];
//方法 1:基础 TCPPing 探测ClsNetworkDiagnosis.sharedInstance().tcpPing("cloud.tencent.com",output: CLSWriter()) { result inprint("TCPPing 探测结果:\\(result?.description ?? "无结果")")}//方法 2:指定端口、超时时间和探测次数的 TCPPing 探测ClsNetworkDiagnosis.sharedInstance().tcpPing("cloud.tencent.com",port: 80, // 目标端口task_timeout: 3000, // 超时时间:3000毫秒count: 10, // 探测次数output: CLSWriter()) { result inprint("TCPPing 探测结果:\\(result?.description ?? "无结果")")}//方法 3:带自定义字段的 TCPPing 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"customFields["connection_type"] = "wifi"ClsNetworkDiagnosis.sharedInstance().tcpPing("cloud.tencent.com",output: CLSWriter(),complete: { result inprint("TCPPing 探测结果:\\(result?.description ?? "无结果")")},customFiled: customFields)//方法 4:完整参数的 TCPPing 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"ClsNetworkDiagnosis.sharedInstance().tcpPing("cloud.tencent.com",port: 443, // HTTPS 端口task_timeout: 5000,count: 10,output: CLSWriter(),complete: { result inguard let result = result else {print("TCPPing 探测失败")return}print("TCPPing 探测结果:")print("- 平均延迟:\\(result.avgRtt ?? "") ms")print("- 成功率:\\(result.success_rate ?? "") %")print("- 完整结果:\\(result.description)")},customFiled: customFields)
// 方法1:基础 TraceRoute 探测[[CLSNetworkDiagnosisPlugin sharedInstance] traceRoute:@"cloud.tencent.com"output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"TraceRoute 探测结果:%@", result);}];// 方法2:指定最大跳数的 TraceRoute 探测[[CLSNetworkDiagnosisPlugin sharedInstance] traceRoute:@"cloud.tencent.com"output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"TraceRoute 探测结果:%@", result);} maxTtl:30];// 方法3:带自定义字段的 TraceRoute 探测NSMutableDictionary *customFields = [NSMutableDictionary dictionary];customFields[@"detect_scene"] = @"log_upload_failure";[[CLSNetworkDiagnosisPlugin sharedInstance] traceRoute:@"cloud.tencent.com"output:selfcomplete:^(BOOL success, NSString *result) {NSLog(@"TraceRoute 探测结果:%@", result);} customFiled:customFields];
// 方法 1:基础 TraceRoute 探测ClsNetworkDiagnosis.sharedInstance().traceRoute("cloud.tencent.com",output: CLSWriter()) { result inprint("TraceRoute 探测结果:\\(result?.content ?? "无结果")")}//方法 2:指定最大跳数的 TraceRoute 探测ClsNetworkDiagnosis.sharedInstance().traceRoute("cloud.tencent.com",output: CLSWriter(),complete: { result inguard let result = result else {print("TraceRoute 探测失败")return}print("TraceRoute 探测结果:")print("- 跳数:\\(result.hop_count ?? 0)")print("- 路由详情:\\(result.content ?? "")")},maxTtl: 30 // 最大跳数)//方法 3:带自定义字段的 TraceRoute 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"customFields["network_carrier"] = "China Mobile"ClsNetworkDiagnosis.sharedInstance().traceRoute("cloud.tencent.com",output: CLSWriter(),complete: { result inprint("TraceRoute 探测结果:\\(result?.content ?? "无结果")")},customFiled: customFields)//方法 4:完整参数的 TraceRoute 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"ClsNetworkDiagnosis.sharedInstance().traceRoute("cloud.tencent.com",output: CLSWriter(),complete: { result inguard let result = result else {print("TraceRoute 探测失败")return}print("TraceRoute 探测结果:")print("- 完成状态:\\(result.status)")print("- 跳数:\\(result.hop_count ?? 0)")print("- 详细路由:")print(result.content ?? "无路由信息")},maxTtl: 30,customFiled: customFields)
// 方法1:基础 HttpPing 探测[[CLSNetworkDiagnosisPlugin sharedInstance] httping:@"https://ap-guangzhou.cls.tencentcs.com/ping"output:selfcomplate:^(BOOL success, NSString *result) {NSLog(@"HttpPing 探测结果:%@", result);}];// 方法2:带自定义字段的 HttpPing 探测NSMutableDictionary *customFields = [NSMutableDictionary dictionary];customFields[@"detect_scene"] = @"log_upload_failure";[[CLSNetworkDiagnosisPlugin sharedInstance] httping:@"https://ap-guangzhou.cls.tencentcs.com/ping"output:selfcomplate:^(BOOL success, NSString *result) {NSLog(@"HttpPing 探测结果:%@", result);} customFiled:customFields];
//方法 1:基础 探测ClsNetworkDiagnosis.sharedInstance().httping("https://ap-guangzhou.cls.tencentcs.com/ping",output: CLSWriter()) { result inprint("HttpPing 探测结果:\\(result?.description ?? "无结果")")}//方法 2:带自定义字段的 HttpPing 探测let customFields = NSMutableDictionary()customFields["detect_scene"] = "log_upload_failure"customFields["api_endpoint"] = "ap-guangzhou"ClsNetworkDiagnosis.sharedInstance().httping("https://ap-guangzhou.cls.tencentcs.com/ping",output: CLSWriter(),complate: { result inguard let result = result else {print("HttpPing 探测失败")return}print("HttpPing 探测结果:")print("- HTTP 状态码:\\(result.statusCode ?? 0)")print("- 响应时间:\\(result.responseTime ?? "") ms")print("- 完整结果:\\(result.description)")},customFiled: customFields)iftshi
参数名 | 类型 | 说明 | 默认值 |
endpoint | String | - | |
accessKeyId(secretId) | String | - | |
accessKeySecret(secretKey) | String | - | |
topicId | String | - | |
token | String | 临时密钥(可选)。 | - |
lingerMs | Long | 批处理逗留时间,单位:毫秒。 | 2000 |
TotalSizeInBytes | Long | 内存缓存上限,单位:字节。 | 100MB(100*1024*1024) |
MaxBatchSize | Long | 单批日志最大大小,单位:字节。 | 512KB(512*1024) |
MaxBatchCount | Int | 单批最大日志条数。 | 4096 |
MaxSendThreadCount | Long | 最大并发发送线程数。 | 50 |
MaxBlockSec | Int | 发送阻塞最大时间,单位:秒。 | 60 |
Retries | Int | 发送失败重试次数。 | 10 |
BaseRetryBackoffMs | Long | 首次重试退避时间,单位:毫秒。 | 100 |
MaxRetryBackoffMs | Long | 重试最大退避时间,单位:毫秒。 | 50000 |
MaxReservedAttempts | Int | 保留的尝试发送记录数。 | 11 |
debuggable | Boolean | 调试模式开关,发布时需关闭。 | false |
implementation(group: 'com.tencentcloudapi.cls', name: 'tencentcloud-cls-sdk-android', version: '2.0.3')implementation(group: 'com.tencentcloudapi.cls', name: 'cls-network-diagnosis-reporter-android', version: '2.0.3')<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">ap-guangzhou.cls.tencentcs.com</domain></domain-config></network-security-config>
android:networkSecurityConfig="@xml/network_security_config"
-keep class net.jpountz.lz4.** { *; }
import com.tencentcloudapi.cls.AsyncProducerClient;import com.tencentcloudapi.cls.AsyncProducerConfig;import com.tencentcloudapi.cls.NetworkUtils;public class MyApplication extends Application {private AsyncProducerClient client;@Overridepublic void onCreate() {super.onCreate();String endpoint = "ap-guangzhou.cls.tencentcs.com";String secretId = "your_accessKeyId";String secretKey = "your_accessKeySecret";String topicId = "your_topicId";// 配置初始化AsyncProducerConfig config = new AsyncProducerConfig(endpoint, secretId, secretKey, "", NetworkUtils.getLocalMachineIP());config.setLingerMs(2000); // 批处理逗留时间,默认2秒config.setMaxBatchSize(512 * 1024); // 单批日志最大大小,默认512KBconfig.setTotalSizeInBytes(100 * 1024 * 1024); // 缓存上限,默认100MBconfig.setRetries(10); // 重试次数,默认10次config.setMaxSendThreadCount(50); // 最大并发线程数,默认50config.setMaxBlockSec(60); // 发送阻塞最大时间,默认60秒// 构建客户端实例client = new AsyncProducerClient(config);}public AsyncProducerClient getClient() {return client;}}
import com.tencentcloudapi.cls.adapter.CLSAdapter;import com.tencentcloudapi.cls.config.CLSConfig;import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosisPlugin;public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();// 初始化插件管理器CLSAdapter adapter = CLSAdapter.getInstance();adapter.addPlugin(new CLSNetDiagnosisPlugin());// 配置初始化CLSConfig config = new CLSConfig(this);config.endpoint = "ap-guangzhou.cls.tencentcs.com";config.accessKeyId = "your_accessKeyId";config.accessKeySecret = "your_accessKeySecret";config.pluginAppId = "123456";config.topicId = "your_topicId";config.debuggable = true; // 发布时建议关闭config.setAppName("your_app_name");config.setAppVersion("1.0.0");config.setUserId("user1");config.setChannel("channel1");config.setChannelName("官方渠道");config.setUserNick("测试用户");config.setLongLoginNick("常用昵称");config.setLongLoginUserId("long_login_user1");config.setLoginType("wechat");config.addCustomWithKey("customKey", "testValue");adapter.init(config);}}
import com.tencentcloudapi.cls.LogItem;import com.tencentcloudapi.cls.LogContent;import java.util.ArrayList;import java.util.List;public class LogUploadUtils {public static void sendLog(AsyncProducerClient client, String topicId) {// 构建日志内容列表List<LogContent> logContents = new ArrayList<>();LogContent content1 = new LogContent();content1.setKey("__CONTENT__");content1.setValue("hello world");LogContent content2 = new LogContent();content2.setKey("city");content2.setValue("guangzhou");LogContent content3 = new LogContent();content3.setKey("logNo");content3.setValue("10001");LogContent content4 = new LogContent();content4.setKey("__PKG_LOGID__");content4.setValue(String.valueOf(System.currentTimeMillis()));logContents.add(content1);logContents.add(content2);logContents.add(content3);logContents.add(content4);// 构建日志项(时间戳为秒级)LogItem logItem = new LogItem((int) (System.currentTimeMillis() / 1000));logItem.setContents(logContents);// 批量上传日志List<LogItem> logItems = new ArrayList<>();logItems.add(logItem);client.putLogs(topicId, logItems, result -> {if (result.isSuccess()) {System.out.println("日志上传成功");} else {System.out.println("日志上传失败:" + result.getErrorMsg());}});}}
import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosis;public class NetworkDetectUtils {public static void pingDetect() {// 方法1:基础 Ping 探测CLSNetDiagnosis.getInstance().ping("www.tencentcloud.com", new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("PingResult", String.format("ping result: %s", result));}});// 方法2:指定探测次数和包大小的 Ping 探测CLSNetDiagnosis.getInstance().ping("www.tencentcloud.com", 10, 64, new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("PingResult", String.format("ping result: %s", result));}});}}
import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosis;public class NetworkDetectUtils {public static void tcpPingDetect() {// 方法1:基础 TCPPing 探测CLSNetDiagnosis.getInstance().tcpPing("www.tencentcloud.com", 80, new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("TCPPingResult", String.format("tcpPing result: %s", result));}});// 方法2:指定探测次数和超时时间的 TCPPing 探测CLSNetDiagnosis.getInstance().tcpPing("www.tencentcloud.com", 80, 10, 3000, new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("TCPPingResult", String.format("tcpPing result: %s", result));}});}}
import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosis;public class NetworkDetectUtils {public static void traceRouteDetect() {// 方法1:基础 TraceRoute 探测CLSNetDiagnosis.getInstance().traceroute("www.tencentcloud.com", new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("TraceRouteResult", String.format("traceRoute result: %s", result));}});// 方法2:指定最大跳数和每跳探测次数的 TraceRoute 探测CLSNetDiagnosis.getInstance().traceroute("www.tencentcloud.com", 30, 3, new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("TraceRouteResult", String.format("traceRoute result: %s", result));}});}}
import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosis;public class NetworkDetectUtils {public static void httpPingDetect() {CLSNetDiagnosis.getInstance().httpPing("https://www.tencentcloud.com", new CLSNetDiagnosis.Output() {@Overridepublic void write(String line) {System.out.println(line);}}, new CLSNetDiagnosis.Callback() {@Overridepublic void onComplete(String result) {CLSLog.d("HttpPingResult", String.format("httpPing result: %s", result));}});}}
文档反馈