Download PDF
Download page Flutter インストゥルメンテーションのカスタマイズ.
Flutter インストゥルメンテーションのカスタマイズ
Flutter アプリケーションをインストゥルメント化したら、インストゥルメンテーションをさらに手動でカスタマイズできます。
ネットワーク要求
ネットワーク要求のメトリックを収集するには、HTTP クライアントラッパーを使用します。
DART
import 'package:http/http.dart' as http;
try {
final client = TrackedHttpClient(http.Client());
final response = await client.get(Uri.parse("https://www.appdynamics.com"));
print(response);
} catch (e) {
print(e);
}
要求にユーザーデータを追加するなど、要求のトラッキングをより細かく制御する必要がある場合は、完了時に要求情報を登録するトラッカーオブジェクトを手動で作成できます。
try {
final url = "www.appdynamics.com"
final tracker = await RequestTracker.create(url);
final response = await http.get(url);
await tracker.setResponseStatusCode(response.statusCode)
..setRequestHeaders(response.request!.headers)
..setResponseHeaders(response.headers)
..setUserDataBool("shouldRespond", false);
} catch (e) {
await tracker.setError(e.toString());
} finally {
await tracker.reportDone();
}
サーバー相関ヘッダーの追加
別の AppDynamics エージェントも、アプリケーションのバックエンドのインストゥルメント化に使用する場合、サーバー相関ヘッダーを追加して、ビジネストランザクションを特定できます。
import 'package:http/http.dart' as http;
try {
final headers = await RequestTracker.getServerCorrelationHeaders();
final url = Uri.parse("https://www.appdynamics.com");
final client = HttpClient(http.Client());
final response = await client.get(url, headers: headers);
print(response);
} catch (e) {
print(e);
}
仕組み
RequestTracker.create(url)
Null 以外の url
を指定する(Instrumentation.start()
を呼び出した後)ことにより、HTTP リクエストを手動でトラッキングするように設定された RequestTracker
オブジェクトを返します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
url | 文字列 | Null 以外。 | トラッキングされるリクエストのターゲット URL。 |
setError(message, stackTrace)
応答を受信できなかったことを示すエラーメッセージを設定します(エラーが発生した場合)。リクエストが成功した場合は、このメソッドを呼び出さないでください。stackTrace 文字列を追加できます。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
message | 文字列 | リクエストが正常に終了しませんでした。 | エラーメッセージまたはエラーを説明する文字列。 |
stackTrace | 文字列 | リクエストが正常に終了しませんでした。 | エラー stackTrace プロパティ(ある場合)。 |
setResponseStatusCode(statusCode)
応答のステータスコードを設定します(ある場合)。応答を受信した場合は、このメソッドは整数になります。エラーが発生し、応答が受信されなかった場合、このメソッドは呼び出しません。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
| 整数 | リクエストが正常に終了しました。 | 応答のステータスコード。 |
setRequestHeaders(requestHeaders)
トラッカーオブジェクトにリクエストヘッダーを追加します。エラーが発生し、応答が受信されなかった場合、このメソッドは呼び出しません。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
| Map<String, String> | リクエストが正常に終了しました。 | リクエストのヘッダー値を表すキーと値のペアのマップ。 |
setResponseHeaders(responseHeaders)
トラッカーオブジェクトにリクエストの応答を追加します。エラーが発生し、応答が受信されなかった場合、これは呼び出しません。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
| Map<String, String> | リクエストが正常に終了しました。 | 応答のヘッダー値を表すキーと値のペアのマップ。 |
reportDone()
HTTP リクエストが完了し、適切な情報をログに記録したことを通知します。別のリクエストをトラッキングする必要がある場合は、新しい RequestTracker
を作成する必要があります。
getServerCorrelationHeaders()
AppDynamics エージェントもサーバー側で使用される場合に使用するサーバー相関ヘッダーを返します。トラッキング対象のリクエストにヘッダーを追加する必要があります。
setUserdata
対応する各 API を使用してリクエスト トラッキング オブジェクトにカスタム値を追加します。
setUserData(key, value)
setUserDataBool(key, value)
setUserDataDateTime(key, value)
setUserDataDouble(key, value)
setUserDataInt(key, value)
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
| String | 最大 2048 文字。一意(そうでない場合は上書きされます)。 | 対応する値のキー名。 |
value | String, bool, DateTime, double, int | 最大 2048 文字。 | リクエストに追加されたカスタム情報。 |
クラッシュ
ネイティブクラッシュの報告
Flutter エージェントは、ネイティブクラッシュ情報を自動的にログに記録します。これは、Instrumentation.start()
の呼び出し時にすでに有効になっています。ネイティブクラッシュは、UI コントローラで対応する .dsym または ProGuard ファイルを渡すことでシンボル化できます。「人間が判読能なクラッシュスナップショットの取得」を参照してください。
すべてのクラッシュの報告
すべてのエラー(Flutter およびネイティブ)をキャプチャするには、ゾーンを使用します。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:appdynamics_mobilesdk/appdynamics_mobilesdk.dart';
void main() {
runZonedGuarded(() {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = Instrumentation.errorHandler;
runApp(MyApp());
}, (Object error, StackTrace stack) async {
final details =
FlutterErrorDetails(exception: error.toString(), stack: stack);
await Instrumentation.errorHandler(details);
});
Dart 例外の報告
Flutter エージェントが提供するエラーハンドラを使用して、Dart 例外をインターセプトし、コントローラに送信します。
import 'package:flutter/material.dart';
import 'package:appdynamics_mobilesdk/appdynamics_mobilesdk.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = Instrumentation.errorHandler;
runApp(MyApp());
}
クラッシュレポートの無効化
クラッシュレポートは、デフォルトで有効になっています。ほとんどのアプリケーションでは、クラッシュレポートを有効にしておく必要がありますが、別のクラッシュレポートツールの使用によって問題が発生する場合にのみ無効にできます。
AgentConfiguration
オブジェクトでネイティブ クラッシュ レポート機能を有効または無効にできます。
AgentConfiguration config = AgentConfiguration(
appKey: <EUM_APP_KEY>,
crashReportingEnabled: false);
await Instrumentation.start(config);
クラッシュコールバック
Flutter エージェントは、クラッシュレポートを受け取るコールバック関数の使用をサポートしています。このレポートには、ネイティブクラッシュ情報を表す Dart オブジェクトの配列が含まれています。
コールバック関数は、AgentConfiguration
オブジェクトで設定できます。
void crashReportCallback(List<CrashReportSummary> summaries) async {
print(summaries);
}
AgentConfiguration config = AgentConfiguration(
appKey: <EUM_APP_KEY>,
crashReportCallback: crashReportCallback);
await Instrumentation.start(config);
Session Frames
セッションフレームは、セッション中にユーザが実行している内容のコンテキストを提供します。カスタム ユーザー インタラクション フレームは、コントローラ UI またはエージェント インストゥルメンテーションの SessionFrame API で作成できます。
セッションフレームをカスタマイズする使用例には、次のようなものがあります。
- 1 つのページで複数の関数を実行し、個々の関数をより詳細にトラッキングする必要があります。
- ユーザーフローが複数のページまたはユーザーインタラクションにまたがっており、ユーザーフロー内のフレームを分類する必要があります。たとえば、購入のユーザーフローがある場合、「Login」、「Product Selection」、および「Purchase」という名前のセッションフレームを作成できます。
- ユーザの操作に基づいて動的情報をキャプチャし、オーダー ID などのセッションフレームに名前を付けることができます。
仕組み
Instrumentation.startSessionFrame(sessionFrameName)
SessionFrame
オブジェクトを開始して返します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
sessionFrameName | 文字列 | Null 以外 | キャプチャされるセッションフレームのわかりやすい名前。 |
updateName(newName)
セッションフレームを新しい名前で更新します。これは通常、適切なセッションフレーム名が作成時に不明な場合に使用されます。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
newName | 文字列 | Null 以外 | キャプチャされるセッションフレームのわかりやすい名前。 |
end()
セッションフレームの終了を報告します。この呼び出しの後、SessionFrame
オブジェクトは使用できなくなります。
次は、ユーザーがチェックアウトボタンを押したときに現在のショッピングセッションの終了をマークする方法の例です。
class ShoppingCart {
late SessionFrame _sessionFrame;
late String _orderId;
void onCheckoutCartButtonClick() async {
// The checkout starts when the user clicks the checkout button.
// This may be after they have updated quantities of items in their
// cart, etc.
_sessionFrame = await Instrumentation.startSessionFrame("Checkout");
}
void onConfirmOrderButtonClick() {
// Once they have confirmed payment info and shipping information,
// and they are clicking the "Confirm" button to start the backend
// process of checking out, we may know more information about the
// order itself, such as an order ID.
_sessionFrame.updateName("Checkout: Order ID {this.orderId}");
}
void onProcessOrderComplete() {
// Once the order is processed, the user is done "checking out" so we end
// the session frame.
_sessionFrame.end();
}
void onCheckoutCancel() {
// If they cancel or go back, you'll want to end the session frame also, or
// else it will be left open and appear to have never ended.
_sessionFrame.end();
}
メトリック
数値をメトリック名に関連付けて、Instrumentation.reportMetric
を介して報告できます。
仕組み
Instrumentation.reportMetric(name, value)
カスタムメトリックを報告します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
| 文字列 | 英数字とスペースのみ。 | メトリックを表す名前。 |
value | 整数 | 数値、Null 以外。 | メトリック値。 |
次は、ユーザーがチェックアウトボタンをクリックした回数をトラッキングする方法の例です。
import 'package:appdynamics_mobilesdk/appdynamics_mobilesdk.dart';
import 'package:flutter/material.dart';
class App extends StatelessWidget {
_finishCheckout() {
Instrumentation.reportMetric(name: "Checkout Count", value: 1);
// ...rest of the checkout logic
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Checkout screen")),
body: Center(
child:
ElevatedButton(
child: Text('Checkout'),
onPressed: _finishCheckout,
)
));
}
自動スクリーンショット(iOS のみ)
デフォルトでは、スクリーンショットのキャプチャは有効になっていますが、(プライバシー上の理由などで)無効にする必要がある場合は、AgentConfiguration
オブジェクトで無効にできます。
次は、スクリーンショットを無効にする例です。
AgentConfiguration config = AgentConfiguration(
appKey: <EUM_APP_KEY>,
screenshotsEnabled: false);
await Instrumentation.start(config);
ユーザ データ
すべてのスナップショットに含まれるカスタムユーザーデータのキーと値のペアの識別子を設定できます。考慮事項:
- キーは、アプリケーション全体で一意である必要があります。
- キーと関連する値は 2048 文字に制限されています。
null
値によってデータが消去され、同じキーを再使用すると前の値が上書きされます。- カスタムユーザーデータは、アプリケーションを実行しても保持されません。アプリケーションが破棄されると、ユーザーデータは消去されます。
仕組み
setUserData(key, value)
string
型を追加するために使用します。
removeUserData(key)
setUserData()
で設定したキーに対応する string
を削除します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
key | 文字列 | 最大 2048 文字(Null 以外)。 | ユーザーデータキーの名前。 |
value | 文字列 | 最大 2048 文字。 | キーに関連付けられた s |
setUserDataDouble(key, value)
double
型を追加するために使用します。
removeUserDataDouble(key)
setUserDataDouble()
で設定されたキーに対応する double
を削除します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
key | 文字列 | 最大 2048 文字(Null 以外)。 | ユーザーデータキーの名前。 |
value | 倍精度浮動小数点型 | 最大 2048 文字。 | キーに関連付けられた double 値。 |
setUserDataInt(key, value)
int
型を追加するために使用します。
removeUserDataInt(key)
setUserDataInt()
で設定したキーに対応する int
を削除します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
key | 文字列 | 最大 2048 文字(Null 以外)。 | ユーザーデータキーの名前。 |
value | 整数 | 最大 2048 文字。 | キーに関連付けられた int 値。 |
setUserDataBool(key, value)
bool
型を追加するために使用します。
removeUserDataBool(key)
setUserDataBool()
で設定したキーに対応する bool
を削除します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
key | 文字列 | 最大 2048 文字(Null 以外)。 | ユーザーデータキーの名前。 |
value | ブール型 | - | キーに関連付けられた bool 値。 |
setUserDataDateTime(key, value)
DateTime
型を追加するために使用します。
removeUserDataDateTime(key)
setUserDataDateTime()
で設定したキーに対応する DateTime
を削除します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
key | 文字列 | 最大 2048 文字(Null 以外)。 | ユーザーデータキーの名前。 |
value | 日時(DateTime) | - | キーに関連付けられた DateTime 値。 |
次は、DateTime
オブジェクトをユーザーデータとして保存する方法の例です。
await Instrumentation.setUserDataDateTime("currentTransactionYear", DateTime.utc(2021));
トピックパス(パンくずリスト)
トピックパス(パンくずリスト)を使用して、アプリケーション全体で関心のあるポイントを報告できます。トピックパスは、モードに応じてさまざまなレポートに含まれます。
- トピックパスをクラッシュレポート(アプリケーションの再起動時にトリガーされる)にのみ表示する場合は、
crashesOnly
モード(デフォルト)を使用します。 - セッションにもトピックパスを表示する場合は、
crashesAndSessions
モードを使用します。
各クラッシュレポートには、最近の 99 件のトピックパスのみが表示されます。
仕組み
leaveBreadcrumb(breadcrumb, mode)
トピックパスの名前と、モバイルセッションでの表示場所を設定します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
breadcrumb | 文字列 | 最大 2048 文字(余分な文字はすべて切り捨てられます)。 | トピックパスを説明するための文字列。 |
mode
| BreadcrumbVisibility (enum) | - | セッションでトピックパス情報を表示するかどうかを設定します。 |
次は、サインアップ画面に切り替える前後にトピックパスを配置する方法の例です。
Future<void> showSignUp() async {
try {
await Instrumentation.leaveBreadcrumb("Sign up button pressed.",
BreadcrumbVisibility.crashesAndSessions);
await pushSignUpScreen();
await Instrumentation.leaveBreadcrumb("Sign Up screen pushed",
BreadcrumbVisibility.crashesOnly);
} catch (e) {
...
}
}
タイマー
複数のメソッドにまたがるカスタムタイマーを使用して、イベントの時間を計測できます。
仕組み
startTimer(name)
タイマーを設定します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
name | 文字列 | 英数字とスペースのみ(Null 以外)。 | タイマーに関連付ける一意の識別子。 |
stopTimer(name)
タイマーを停止します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
name | 文字列 | 英数字とスペースのみ(Null 以外)。 | タイマーに関連付ける一意の識別子。 |
次は、チェックアウトにかかる時間をカウントするタイマーを開始する方法の例です。
Future<void> doCheckout() async {
final checkoutTimerName = "Time spent on checkout";
try {
await Instrumentation.startTimer(checkoutTimerName);
await someCheckoutService();
await someOtherLongTask();
} finally {
await Instrumentation.stopTimer(checkoutTimerName);
}
}
エラー
Dart エラー、例外、およびカスタムメッセージを報告できます。
エラーのシビラティ(重大度)には以下の 3 つのレベルがあります。
info
:エラーが発生しましたが、問題にはなりませんでした。warning
:エラーが発生しましたが、アプリケーションはグレースフルで回復しました。critical
:エラーが発生し、アプリケーションに問題が発生しました。
仕組み
reportException(exception, severityLevel)
エラー例外と関連するシビラティ(重大度)レベルを設定します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
exception | Exception | - | Dart |
severityLevel | ErrorSeverityLevel (enum) | デフォルトでは60000。 warning | 対応するシビラティ(重大度)レベル。 |
reportError(error, severityLevel)
関連するシビラティ(重大度)レベルでエラーレポートを作成します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
error | Error | - | Dart |
severityLevel | ErrorSeverityLevel (enum) | デフォルトでは60000。 warning | 対応するシビラティ(重大度)レベル。 |
reportMessage(message, severityLevel)
メッセージレポートを作成します(reportError()
と reportException()
がどちらも適切ではない場合に使用します)。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
message | 文字列 | - | Dart |
severityLevel | ErrorSeverityLevel (enum) | デフォルトでは60000。 warning | 対応するシビラティ(重大度)レベル。 |
次は、宣言されていないメソッドを呼び出したときに NoSuchMethodError
を報告する方法の例です。
try {
final myMethod = null;
myMethod();
} on NoSuchMethodError catch (e) {
await Instrumentation.reportError(e, severityLevel: ErrorSeverityLevel.CRITICAL);
}
Application Not Responding(ANR)
AgentConfiguration
オブジェクトの作成時に、アプリケーションが応答しない場合(ANR)の自動検出とレポートを設定できます。
次は、自動 ANR 検出機能を有効にする方法の例です。
AgentConfiguration config = AgentConfiguration(
appKey: <EUM_APP_KEY>
);
await Instrumentation.start(config);
情報ポイント
Instrumentation
クラスを使用して、アプリケーション内の特定の関心ポイントをトラッキングできます。
方法
trackCall(className, methodName, methodBody, methodArgs, uniqueCallId)
呼び出しにトラッカーを設定します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
className | String | - | メソッド呼び出しのクラスまたはオブジェクトの名前。 |
methodName
| String | - | メソッドの名前。 |
methodBody | FutureOr<T> Function() | - | トラッキングされているメソッドの本文。 |
methodArgs | dynamic | - | メソッドの引数。 |
uniqueCallId | String? | - | この呼び出しをトラッキングするための一意のカスタム ID。 |
次は、サーバー上のユーザーの姓名を更新する非同期メソッドをトラッキングする例です。
const firstName = "John";
const lastName = "Peters";
final result = await Instrumentation.trackCall(
className: "MyAccountScreen",
methodName: "updateUserName",
methodArgs: [firstName, lastName],
methodBody: () async {
await http.post(
Uri.parse('https://jsonplaceholder.typicode.com/albums'),
body: jsonEncode(
<String, String>{'firstName': firstName, 'lastName': lastName}),
);
}
);
セッション
新しいセッションを開始して、現在のセッションの終了をマークできます。
方法
startNextSession()
セッションの開始と終了を設定します。
次は、顧客の前のチェックアウトセッションが終了した後に、新しいチェックアウトセッションをマークする例です。
Future<void> checkout(dynamic data) async {
try {
final response = http.post("https://server.com/checkout", data);
await Instrumentation.startNextSession();
} catch (e) {
print(e);
}
}
アプリケーションキー
アプリケーションキーは初期化後に変更できます。新しいキーが適用されると、古いレポートは破棄されます。いずれかの開始メソッドを呼び出してエージェントがすでに初期化されていない限り、このメソッドを呼び出しても効果はありません。
メソッド
changeAppKey(newKey)
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
newKey | String | アプリケーションキーの形式を尊重する必要があります(有効である必要があります)。 | 古いキーに代わる新しいキー。 |
次は、アプリケーションキーを AA-BBB-CCC に更新する例です。
try {
await Instrumentation.changeAppKey("AA-BBB-CCC");
} catch (e) {
print(e);
}
画面トラッキング
NavigationObserver
をアプリケーションに追加して、名前付きルートを使用してアプリケーション ウィジェットの遷移を自動的に検出できます。アプリケーションが名前付きルートを実装していない場合は、WidgetTracker
クラスを介して画面を手動でトラッキングできます。
仕組み
NavigationObserver
import 'package:appdynamics_mobilesdk/appdynamics_mobilesdk.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: MyRoutes.mainScreen,
onGenerateRoute: MyRouter.onGenerateRoute,
navigatorObservers: [NavigationObserver()]);
}
}
WidgetTracker
Flutter ウィジェットにトラッキングを追加して、特定の UI 要素をモニターできます。たとえば、Flutter アプリケーションが名前付きルートを自動的に実装していない場合、WidgetTracker
クラスを介して画面を手動でトラッキングできます。
仕組み
trackWidgetStart()
ウィジェットのトラッキングを開始します。
trackWidgetEnd()
ウィジェットのトラッキングを停止します。
パラメータ
名前 | タイプ | 要件 | 説明 |
---|---|---|---|
widgetName | String | 一意である必要があります。 | メソッド呼び出しのクラスまたはオブジェクトの名前。 |
次は、CheckoutPage.screenName
ウィジェットをトラッキングする例です。
import 'package:appdynamics_mobilesdk/appdynamics_mobilesdk.dart';
import 'package:flutter/material.dart';
class CheckoutPage extends StatefulWidget {
const CheckoutPage({Key? key}) : super(key: key);
static String screenName = "Checkout Page";
@override
_CheckoutPageState createState() => _CheckoutPageState();
}
class _CheckoutPageState extends State<CheckoutPage> {
@override
void initState() async {
super.initState();
await WidgetTracker.instance.trackWidgetStart(CheckoutPage.screenName);
}
_backToMainScreen() async {
await WidgetTracker.instance.trackWidgetEnd(CheckoutPage.screenName);
Navigator.pop(context);
}
@override
Widget build(BuildContext context) {
return Center(
child:
Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
ElevatedButton(
child: const Text('Proceed'),
onPressed: _backToMainScreen,
)
]));
}
}
デバイスメトリック
デバイスのステータスに関するさまざまなメトリックが自動的にトラッキングされます。「モバイル デバイス メトリック コレクション」を参照してください。
Flutter エージェント API ドキュメント
以下の最新の Flutter エージェント API ドキュメントまたは前のバージョンを参照してください。