Web request performance

  • Latest Dynatrace
  • Explanation
  • 1-min read
  • Published Dec 24, 2025

Dynatrace provides comprehensive web request monitoring for Flutter applications. You can automatically instrument HTTP requests, enable distributed tracing with W3C trace context, manually report requests from unsupported libraries, and enrich request data with custom properties.

Automated web request instrumentation

Dynatrace offers automatic instrumentation for popular HTTP libraries in Flutter. Once configured, web requests are automatically tracked and timed.

Dart http package

The Dynatrace Flutter plugin provides DynatraceHttpClient, a wrapper for Dart's http package that automatically instruments all requests.

Basic usage

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
final client = Dynatrace().createHttpClient();
try {
await client.get(Uri.parse('https://api.example.com/data'));
} finally {
client.close();
}

Using custom HTTP clients

You can wrap your own HTTP client implementations:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:http/retry.dart';
// Standard Client
final standardClient = Dynatrace().createHttpClient(client: Client());
// IOClient
final ioClient = Dynatrace().createHttpClient(client: IOClient());
// RetryClient
final retryClient = Dynatrace().createHttpClient(client: RetryClient(Client()));

URL exclusion list

Exclude specific URLs from monitoring using strings or regular expressions. For string patterns, a URL is excluded if it contains the pattern. For RegExp patterns, the regex is evaluated against the URL.

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
final options = DynatraceHttpClientOptions(
{}, // Custom default headers (empty if not needed)
[
'internal-api.example.com', // String: excludes URLs containing this
'analytics.example.com', // String: excludes URLs containing this
RegExp(r'/api/users/\d+/profile'), // RegExp: excludes URLs matching this pattern
],
);
final client = Dynatrace().createHttpClient(options: options);

Request size calculation

The requestHeaders parameter in DynatraceHttpClientOptions is used only for accurate request size calculation. By default, Dart's HTTP client appends headers that are not visible at send time:

  • Accept-Encoding: gzip
  • User-Agent: Dart/X.X (dart:io)

If you modify or remove these default headers, provide the actual headers in requestHeaders so the size calculation remains accurate:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
// If you've changed the default User-Agent or removed Accept-Encoding
final options = DynatraceHttpClientOptions(
{
'User-Agent': 'MyApp/1.0', // Your custom User-Agent
// Don't include Accept-Encoding if you've removed it
},
[], // No exclusions
);
final client = Dynatrace().createHttpClient(options: options);

The requestHeaders parameter does not add headers to your requests. It only informs the plugin about headers that are automatically added by the HTTP client for accurate size calculation.

Dio package

For applications using the Dio HTTP client, Dynatrace provides a separate plugin for automatic instrumentation.

Installation

Add the Dio plugin to your dependencies:

flutter pub add dynatrace_flutter_plugin_dio

Basic usage

Use the .instrument() extension method to enable monitoring:

import 'package:dynatrace_flutter_plugin_dio/dynatrace_flutter_plugin_dio.dart';
import 'package:dio/dio.dart';
final dio = Dio();
dio.instrument();
await dio.get('https://api.example.com/data');

URL exclusion and options

import 'package:dynatrace_flutter_plugin_dio/dynatrace_flutter_plugin_dio.dart';
import 'package:dio/dio.dart';
final options = DynatraceClientAdapterOptions(
requestHeaders: {'User-Agent': 'MyApp/1.0'},
exclusionList: ['internal-api.example.com'],
);
final dio = Dio();
dio.instrument(options: options);

Manual web request reporting

For HTTP libraries not supported by automatic instrumentation, you can manually report web requests.

Using sendHttpRequestEvent

Report a completed HTTP request:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
import 'package:http/http.dart' as http;
final url = 'https://api.example.com/data';
// Time the request
final stopwatch = Stopwatch()..start();
final response = await http.get(Uri.parse(url));
stopwatch.stop();
// Report the request
Dynatrace().sendHttpRequestEvent(HttpRequestEventData(
url: url,
method: 'GET',
statusCode: response.statusCode,
duration: stopwatch.elapsedMilliseconds,
bytesReceived: response.bodyBytes.length,
));

Event enrichment and modifiers

Event modifiers allow you to customize HTTP event data before it's sent to Dynatrace. They work with events automatically captured by our instrumentation and do not apply to manually reported HTTP events.

HTTP events can also be modified via the general event modifier api but the http event modifier provides additional parameters to access the http request and response details.

Modifier order:

  1. General event modifier.
  2. HTTP event modifier.

Common use cases

  • Add custom properties.
  • Redact sensitive information from URLs.
  • Filter out specific requests.
  • Enrich events with business context.

HTTP event modifier (http package)

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
Dynatrace().addHttpEventModifier((event, request, response, error, stackTrace) {
// Add custom properties
event['event_properties.api_version'] = 'v2';
// Add request headers for debugging
// Warning: May expose sensitive data
event['event_properties.request_headers'] = request.headers.toString();
// Redact user IDs from URLs
if (event.containsKey('url.full')) {
event['url.full'] = event['url.full']
.toString()
.replaceAll(RegExp(r'/users/\w+/'), '/users/{id}/');
}
// Filter out health check requests
if (request.url.path.contains('/health')) {
return null; // Discard this event
}
return event;
});

Dio HTTP event modifier

For Dio requests, use the Dio-specific modifier:

import 'package:dynatrace_flutter_plugin_dio/dynatrace_flutter_plugin_dio.dart';
import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
import 'package:dio/dio.dart';
Dynatrace().addDioHttpEventModifier((event, request, response, error, stackTrace) {
// Add custom properties
event['event_properties.endpoint'] = request.path;
// Access Dio-specific response details
if (response != null) {
event['event_properties.response_type'] = response.data.runtimeType.toString();
}
return event;
});
final dio = Dio();
dio.instrument();

Remove modifiers

Remove modifiers when they are no longer needed:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
import 'package:http/http.dart';
// Define the modifier
Map<String, dynamic>? myModifier(
Map<String, dynamic> event,
BaseRequest request,
BaseResponse? response,
dynamic error,
StackTrace? stackTrace,
) {
event['event_properties.custom'] = 'value';
return event;
}
// Add the modifier
Dynatrace().addHttpEventModifier(myModifier);
// Remove when no longer needed
Dynatrace().removeHttpEventModifier(myModifier);

Modifier parameters

Parameter

Type

Description

event

Map<String, dynamic>

The HTTP event data containing fields like url.full, http.request.method, http.response.status_code

request

BaseRequest / RequestOptions

The HTTP request object with URL, method, headers

response

BaseResponse? / Response?

The HTTP response (null if request failed before response)

error

dynamic

Any error that occurred (null for successful requests)

stackTrace

StackTrace?

Stack trace for errors (null for successful requests)

Modifiable fields

Most HTTP event fields are read-only. The following can be modified:

  • url.full—the complete request URL.
  • exception.stack_trace—the exception stack trace.
  • event_properties.*—custom properties with this prefix.

Important considerations

  • Execution order—modifiers run in the order they were added.
  • Returning null—discards the event; subsequent modifiers won't run.
  • Performance—keep modifiers efficient—they run for every request.
  • Field naming—custom properties must use the event_properties. prefix.
  • Error handling—exceptions in modifiers are logged but don't block other modifiers.
Related tags
Digital Experience