closeyourit 0.1.0
closeyourit: ^0.1.0 copied to clipboard
Client Dart/Flutter per CloseYourIt — errori, metriche e logs verso il backend di osservabilità interno.
closeyourit #
Client Dart/Flutter per CloseYourIt — il backend di osservabilità interno. Specchio del gem
closeyourit-ruby: cattura errori, metriche e
logs delle app Flutter e li invia a CloseYourIt, fire-and-forget (non rallenta né crasha l'app).
Status: in sviluppo (v0.1.0). API non ancora stabile.
Cosa fa #
- Errori — cattura automatica delle eccezioni non gestite (
FlutterError.onError,PlatformDispatcher.onError, zone) +captureException/captureMessagemanuali. - Scope & breadcrumbs — user, tag, context,
trace_ide cronologia eventi allegati a ogni evento. - Metriche —
measure()per il timing dei blocchi (slow_method). - Logs —
CloseYourIt.log/CloseYourIt.loggercon batching e correlazionetrace_id. - Integrazioni — interceptor Dio, observer go_router/Navigator, scrubbing PII di default.
Installazione #
dependencies:
closeyourit:
git: https://github.com/bussolabs/closeyourit-dart
Quick start #
import 'package:closeyourit/closeyourit.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await CloseYourIt.init(
CloseYourItOptions(
endpointUrl: const String.fromEnvironment('CLOSEYOURIT_ENDPOINT_URL'),
token: const String.fromEnvironment('CLOSEYOURIT_TOKEN'),
projectId: const String.fromEnvironment('CLOSEYOURIT_PROJECT_ID'),
environment: const String.fromEnvironment('CLOSEYOURIT_ENVIRONMENT', defaultValue: 'development'),
release: const String.fromEnvironment('CLOSEYOURIT_RELEASE'),
),
appRunner: () => runApp(const MyApp()),
);
}
appRunner avvia l'app dentro una zona protetta e installa i gestori globali degli errori: ogni
crash non gestito viene catturato in automatico. I valori CLOSEYOURIT_* arrivano via --dart-define
dal Doppler {app}-flutter di ogni app consumer — mai hardcodati.
Errori e messaggi #
CloseYourIt.captureException(error, stackTrace: st, handled: true);
CloseYourIt.captureMessage('cache miss', level: 'warning');
Scope e breadcrumbs #
CloseYourIt.setUser(id: account.id); // senza sendPii viene inviato solo l'id
CloseYourIt.setTag('tenant', 'acme');
CloseYourIt.setContext('billing', {'plan': 'pro'});
CloseYourIt.setTraceId(requestId); // correla log ↔ errori ↔ metriche
CloseYourIt.addBreadcrumb(message: 'checkout aperto', category: 'ui');
CloseYourIt.configureScope((s) => s.setTag('area', 'checkout'));
Logs #
CloseYourIt.log(LogLevel.info, 'ordine creato', attributes: {'order_id': 1});
CloseYourIt.logger.warn('retry', attributes: {'attempt': 3}); // warn → warning
I log sono bufferizzati e inviati in batch (default 50 voci o ogni 5s, e su pausa app). Gli
attributes con chiavi sensibili (password, token, authorization, card…) sono redatti.
Metriche #
final result = await CloseYourIt.measure('checkout.total', () async {
return await expensiveWork();
});
Se la durata supera slowMethodThresholdMs (default 200ms) viene inviata una metrica slow_method.
Interceptor Dio #
final dio = Dio()..interceptors.add(CloseYourItDioInterceptor());
Le richieste diventano breadcrumb; gli errori 5xx vengono catturati come eccezioni. Gli header
sensibili (Authorization, Cookie…) non vengono mai inviati.
Navigazione #
MaterialApp(
navigatorObservers: [CloseYourItNavigatorObserver()],
// ...
);
Privacy #
sendPii è false di default: niente email/IP/username. Tutti i payload passano per uno scrubber
PII, e puoi aggiungere un hook beforeSend per modificare o scartare (return null) ogni evento.
Wire contract #
POST {endpointUrl}/api/v1/projects/{projectId}/{events,metrics,logs} con header
Authorization: Bearer cyi_…. Risposta 202 {data:…}. Vedi BUILD.md per i dettagli.
Diagnostica #
CloseYourIt.stats; // { enqueued, dropped, sent, failed }
await CloseYourIt.flush(); // forza l'invio (es. prima di un test)
await CloseYourIt.close(); // shutdown
Licenza #
MIT — vedi LICENSE.