この記事でやること(3分で読める要約)
- Flutterアプリに New Relic Flutter Agent を導入して、クラッシュ/通信/画面遷移/分散トレーシングまで“一気通貫”で見えるようにする
- New Relic MCP を使って、AIエージェントから「いま何が起きてる?」を自然言語で調査できる状態にする
- 監視は“データ入れすぎるとコスト化”するので、Drop/集約(Events→Metrics) まで含めて運用に落とす
1. なぜFlutterにオブザーバビリティが必要か
Flutterは体感品質が命です。
でも、障害が起きた瞬間に起こるのはだいたいこれ。
- 「特定の画面で落ちる」けど再現しない
- 「遅い」けど端末や回線条件が分からない
- 「APIは正常」なのに“体感”が悪い
ここを アプリ(フロント)⇄ バックエンド まで一本の線(トレース)でつなぐのが、New Relicの強いところ。
Flutterでも Dartエラー / HTTP / 分散トレーシング / カスタムイベント まで取れます。
2. FlutterにNew Relicを入れる(newrelic_mobile)
Flutter向けは newrelic_mobile(New Relic公式publisher)を使います。
2.1 pubspec.yaml
dependencies:
newrelic_mobile: ^1.1.19
※バージョンは最新に合わせてOK(この記事では例として
^1.1.19を記載)
2.2 main.dart(最小構成:起動+主要機能ON)
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:newrelic_mobile/newrelic_mobile.dart';
void main() {
var appToken = "";
if (Platform.isAndroid) appToken = "<android app token>";
if (Platform.isIOS) appToken = "<ios app token>";
final config = Config(
accessToken: appToken,
analyticsEventEnabled: true,
networkErrorRequestEnabled: true,
networkRequestEnabled: true,
crashReportingEnabled: true,
interactionTracingEnabled: true,
httpResponseBodyCaptureEnabled: true,
loggingEnabled: true,
webViewInstrumentation: true,
printStatementAsEventsEnabled: true,
httpInstrumentationEnabled: true,
distributedTracingEnabled: true,
logLevel: LogLevel.DEBUG,
);
NewrelicMobile.instance.start(config, () {
runApp(const MyApp());
});
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(child: Text("Hello New Relic")),
),
);
}
}
3. “再現しないクラッシュ”を捕まえる(runZonedGuarded)
Dart側の例外が落ちた時に、New Relicへ送っておくと「あの日あの端末だけ落ちた」が追えます。
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:newrelic_mobile/newrelic_mobile.dart';
void main() {
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
// FlutterエラーをNew Relicへ
FlutterError.onError = NewrelicMobile.onError;
// startAgent を使う場合の例(start(config, callback) でOKならそちらで)
await NewrelicMobile.instance.startAgent(config);
runApp(const MyApp());
}, (Object error, StackTrace stackTrace) {
NewrelicMobile.instance.recordError(error, stackTrace);
});
}
4. “画面遷移”が取れると、調査が一気にラク
障害対応で効くのは「どの画面で起きたか」です。
NewRelicNavigationObserver を入れるだけで、画面遷移イベントを追えるようになります。
import 'package:flutter/material.dart';
import 'package:newrelic_mobile/newrelic_navigation_observer.dart';
MaterialApp(
navigatorObservers: [NewRelicNavigationObserver()],
// ...
)
スクショ映えポイント
- 「クラッシュした直前にどの画面にいたか」
- 「遅延が出る画面遷移のパターン」
を1枚で見せると“ワオッ”が出ます。
5. “体感の悪さ”をインタラクションとして計測する
「遅い」を“計測できる形”にします。
例:タイムラインのロードや画像生成など、ユーザーが待つ処理に名前を付けます。
final id = await NewrelicMobile.instance.startInteraction("Load timeline");
try {
// API呼び出し等
} finally {
NewrelicMobile.instance.endInteraction(id);
}
6. ここからが本番:New Relic MCPで“AIに調査させる”
New RelicのMCPサーバーは、AIエージェントからNew Relicに安全にアクセスするための“標準ブリッジ”です。
AIに「関連するメトリクス/ログ/トレースを取ってきて整理」させられるのが強い。
6.1 AIへの質問テンプレ(そのまま使える)
- 「直近30分でクラッシュが増えたリリースは?」
- 「
/purchaseが遅いユーザーセグメント(端末/OS/回線)は?」 - 「遅延が出ているトレースの共通点(画面/属性/外部API)をまとめて」
- 「アラートが多い原因の上位3つと、抑える施策案を出して」
7. 監視の落とし穴:データを入れすぎるとコストになる → “絞る”までがセット
監視を本番投入すると、ログ/イベントが増えがちです。
「見える化」は強い一方、何も考えずに全部入れると“嬉しいけど高い”になります。
ここは Drop / 集約(Events→Metrics) をセットでやります。
7.1 Drop rule:ノイズを捨てる(例)
- healthcheck / bot / 期待通りのエラー(404など)
- debugログや、検証用のカスタムイベント
- 特定エンドポイントの高頻度ログ(必要なものだけ残す)
注意:Dropしたデータは保持されず復元不可。
ただし、その分 取り込み量(ingest)も減り、コスト最適化に直結します。
7.2 Events / Logs / Spans を Metrics に集約して長期トレンドを見る
「粒度の高い生データ」は短期分析に強い一方、長期保持や集計は重くなります。
集約してメトリクス化しておくと、長期の傾向(徐々に遅くなる等)を安定して追えます。
8. まとめ:導入しました、で終わらせない
この記事のキモは **「導入しました」じゃなく「運用が変わった」**まで見せること。
- Flutter側:クラッシュ/遅延/画面遷移/通信を“線”で追えるようにした
- AI側:MCPで「原因特定→次アクション」を自然言語で回せるようにした
- コスト側:Drop / 集約で“データを絞る”運用まで入れた
おまけ:優勝仕様にするチェックリスト
- 「導入前→導入後」で 1つだけ数値を出す(例:MTTR / 問い合わせ回数 / 遅延割合)
- AIに投げた質問と回答をそのまま載せる(スクショ1枚)
- Drop/集約で “どれを捨て、どれを残すか”の判断基準を書く(ここが一番参考になる)
- 可能なら「実害(ユーザー影響)」→「発見」→「切り分け」→「復旧」までの小さなストーリーにする