Flutter 应用接入¶
前置条件¶
- 安装 DataKit(DataKit 安装文档)
应用接入¶
当前 Flutter 版本暂只支持 Android 和 iOS 平台。登录 “观测云” 控制台,进入「应用监测」页面,点击右上角「新建应用」,在新窗口输入「应用名称」,点击「创建」,然后相应接入的平台,即可开始配置。
安装¶
Pub.Dev: ft_mobile_agent_flutter
源码地址:https://github.com/GuanceCloud/datakit-flutter
Demo 地址:https://github.com/GuanceCloud/datakit-flutter/example
在项目路径下,终端运行 Flutter 命令:
这将在包的 pubspec.yaml 中添加这样的一行(并运行一个隐式 flutter pub get ):
现在在您的 Dart 代码中,您可以使用:
Android 需要在 app/android 目录下 build.gradle 安装 ft-plugin 配合使用,并在创建自定义 Application,并且 AndroidMainifest.xml 中声明使用,代码如下,详细配置请见 Android SDK 配置,或参考 demo
import io.flutter.app.FlutterApplication
/**
* 如果需要统计【启动次数】和【启动时间】需要在此处添加自定义 Application
*/
class CustomApplication : FlutterApplication() {
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloudcare.ft.mobile.sdk.agent_example">
<application android:name=".CustomApplication">
//...
</application>
</manifest>
SDK 初始化¶
基础配置¶
void main() async {
WidgetsFlutterBinding.ensureInitialized();
//初始化 SDK
await FTMobileFlutter.sdkConfig(
serverUrl: serverUrl,
debug: true,
);
}
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
serverUrl | String | 是 | 数据上报地址 |
useOAID | bool | 否 | 是否使用 OAID 唯一识别,默认false ,开启后替换 deviceUUID 进行使用,仅仅作用于 Android 设备 |
debug | bool | 否 | 设置是否允许打印日志,默认false |
datakitUUID | String | 否 | 请求HTTP 请求头X-Datakit-UUID 数据采集端 如果用户不设置会自动配置 |
envType | enum EnvType | 否 | 环境,默认prod |
RUM 配置¶
await FTRUMManager().setConfig(
androidAppId: appAndroidId,
iOSAppId: appIOSId,
enableNativeUserAction:false,
enableNativeUserView: false
);
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
androidAppId | String | 是 | appId,监测中申请 |
iOSAppId | String | 是 | appId,监测中申请 |
sampleRate | double | 否 | 采样率,(采集率的值范围为>= 0、<= 1,默认值为 1) |
enableNativeUserAction | bool | 否 | 是否进行 Native Action 追踪,Button 点击事件,纯 Flutter 应用建议关闭,默认为 false |
enableNativeUserView | bool | 否 | 是否进行 Native View 自动追踪,纯 Flutter 应用建议关闭,,默认为 false |
enableNativeUserResource | bool | 否 | 是否进行 Native Resource 自动追踪,纯 Flutter 应用建议关闭,默认为 false |
monitorType | enum MonitorType | 否 | 监控补充类型 |
globalContext | Map | 否 | 自定义全局参数 |
添加自定义标签¶
静态使用¶
- 拆分原有的 main.dart 为 2 个部分,一部分为 main(),一部分为 App() MaterialApp 组件;
- 建立对应各个环境的入口文件,如:main_prod.dart、main_gray.dart 等;
- 在对应的环境文件中进行自定义标签配置。例如:
///main_prod.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
//初始化 SDK
await FTMobileFlutter.sdkConfig(
serverUrl: serverUrl,
debug: true,
);
await FTRUMManager().setConfig(
androidAppId: appAndroidId,
iOSAppId: appIOSId,
globalContext: {CUSTOM_STATIC_TAG:"prod_static_tag"},
);
runApp(MyApp());
};
}
动态使用¶
- 通过存文件类型数据,例如
shared_preferences
库SharedPreferences
,配置使用SDK
,在配置处添加获取标签数据的代码。
final prefs = await SharedPreferences.getInstance();
String customDynamicValue = prefs.getString("customDynamicValue")?? "not set";
await FTRUMManager().setConfig(
androidAppId: appAndroidId,
iOSAppId: appIOSId,
globalContext: {CUSTOM_DYNAMIC_TAG:customDynamicValue},
//… 添加其他配置
);
- 在任意处添加改变文件数据的方法。
static Future<void> setDynamicParams(String value) async{
final prefs = await SharedPreferences.getInstance();
prefs.setString(CUSTOM_DYNAMIC_TAG, value);
}
- 最后重启应用。
注意:
- 特殊 key : track_id (用于追踪功能)
- 当用户通过 globalContext 添加自定义标签与 SDK 自有标签相同时,SDK 的标签会覆盖用户设置的,建议标签命名添加项目缩写的前缀,例如
df_tag_name
。项目中使用key
值可查询源码。
Log 配置¶
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
sampleRate | double | 否 | 采样率,采集率的值范围为>= 0、<= 1,默认值为 1 |
serviceName | String | 否 | 服务名 |
enableLinkRumData | bool | 否 | 是否与 RUM 关联 |
enableCustomLog | bool | 否 | 是否开启自定义日志 |
discardStrategy | enum FTLogCacheDiscard | 否 | 日志丢弃策略,默认FTLogCacheDiscard.discard |
logLevelFilters | List |
否 | 日志等级过滤 |
Trace 配置¶
await FTTracer().setConfig(
enableLinkRUMData: true,
enableAutoTrace:false,
enableNativeAutoTrace: false
);
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
sampleRate | double | 否 | 采样率,采集率的值范围为>= 0、<= 1,默认值为 1 |
serviceName | String | 否 | 服务名 |
traceType | enum TraceType | 否 | 链路类型,默认TraceType.ddTrace |
enableLinkRUMData | bool | 否 | 是否与 RUM 数据关联,默认false |
enableAutoTrace | bool | 否 | 是否开启 flutter 网络追踪,默认false |
enableNativeAutoTrace | bool | 否 | 是否开启原生网络自动追踪 iOS NSURLSession ,Android OKhttp ,默认false |
RUM 用户数据追踪¶
Action¶
View¶
FTRUMManager().createView("Current Page Name",100000000)
FTRUMManager().starView("Current Page Name");
FTRUMManager().stopView();
如果需要采集应用休眠和唤醒行为需要添加如下代码:
class _HomeState extends State<HomeRoute> {
@override
void initState(){
//添加应用休眠和唤醒监听
FTLifeRecycleHandler().initObserver();
}
@override
void dispose(){
//移除应用休眠和唤醒监听
FTLifeRecycleHandler().removeObserver();
}
}
Error¶
/// flutter 自动采集 error
void main() async {
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
await FTMobileFlutter.sdkConfig(
serverUrl: serverUrl,
debug: true,
);
await FTRUMManager().setConfig(
androidAppId: appAndroidId,
iOSAppId: appIOSId,
enableNativeUserAction:false,
enableNativeUserView: false
);
// Flutter 框架异常捕获
FlutterError.onError = FTRUMManager().addFlutterError;
runApp(MyApp());
}, (Object error, StackTrace stack) {
//其它异常捕获与日志收集
FTRUMManager().addError(error, stack);
});
///自定义 error
FTRUMManager().addCustomError("error stack", "error message");
Resource¶
/// 使用 httpClient
void httpClientGetHttp(String url) async {
var httpClient = new HttpClient();
String key = Uuid().v4();
HttpClientResponse? response;
HttpClientRequest? request;
try {
request = await httpClient
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 10));
FTRUMManager().startResource(key);
response = await request.close();
} finally {
Map<String, dynamic> requestHeader = {};
Map<String, dynamic> responseHeader = {};
request!.headers.forEach((name, values) {
requestHeader[name] = values;
});
var responseBody = "";
if (response != null) {
response.headers.forEach((name, values) {
responseHeader[name] = values;
});
responseBody = await response.transform(Utf8Decoder()).join();
}
FTRUMManager().stopResource(key);
FTRUMManager().addResource(
key: key,
url: request.uri.toString(),
requestHeader: requestHeader,
httpMethod: request.method,
responseHeader: responseHeader,
resourceStatus: response?.statusCode,
responseBody: responseBody,
);
}
}
使用 http 库与 dio 库,可参考 example。
Logger 日志打印¶
日志等级¶
方法名 | 含义 |
---|---|
FTLogStatus.info | 提示 |
FTLogStatus.warning | 警告 |
FTLogStatus.error | 错误 |
FTLogStatus.critical | 严重 |
FTLogStatus.ok | 恢复 |
Tracer 网络链路追踪¶
/// 使用 httpClient
void httpClientGetHttp() async {
var url = 'http://www.google.cn';
var httpClient = new HttpClient();
String key = DateTime.now().millisecondsSinceEpoch.toString() + url;
var errorMessage = "";
HttpClientRequest request = await httpClient.getUrl(Uri.parse(url));
HttpClientResponse? response;
try {
final traceHeaders =
await FTTracer().getTraceHeader(key, request.uri.toString());
traceHeaders.forEach((key, value) {
request.headers.add(key, value);
});
response = await request.close();
} catch (exception) {
errorMessage = exception.toString();
} finally {
Map<String, dynamic> requestHeader = {};
Map<String, dynamic> responseHeader = {};
request.headers.forEach((name, values) {
requestHeader[name] = values;
});
if (response != null) {
response.headers.forEach((name, values) {
responseHeader[name] = values;
});
}
}
}
使用 http 库与 dio 库,可参考 example。