instana_agent 3.0.6
instana_agent: ^3.0.6 copied to clipboard
An Instana agent to collect statistics about sessions and HTTP requests for Flutter-based apps.
example/lib/main.dart
/*
* (c) Copyright IBM Corp. 2021
* (c) Copyright Instana Inc. and contributors 2021
*/
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:instana_agent/instana_agent.dart';
<<<<<<< Updated upstream
=======
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
>>>>>>> Stashed changes
import 'http_client.dart';
class MyProxyHttpOverride extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..findProxy = (uri) {
return "PROXY proxy.us.ibm.com:8080;";
}
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
// In your main.dart
HttpOverrides.global = MyProxyHttpOverride();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Future<Album> futureAlbum;
@override
void initState() {
super.initState();
/// Initializes Instana. Must be run only once as soon as possible in the app's lifecycle
setupInstana();
setupWebview();
/// optional
futureAlbum = fetchAlbum();
}
void setupInstana() async {
var options = SetupOptions();
options.collectionEnabled = false;
// options.slowSendInterval = 60.0; // enable slow send mode on beacon send failure, send interval is 60 seconds
// options.usiRefreshTimeIntervalInHrs = 24.0; // refresh user session id every 24 hours
bool ret = await InstanaAgent.setup(key: 'key', reportingUrl: 'URL', options: options);
if (!ret) {
// Error handling here
if (kDebugMode) {
print("InstanaAgent setup failed");
}
}
setUserIdentifiers();
InstanaAgent.setCollectionEnabled(true);
/// optional
setView();
InstanaAgent.setCaptureHeaders(regex: [
'x-ratelimit-limit',
'x-ratelimit-remaining',
'x-ratelimit-reset'
]);
InstanaAgent.redactHTTPQuery(regex: ['uid', 'user']);
/// optional
reportCustomEvents();
}
/// Set user identifiers
///
/// These will be attached to all subsequent beacons
setUserIdentifiers() {
InstanaAgent.setUserID('1234567890');
InstanaAgent.setUserName('Boty McBotFace');
InstanaAgent.setUserEmail('boty@mcbot.com');
}
/// Setting a view allows for easier logical segmentation of beacons in the timeline shown in the Instana Dashboard's Session
setView() {
InstanaAgent.setView('Home');
}
/// At any time, Metadata can be added to Instana beacons and events can be generated
Future<void> reportCustomEvents() async {
InstanaAgent.setMeta(key: 'exampleGlobalKey', value: 'exampleGlobalValue');
await InstanaAgent.reportEvent(name: 'simpleCustomEvent');
await InstanaAgent.reportEvent(
name: 'complexCustomEvent',
options: EventOptions()
..viewName = 'customViewName'
..startTime = DateTime.now().millisecondsSinceEpoch
..duration = 2 * 1000);
await InstanaAgent.reportEvent(
name: 'advancedCustomEvent',
options: EventOptions()
..viewName = 'customViewName'
..startTime = DateTime.now().millisecondsSinceEpoch
..duration = 3 * 1000
..meta = {
'customKey1': 'customValue1',
'customKey2': 'customValue2'
});
await InstanaAgent.startCapture(
url: 'https://example.com/failure', method: 'GET')
.then((marker) => marker
..responseStatusCode = 500
..responseSizeBody = 1000
..responseSizeBodyDecoded = 2400
..errorMessage = 'Download of album failed'
..finish());
await InstanaAgent.startCapture(
url: 'https://example.com/cancel', method: 'POST')
.then((marker) => marker.cancel());
}
Future<Album> fetchAlbum() async {
return Album.fromJson(jsonDecode('{"userId": 1, "id": 1, "title": "quidem molestiae enim"}'));
// final InstrumentedHttpClient httpClient =
// InstrumentedHttpClient(http.Client());
//
// Random random = new Random();
// var id = random.nextInt(100);
// var uid = random.nextInt(1000);
// var url = 'https://jsonplaceholder.typicode.com/albums/${id}?uid=${uid}';
// final http.Request request = http.Request("GET", Uri.parse(url));
//
// final response = await httpClient.send(request);
// if (response.statusCode == 200) {
// var responseBody = await response.stream.bytesToString();
// return Album.fromJson(jsonDecode(responseBody));
// } else {
// throw Exception('Failed to load album');
// }
}
<<<<<<< Updated upstream
@override
Widget build(BuildContext context) {
=======
String script = '''
(function(s,t,a,n){s[t]||(s[t]=a,n=s[a]=function(){n.q.push(arguments)},
n.q=[],n.v=2,n.l=1*new Date)})(window,"InstanaEumObject","ineum");
ineum('reportingUrl', 'https://eum-pink-saas.instana.rocks');
ineum('key', 'WEBSITE_KEY');
ineum('trackSessions');
var newScript = document.createElement("script");
newScript.src = "https://eum-pink-saas.instana.rocks/eum.min.js";
newScript.crossorigin = "anonymous";
document.head.appendChild(newScript);
''';
void setupWebview() {
PlatformWebViewControllerCreationParams params;
if (defaultTargetPlatform == TargetPlatform.iOS) {
params = WebKitWebViewControllerCreationParams();
} else {
params = const PlatformWebViewControllerCreationParams();
}
controller = WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
'Toaster',
onMessageReceived: (JavaScriptMessage message) {
print("MESSAGGGGEE $message");
},
)
..loadRequest(Uri.parse('https://twitter.com/'));
// ..runJavaScript("(function(s,t,a,n){s[t]||(s[t]=a,n=s[a]=function(){n.q.push(arguments)}, n.q=[],n.v=2,n.l=1*new Date)})(window,\"InstanaEumObject\",\"ineum\"); ineum('reportingUrl', 'https://eum-pink-saas.instana.rocks'); ineum('key', 'WEBSITE_KEY'); ineum('trackSessions'); var newScript = document.createElement(\"script\"); newScript.src = \"https://eum-pink-saas.instana.rocks/eum.min.js\"; newScript.crossorigin = \"anonymous\"; document.head.appendChild(newScript);");
}
late WebViewController controller;
@override
Widget build(BuildContext context) {
controller.runJavaScript(script.toString());
controller.setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
// Update loading bar.
},
onPageStarted: (String url) {
print("URLs onPageStarted: $url");
},
onPageFinished: (String url) {
print("URLs onPageFinished: $url");
controller.runJavaScript(script.toString());
},
onWebResourceError: (WebResourceError error) {
},
onNavigationRequest: (NavigationRequest request) async {
print("URLs:NavigationRequest: ${request.url}");
// await InstanaAgent.startCapture(url: request.url, method: 'GET').then((marker) => marker.finish());
return NavigationDecision.navigate;
},
),
);
>>>>>>> Stashed changes
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: <Widget>[
ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
padding: const EdgeInsets.all(8.0),
textStyle: const TextStyle(fontSize: 16, color: Colors.blue),
),
onPressed: () {
this.setState(() {
futureAlbum = fetchAlbum();
});
},
child: Text("Reload")),
FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("Title: " +
snapshot.data!.title +
"\nID: " +
snapshot.data!.id.toString());
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return Text("Loading...");
}
},
)
],
),
),
),
);
}
}
class Album {
final int userId;
final int id;
final String title;
Album({required this.userId, required this.id, required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}