Android/IOS SDK 上传日志

最近更新时间:2026-01-30 11:32:11

我的收藏

SDK 概述

腾讯云 CLS(Cloud Log Service)移动端 SDK 支持 Android 和 iOS 两大平台,提供日志采集、上传、网络探测等核心能力,具备端侧优化、高可靠性、上传加速、弹性配置等优势,适用于各类移动应用的日志管理场景,可实现日志数据的安全、高效传输与存储。

核心功能

日志上传核心能力

端侧优化:适配移动场景,兼顾性能与资源
原生深度适配:兼容 Android/iOS 原生 API,通过原生线程同步避免冲突,借助 Reachability 库与 ConnectivityManager 实时感知网络状态,精准匹配移动端运行环境。
资源智能管控:SQLite 本地存储搭配 maxDatabaseSize 限制数据库体积,核心逻辑运行于独立后台线程,杜绝 UI 阻塞;支持 batchSize 与 sendLogInterval 配置,批处理发送日志,大幅降低网络开销与电量消耗。
安全存储规范:仅在应用沙盒 Documents 目录操作数据库,严格遵循移动端数据存储标准,从源头防范数据泄露与非法访问。
可靠性保障:全链路防护,日志不丢不重
本地持久化:日志生成后即时序列化存储至本地数据库,App 崩溃或网络中断时数据完整保留,网络恢复后自动续传。
多层校验体系:发送前校验 logIds、topicId、Protobuf 序列化结果等数据完整性,同时校验 URL 与请求体合法性,避免参数错误导致发送失败。
智能重试机制:精细化处理错误码,4xx 错误直接终止重试,5xx 及特定 4xx 错误保留日志并动态调整重试策略;仅收到服务器 200 响应后删除本地日志,实现数据最终一致性。
上传加速策略:双阶压缩,提升传输效率
高效序列化:采用 Google Protocol Buffers 替代 JSON/XML,数据体积更小、解析速度更快,显著减少传输量与 CPU 消耗。
极速压缩:LZ4 算法对 Protobuf 序列化数据二次压缩,几乎不增加 CPU 负载,进一步缩减传输 payload 大小,最大化上传速度。
弹性配置能力:灵活适配复杂业务场景
丰富配置项:Android/iOS 统一封装 endpoint、accessKeyId、accessKey 等核心配置,及 sendLogInterval、maxMemorySize 等性能参数。
动态调整:运行时可灵活修改日志发送间隔、数据库容量等参数,无需重启即可生效,适配弱网、高实时性等多种场景。
生命周期管理:提供 updateToken 方法,支持动态更新认证 Token,满足临时安全凭证轮换需求,环境适应性强。
工程化优势:稳定架构,安全可扩展
架构设计:单例模式确保全局日志管理实例唯一,避免资源竞争;模块化划分核心控制器、数据访问层等组件,结构清晰、易于维护扩展。
安全防护:HMACSHA1 算法对请求方法、路径、参数及 headers 签名,抵御中间人篡改与重放攻击;密钥永不落盘,配合服务器验签,筑牢数据传输安全防线。
线程安全:updateToken、setConfig 等多线程调用方法通过 @synchronized 锁保护,确保多线程环境下数据一致性与稳定性。

网络探测功能

支持 Ping、TCPPing、TraceRoute、HttpPing 四种探测方式,可获取网络连通性、延迟、路由等信息,为日志上传故障排查提供依据。

快速接入

注意事项

密钥安全:accessKeyId 和 accessKeySecret 需妥善保管,避免硬编码在客户端代码中,建议通过服务端动态下发。
混淆配置:Android 平台需添加 LZ4 压缩算法混淆豁免:-keep class net.jpountz.lz4.** { *; }
调试模式:发布应用时,需关闭 SDK 调试模式(iOS:config.debuggable = NO;Android:config.debuggable = false),避免日志泄露。
网络适配:Android 9.0 及以上需配置网络安全策略,允许对应域名的明文传输或使用 HTTPS;iOS 需确保网络权限开启,适配 ATS 策略。
权限控制:Android 需申请网络访问、网络状态查询等必要权限;iOS 需在 Info.plist 中配置网络权限描述(如需)。
缓存管理:合理设置数据库和内存缓存上限,避免占用过多设备存储空间,适配不同设备性能。
版本兼容:集成时需确认 SDK 版本与项目最低支持系统版本匹配,避免兼容性问题。

iOS 平台

环境准备

开发工具:Xcode。
支持版本:iOS 9.0及以上。
依赖管理:CocoaPods。

配置参数

参数名
类型
说明
默认值
endpoint
String
地域信息,填写请参见 可用地域 中 API 上传日志 Tab 中的域名。
-
accessKeyId(secretId)
String
访问密钥 ID,需具备 SDK 上传日志权限
-
accessKeySecret(secretKey)
String
访问密钥 Key,需具备 SDK 上传日志权限
-
topicId
String
日志主题 ID,可在 控制台 获取。
-
token
String
临时密钥(可选)。
-
sendLogInterval
Int
日志发送逗留时间,单位:秒。
5
maxMemorySize
Int
内存缓存上限,单位:字节。
32MB(3210241024)
batchSize
Int
批处理日志条数阈值。
默认适配平台特性,可自定义。
maxDatabaseSize
Long
数据库最大体积限制,单位:字节。
适配设备存储,可自定义。
debuggable
BOOL
调试模式开关,发布时需关闭。
NO

接入步骤

说明:
1. 集成插件。在 Podfile 中添加对应依赖,执行 pod install 完成集成。
核心日志上传:pod 'TencentCloudLogProducer/Core', '2.0.0'
网络探测插件:pod 'TencentCloudLogProducer/NetWorkDiagnosis'
2. 初始化配置。
2.1 核心日志上传初始化。
Objective-C
Swift
#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; // 内存上限,默认32MB
config.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 // 内存上限,默认32MB
config.token = "your_temp_token" // 临时密钥(可选)

// 启动SDK
let sender = LogSender.shared()
sender.setConfig(config)
sender.start()
2.2 网络探测插件初始化。
Objective-C
Swift
#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 UIKit
import 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)
}

3. 日志写入,示例如下。
Objective-C
Swift
#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:logItem
topicId:@"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 in
if success {
print("日志写入成功,等待发送")
} else {
print("日志写入失败:error.debugDescription)")
}
}
4. 网络探测,使用示例如下。
Ping 探测。
Objective-C
Swift
// 方法1:基础 Ping 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] ping:@"cloud.tencent.com"
size:64
output:self
complete:^(BOOL success, NSString *result) {
NSLog(@"Ping 探测结果:%@", result);
}];

// 方法2:指定超时时间和探测次数的 Ping 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] ping:@"cloud.tencent.com"
size:64
task_timeout:3000
output:self
complete:^(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:64
output:self
complete:^(BOOL success, NSString *result) {
NSLog(@"Ping 探测结果:%@", result);
} customFiled:customFields];
//方法一:基础 Ping 探测
ClsNetworkDiagnosis.sharedInstance().ping(
"cloud.tencent.com",
size: 64,
output: CLSWriter()
) { result in
print("Ping 探测结果:\\(result?.description ?? "无结果")")
}

// 方法 2:指定超时时间和探测次数的 Ping 探测
ClsNetworkDiagnosis.sharedInstance().ping(
"cloud.tencent.com",
size: 64,
task_timeout: 3000, // 超时时间:3000毫秒
output: CLSWriter(),
complete: { result in
print("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 in
print("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 in
guard let result = result else {
print("Ping 探测失败")
return
}
print("Ping 探测结果:")
print("- 平均延迟:\\(result.avgRtt ?? "") ms")
print("- 丢包率:\\(result.loss_rate ?? "") %")
print("- 完整结果:\\(result.description)")
},
count: 10,
customFiled: customFields
)

TCPPing 探测。
Objective-C
Swift
// 方法1:基础 TCPPing 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] tcpPing:@"cloud.tencent.com"
output:self
complete:^(BOOL success, NSString *result) {
NSLog(@"TCPPing 探测结果:%@", result);
}];

// 方法2:指定端口、超时时间和探测次数的 TCPPing 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] tcpPing:@"cloud.tencent.com"
port:80
task_timeout:3000
count:10
output:self
complete:^(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:self
complete:^(BOOL success, NSString *result) {
NSLog(@"TCPPing 探测结果:%@", result);
} customFiled:customFields];
//方法 1:基础 TCPPing 探测
ClsNetworkDiagnosis.sharedInstance().tcpPing(
"cloud.tencent.com",
output: CLSWriter()
) { result in
print("TCPPing 探测结果:\\(result?.description ?? "无结果")")
}

//方法 2:指定端口、超时时间和探测次数的 TCPPing 探测
ClsNetworkDiagnosis.sharedInstance().tcpPing(
"cloud.tencent.com",
port: 80, // 目标端口
task_timeout: 3000, // 超时时间:3000毫秒
count: 10, // 探测次数
output: CLSWriter()
) { result in
print("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 in
print("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 in
guard let result = result else {
print("TCPPing 探测失败")
return
}
print("TCPPing 探测结果:")
print("- 平均延迟:\\(result.avgRtt ?? "") ms")
print("- 成功率:\\(result.success_rate ?? "") %")
print("- 完整结果:\\(result.description)")
},
customFiled: customFields
)

TraceRoute 探测。
Objective-C
Swift
// 方法1:基础 TraceRoute 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] traceRoute:@"cloud.tencent.com"
output:self
complete:^(BOOL success, NSString *result) {
NSLog(@"TraceRoute 探测结果:%@", result);
}];

// 方法2:指定最大跳数的 TraceRoute 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] traceRoute:@"cloud.tencent.com"
output:self
complete:^(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:self
complete:^(BOOL success, NSString *result) {
NSLog(@"TraceRoute 探测结果:%@", result);
} customFiled:customFields];
// 方法 1:基础 TraceRoute 探测
ClsNetworkDiagnosis.sharedInstance().traceRoute(
"cloud.tencent.com",
output: CLSWriter()
) { result in
print("TraceRoute 探测结果:\\(result?.content ?? "无结果")")
}

//方法 2:指定最大跳数的 TraceRoute 探测
ClsNetworkDiagnosis.sharedInstance().traceRoute(
"cloud.tencent.com",
output: CLSWriter(),
complete: { result in
guard 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 in
print("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 in
guard 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
)


HttpPing 探测。
Objective-C
Swift
// 方法1:基础 HttpPing 探测
[[CLSNetworkDiagnosisPlugin sharedInstance] httping:@"https://ap-guangzhou.cls.tencentcs.com/ping"
output:self
complate:^(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:self
complate:^(BOOL success, NSString *result) {
NSLog(@"HttpPing 探测结果:%@", result);
} customFiled:customFields];
//方法 1:基础 探测
ClsNetworkDiagnosis.sharedInstance().httping(
"https://ap-guangzhou.cls.tencentcs.com/ping",
output: CLSWriter()
) { result in
print("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 in
guard let result = result else {
print("HttpPing 探测失败")
return
}
print("HttpPing 探测结果:")
print("- HTTP 状态码:\\(result.statusCode ?? 0)")
print("- 响应时间:\\(result.responseTime ?? "") ms")
print("- 完整结果:\\(result.description)")
},
customFiled: customFields
)
iftshi

Android 平台

环境准备

开发工具:Android Studio。
支持版本:Android 4.4及以上。
构建工具:Gradle。

配置参数

参数名
类型
说明
默认值
endpoint
String
地域信息,填写请参见 可用地域 中 API 上传日志 Tab 中的域名。
-
accessKeyId(secretId)
String
访问密钥 ID,需具备 SDK 上传日志权限
-
accessKeySecret(secretKey)
String
访问密钥 Key,需具备 SDK 上传日志权限
-
topicId
String
日志主题 ID,可在 控制台 获取。
-
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

接入步骤

说明:
1. 集成插件。在模块的 build.gradle 文件中添加依赖。
核心日志上传: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')
2. 权限配置。在 AndroidManifest.xml 中添加必要权限。
<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" />
3. 网络安全配置(Android 9.0 及以上版本需配置)。
3.1 在 res/xml 目录下创建 network_security_config.xml。
<?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>
3.2 在 AndroidManifest.xml 的 application 标签中添加。
android:networkSecurityConfig="@xml/network_security_config"
4. 混淆配置。在 proguard-rules.pro 中添加 LZ4压缩算法混淆豁免。
-keep class net.jpountz.lz4.** { *; }
5. 初始化配置。
5.1 核心日志上传初始化。
import com.tencentcloudapi.cls.AsyncProducerClient;
import com.tencentcloudapi.cls.AsyncProducerConfig;
import com.tencentcloudapi.cls.NetworkUtils;

public class MyApplication extends Application {
private AsyncProducerClient client;

@Override
public 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); // 单批日志最大大小,默认512KB
config.setTotalSizeInBytes(100 * 1024 * 1024); // 缓存上限,默认100MB
config.setRetries(10); // 重试次数,默认10次
config.setMaxSendThreadCount(50); // 最大并发线程数,默认50
config.setMaxBlockSec(60); // 发送阻塞最大时间,默认60秒

// 构建客户端实例
client = new AsyncProducerClient(config);
}

public AsyncProducerClient getClient() {
return client;
}
}
5.2 网络探测插件初始化。
import com.tencentcloudapi.cls.adapter.CLSAdapter;
import com.tencentcloudapi.cls.config.CLSConfig;
import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosisPlugin;

public class MyApplication extends Application {
@Override
public 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);
}
}
6. 日志写入,示例如下。
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());
}
});
}
}
7. 网络探测,使用示例如下。
Ping 探测
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() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public 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() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public void onComplete(String result) {
CLSLog.d("PingResult", String.format("ping result: %s", result));
}
});
}
}
TCPPing 探测。
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() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public 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() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public void onComplete(String result) {
CLSLog.d("TCPPingResult", String.format("tcpPing result: %s", result));
}
});
}
}
TraceRoute 探测。
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() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public 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() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public void onComplete(String result) {
CLSLog.d("TraceRouteResult", String.format("traceRoute result: %s", result));
}
});
}
}
HttpPing 探测。
import com.tencentcloudapi.cls.plugin.netdiagnosis.CLSNetDiagnosis;

public class NetworkDetectUtils {
public static void httpPingDetect() {
CLSNetDiagnosis.getInstance().httpPing("https://www.tencentcloud.com", new CLSNetDiagnosis.Output() {
@Override
public void write(String line) {
System.out.println(line);
}
}, new CLSNetDiagnosis.Callback() {
@Override
public void onComplete(String result) {
CLSLog.d("HttpPingResult", String.format("httpPing result: %s", result));
}
});
}
}