otel_command_it 0.2.0 copy "otel_command_it: ^0.2.0" to clipboard
otel_command_it: ^0.2.0 copied to clipboard

OpenTelemetry instrumentation for package:command_it (Thomas Burkhart's renamed flutter_command). Wraps each Command execution in a CLIENT-kind span with duration and failures.

example/example.md

otel_command_it example #

A login form whose submit button taps emit a span you can find in any OTLP-compatible tracing backend.

// example/lib/main.dart

import 'package:command_it/command_it.dart';
import 'package:dartastic_opentelemetry/dartastic_opentelemetry.dart';
import 'package:flutter/material.dart';
import 'package:otel_command_it/otel_command_it.dart';

class AuthService {
  Future<void> login(String email, String password) async {
    await Future<void>.delayed(const Duration(milliseconds: 250));
    if (password.length < 8) throw StateError('password too short');
  }
}

late final AuthService auth;

Future<void> main() async {
  await OTel.initialize(
    serviceName: 'command-it-demo',
  );
  // Required so runAsync's future completes on error.
  // Even a no-op is fine.
  Command.globalExceptionHandler = (cmd, err) {};
  auth = AuthService();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: LoginPage());
  }
}

class LoginPage extends StatefulWidget {
  const LoginPage({super.key});
  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  late final Command<List<String>, void> login;
  final emailCtrl = TextEditingController();
  final pwdCtrl = TextEditingController();

  @override
  void initState() {
    super.initState();
    login = Command.createAsyncNoResult<List<String>>(
      (args) => auth.login(args[0], args[1]),
    );
  }

  Future<void> _submit() async {
    // ✨ Span: `command_it login`
    //
    //    Carries `command.name=login`, `command.result=success` or
    //    `error`, and on failure `error.type` plus the exception
    //    recorded on the span. Duration is exactly the awaited
    //    Future.
    try {
      await login.runAsyncTraced(
        [emailCtrl.text, pwdCtrl.text],
        'login',
      );
      if (mounted) Navigator.of(context).pushReplacementNamed('/home');
    } catch (_) {
      // Stay on this screen; the span already captured the error.
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Sign in')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(controller: emailCtrl,
              decoration: const InputDecoration(labelText: 'Email')),
            TextField(controller: pwdCtrl, obscureText: true,
              decoration: const InputDecoration(labelText: 'Password')),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _submit,
              child: const Text('Sign in'),
            ),
          ],
        ),
      ),
    );
  }
}

What you'll see #

command_it login
  command.name = login
  command.system = command_it
  command.result = error
  error.type = StateError
  status = Error  (description: "Bad state: password too short")

…or on success:

command_it login
  command.name = login
  command.system = command_it
  command.result = success
  status = Unset  (no error)

Trace duration is exactly the auth.login Future, so if a login suddenly gets slower, this is where you see it.

0
likes
160
points
99
downloads

Documentation

API reference

Publisher

verified publisherdartastic.io

Weekly Downloads

OpenTelemetry instrumentation for package:command_it (Thomas Burkhart's renamed flutter_command). Wraps each Command execution in a CLIENT-kind span with duration and failures.

Homepage
Repository (GitHub)
View/report issues

License

Apache-2.0 (license)

Dependencies

command_it, dartastic_opentelemetry, dartastic_opentelemetry_api, flutter

More

Packages that depend on otel_command_it