Sürüm: 1.1.0Bu dokümantasyon Spitfire 1.1.0 içindir.
Flutter uygulamasını OTel ile bağlamak
Flutter (Android, iOS, web, masaüstü): HTTP çağrıları trace olarak; backend'e traceparent ile bağlanır. Değerler: Servisleri OTel ile bağlamak: genel bakış.
Sürüm tablosu
| Flutter | Dart | Paket | Sürüm |
|---|---|---|---|
| 3.22 ve sonrası | 3.4 ve sonrası | dartastic_opentelemetry |
0.12.0 |
| 3.22 ve sonrası | 3.4 ve sonrası | http |
1.6.0 |
| 3.19 ve öncesi | 3.3 ve öncesi | desteklenmiyor | Flutter 3.22'ye yükseltin |
Sürümünüzü bulun: flutter --version
OpenTelemetry'nin resmi Dart SDK'sı yok. dartastic_opentelemetry bir topluluk paketidir (Apache-2.0, CNCF'e bağışlanma sürecinde); sürümünü sabitleyin. Yalnızca trace.
Doğrulandı: 2026-11-04 (kod Flutter 3.47.5, Dart 3.13.4 ile denendi). Kaynak: pub.dev dartastic_opentelemetry, kaynak kod ve README, OTel blog: Dart ve Flutter, pub.dev http, Flutter --dart-define-from-file.
Gerekenler
- Spitfire adresi
https://<spitfire>(HTTPS: Android ve iOS düz HTTP'yi reddeder) - Servis adı
<service-name>, sürüm<service-version>, ortam<environment> - Uygulama klasörü (burada
/srv/app,pubspec.yamldosyasının olduğu yer)
Flutter
Anahtarı oluşturun: Gözlemlenebilirlik → Tarayıcı ve uygulama anahtarı; İzin verilen kökenler: web derlemesinin adresi, yalnızca Android ve iOS için boş;
sfrum_…anahtarını kopyalayın (Gözlemlenebilirlik).Paketleri ekleyin:
cd /srv/app && flutter pub add 'dartastic_opentelemetry:0.12.0' 'http:1.6.0'/srv/app/lib/otel.dartdosyasını oluşturun, yapıştırın:
// IS_OTEL_ENABLED=true: OTel on; any other value: off.
import 'package:dartastic_opentelemetry/dartastic_opentelemetry.dart';
import 'package:http/http.dart' as http;
const otelOn = String.fromEnvironment('IS_OTEL_ENABLED') == 'true';
Future<void> initOtel() async {
if (!otelOn) return;
await OTel.initialize(
serviceName: const String.fromEnvironment('OTEL_SERVICE_NAME'),
serviceVersion: const String.fromEnvironment('OTEL_SERVICE_VERSION'),
resourceAttributes: OTel.attributesFromMap({'deployment.environment': const String.fromEnvironment('OTEL_ENVIRONMENT')}),
spanKind: SpanKind.client,
sampler: ParentBasedSampler(TraceIdRatioSampler(double.parse(const String.fromEnvironment('OTEL_TRACES_SAMPLER_ARG', defaultValue: '0.1')))),
spanProcessor: BatchSpanProcessor(OtlpHttpSpanExporter(OtlpHttpExporterConfig(
endpoint: const String.fromEnvironment('OTEL_TRACES_ENDPOINT'),
headers: {'authorization': 'Bearer ${const String.fromEnvironment('OTEL_KEY')}'},
))),
detectPlatformResources: false,
enableMetrics: false,
enableLogs: false,
);
}
/// An http.Client whose requests are client spans carrying traceparent.
class OtelHttpClient extends http.BaseClient {
final http.Client _inner = http.Client();
final _propagator = W3CTraceContextPropagator();
@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
if (!otelOn) return _inner.send(request);
final span = OTel.tracer().startSpan('HTTP ${request.method}', kind: SpanKind.client,
attributes: OTel.attributesFromMap({'http.request.method': request.method, 'url.full': request.url.toString()}));
try {
return await OTel.withSpanAsync(span, () async {
_propagator.inject(Context.current, request.headers, _HeaderSetter(request.headers));
final res = await _inner.send(request);
span.addAttributes(OTel.attributesFromMap({'http.response.status_code': res.statusCode}));
return res;
});
} catch (e, st) {
span.recordException(e, stackTrace: st);
span.setStatus(SpanStatusCode.Error, e.toString());
rethrow;
} finally {
span.end();
}
}
}
class _HeaderSetter implements TextMapSetter<String> {
_HeaderSetter(this._headers);
final Map<String, String> _headers;
@override
void set(String key, String value) => _headers[key] = value;
}/srv/app/lib/main.dartiçindemainasync olsun, OTel ilk başlasın:
import 'otel.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await initOtel();
runApp(const MyApp());
}- API çağrılarınızı trace'li client ile gönderin:
final api = OtelHttpClient();
final res = await api.get(Uri.parse('https://api.example.com/orders'));/srv/app/otel.jsondosyasını oluşturun, yapıştırın:
{
"IS_OTEL_ENABLED": "true",
"OTEL_SERVICE_NAME": "<service-name>",
"OTEL_SERVICE_VERSION": "<service-version>",
"OTEL_ENVIRONMENT": "<environment>",
"OTEL_TRACES_ENDPOINT": "https://<spitfire>/otlp/v1/traces",
"OTEL_KEY": "sfrum_…",
"OTEL_TRACES_SAMPLER_ARG": "0.1"
}- Bu dosyayla derleyin (iOS:
ipa; web:web):
cd /srv/app && flutter build apk --release --dart-define-from-file=otel.jsonDoğrulama
- Spitfire anahtarı bir uygulamadan (
Originolmadan) kabul ediyor:
curl -s -o /dev/null -w '%{http_code}' -X POST https://<spitfire>/otlp/v1/traces -H 'Authorization: Bearer sfrum_…' -H 'Content-Type: application/json' -d '{}' | grep -q '^200