forge_ops_tracker 0.11.0
forge_ops_tracker: ^0.11.0 copied to clipboard
Dart error reporting client for ForgeOps. Works in any Dart VM environment (server apps, CLI tools, Flutter mobile/desktop): see README.md for why Flutter Web specifically isn't covered, and for the s [...]
Changelog #
0.11.0 - 2026-09-25 #
- A
databasespan can now carry the SQL it ran, such as a local SQLite query:span,spanAsyncandrecordSpantake optionalstatementanddbSystem(such as'sqlite') arguments. The statement is masked before it leaves the process (every string and number literal becomes?), cut at 4000 characters, and sent in the span's data asdb.statement, withdb.systemlowercased. Adb.statementput indatadirectly is masked the same way. Both are ignored on spans of any other kind.
0.10.0 - 2026-09-25 #
- Change tracking:
recordChange(kind, title, {details, environment, service, actor, url, id, occurredAt})records one change you made (a feature flag flipped, a config value changed, a migration run) so ForgeOps can show it next to the errors and slowdowns that followed.kindis one offeature_flag,config,migration,dependency,infrastructureorother(exported aschangeKinds); anything else is sent asother. The title is cut to 200 characters,environmentdefaults to the configured one, andoccurredAtto now. Queued on the event loop like an error report, so it never blocks and never throws; a failed delivery, including a 403 on a plan without change tracking, is dropped quietly.await flushChanges()before a short-lived program exits. This client sends no startup snapshot of its own.
0.9.0 #
- Trace context: an error captured inside a
trace/traceAsync(acrossawaits) now carries the trace'strace_id, and so does an error that escaped a trace and is captured afterward, which links it to errors other services reported for the same request (the two projects must be linked in ForgeOps). NewhttpSpan/httpSpanAsync(method, url, (headers) => ...)record an outgoing call as anhttpspan and hand your code a W3Ctraceparentheader naming that span, so the service being called continues the trace.trace/traceAsynctake an optionaltraceparentto continue a trace another service started (strictly parsed; a bad value starts a fresh trace), andcurrentTraceId()returns the open trace's id. Trace and span ids are W3C ids, never all zeros;TraceParentis exported. Two new options:propagateTraces(default true; false stops the header but still records the span) andtracePropagationTargets(default null, every host; otherwise host strings matched exactly or as a subdomain on a dot boundary, andRegExps matched against the host). WithtrackTracingoff a trace still has an id for errors and headers; only its spans stop being sent. Nothing instrumentsHttpClientautomatically, and errors captured outside a trace are unchanged.
0.8.0 #
- Database errors now say where to look. When an error carries the SQL behind a failed local database call (
package:sqlite3'sSqliteException.causingStatement, or sqflite's and SQLite's error text), the event carries the names of the tables and views (and any stored procedure) that SQL touched. On by default (captureSqlObjects); names are identifiers, never values. New opt-incaptureSqlStatement(default false) also sends the statement itself, with every string and number replaced by?. Each project has its own server-side setting that can stop the statement being stored regardless of this flag; the names are still kept.
0.7.1 #
- Documentation only: the README and package description now describe ForgeOps as a hosted service, link to getforgeops.net, and show the real host in the connection string example instead of a placeholder. No code changes.
0.7.0 #
- Performance percentiles: every performance sample now carries a small latency histogram alongside its count/sum/max (fixed buckets of 50, 100, 250, 500, 1000, 2500, 5000 and 10000ms, plus an overflow bucket), so ForgeOps can show an approximate p50/p95/p99 per transaction instead of only an average. No new config; this rides the existing performance tracking flag and flush interval.
0.6.0 #
- Custom metrics and infrastructure monitoring:
captureMetric(name, [value = 1])records a named business event (a purchase, a level completed) andcaptureInfrastructureMetric(name, value, {hostname})a CPU/memory/disk reading from one of your own hosts. Buffered and flushed as one batch oncemetricFlushInterval/infrastructureMetricFlushIntervalhas elapsed at a capture (no background timer, for the same reason performance monitoring has none);await flushMetrics()before a short-lived program exits. Nothing is automatic, so there is notrackMetricsflag.
0.5.0 #
- Distributed tracing:
trace/traceAsyncwrap a unit of work,span/spanAsyncadd child spans (nested viaZone, so parallel futures each parent under their own span), andrecordSpanadds one you timed yourself. A trace is sent to the new/spansendpoint only when it took at leastConfiguration.traceCaptureThreshold(one second), and is sent even if the body throws. Nothing is traced automatically (no web framework integration in this client). Delivery is the same bounded event-loop queue as error reports;await flushSpans()before a short-lived program exits. Turn it off withConfiguration.trackTracing = false.
0.4.0 #
- Performance monitoring:
recordPerformancetallies how long named work took (count, total, max) and flushes one small aggregate per transaction, for the Performance page's per-transaction table.timeTransaction/timeTransactionAsyncwrap a block and record even if it throws. Nothing is timed automatically (no web framework integration in this client). There is deliberately no background timer, since a pendingTimerwould stop a Dart CLI program from exiting on its own: a flush starts from arecordPerformancecall onceperformanceFlushIntervalhas elapsed, or from an explicitflushPerformance(), which a short-lived program or a Flutter app'sAppLifecycleState.pausedhandler should call. Turn it off withConfiguration.trackPerformance = false.
0.3.0 #
- Breadcrumbs:
addBreadcrumbrecords a small, bounded trail of recent events (30 by default, configurable viaConfiguration.maxBreadcrumbs) attached to whatever error gets reported next.addBreadcrumbis a plain global by default (the same single-flow reasoningsetUseralready documents);runWithBreadcrumbsscopes a fresh, isolated trail to one call chain viaZoneinstead, for a Dart server handling more than one request at a time on the same isolate. Never recorded automatically (no web framework built into this client to record one from); turn it off entirely withConfiguration.trackBreadcrumbs = false.
0.2.0 #
- Identify the affected user on a reported error: pass
usertocaptureException, or callsetUser/runWithUserto attach one to every subsequently reported error until changed or cleared.setUseris a plain global (correct for a single-user Flutter/CLI app);runWithUserscopes the value to one call chain via Dart'sZonemechanism instead, for a Dart server handling more than one request at a time on the same isolate. Never scrubbed by PII scrubbing.
0.1.0 #
- Initial release: works in any Dart VM environment (server apps, CLI tools, Flutter
mobile/desktop) via
dart:io/dart:convert, zero runtime dependencies. PII scrubbing (email addresses, formatted SSNs/credit cards, known API key/token formats, and any field whose name suggests a secret) runs before a payload ever leaves the host app's process. Delivery runs on an async drain loop with a bounded queue and short HTTP timeouts; every failure mode is caught and dropped rather than thrown, so a broken or unreachable tracker can never take down the host app. See the separateflutter_forge_ops_trackerpackage for Flutter-specific automatic capture (FlutterError.onError/PlatformDispatcher.onError) on top of this one.