talaria 0.2.3 copy "talaria: ^0.2.3" to clipboard
talaria: ^0.2.3 copied to clipboard

Official Dart SDK for Talaria — capture exceptions and logs into triageable issues.

talaria #

pub package license: MIT

Official Dart SDK for Talaria — capture exceptions and application logs into triageable issues, with optional APM spans.

Events queue in memory and flush on batch size, max age, or flush / close. Fingerprinting stays on the server. A permanent ingest error (retry: false, such as an invalid API key) stops further event and span sends for this process; quota and 5xx do not.

Docs: Dart SDK · Flutter · Serverpod · Dashboard

Install #

dependencies:
  talaria: ^0.2.3

Building a Flutter app? Use talaria_flutter instead — it re-exports this package and installs framework hooks. Building a Serverpod 4 server? Add talaria_serverpod for endpoint, database, and FutureCall tracing.

Initialize #

Create a client key under Project settings → Client keys (tal_live_…). Default keys include eventsWrite and spansWrite.

import 'package:talaria/talaria.dart';

await Talaria.init(TalariaOptions(
  dsn: 'https://api.newtalaria.com',
  apiKey: const String.fromEnvironment('TALARIA_API_KEY'),
  environment: 'production', // staging | development also accepted
  release: '1.4.2',
  commitSha: const String.fromEnvironment('TALARIA_COMMIT_SHA'),
  minLevel: SeverityLevel.warning,
  tags: {
    'service': 'api',
    'platform': 'dart',
  },
));

Prefer runZonedTalaria (or talaria_flutter) so uncaught errors are captured:

final client = await Talaria.init(/* … */);
runZonedTalaria(client, () {
  // your app entry
});

Never hardcode keys. Prefer --dart-define, environment variables, or your secret store.

Capture exceptions #

try {
  await charge();
} catch (error, stackTrace) {
  await Talaria.captureException(
    error,
    stackTrace: stackTrace,
    context: CaptureContext(
      tags: {'feature': 'checkout', 'component': 'payments'},
      extra: {'cart_id': 'cart_01H…'},
    ),
  );
  rethrow;
}

captureException always sends severity error. captureMessage defaults to info.

Scoped logging #

Prefer a scoped logger in application code. Level methods wrap captureMessage; use captureException for errors.

final logger = Talaria.logger(tags: {
  'feature': 'checkout',
  'operation': 'pay',
});

await logger.info('Checkout opened'); // filtered if minLevel is warning
await logger.warn('Payment method missing');

try {
  await charge();
} catch (e, st) {
  await logger.captureException(e, stackTrace: st, context: CaptureContext(
    tags: {'component': 'stripe'},
    extra: {'cart_id': 'abc123'},
  ));
  rethrow;
}

// Child scopes inherit tags. Assigned minLevel may raise or lower the floor
// unless enforceDefaultLevel is true.
final payments = logger.child(
  tags: {'component': 'payments'},
  minLevel: SeverityLevel.error,
);
await payments.error('Charge failed');
Method Severity sent
debug / info / warning / error / fatal same name
warn warning
log(level, message) mapped severity
captureException error

Tags vs extra #

  • tags — low-cardinality filters (feature, operation, component). These become dashboard facets.
  • extra — high-cardinality diagnostics (cart_id, payloads). Do not put unique ids in tags.

Level hierarchy #

Client minLevel is the default/root. A scoped logger may assign a different floor (more or less verbose). Set enforceDefaultLevel: true to restore a hard floor (max(root, scope)).

Gates run in order. Filtered calls are quiet no-ops.

  1. minLevel — default/root severity
  2. sampleRate — fraction of eligible events to enqueue (not traces)
  3. beforeSend — return null to drop, or a mutated event
await Talaria.init(TalariaOptions(
  dsn: 'https://api.newtalaria.com',
  apiKey: 'tal_live_…',
  environment: 'production',
  minLevel: SeverityLevel.warning,
  ignoreErrors: [RegExp(r'SocketException')],
  ignoreUrls: ['/health'],
  beforeSend: (event, hint) {
    if (event.message.toLowerCase().contains('password')) return null;
    return event;
  },
  loggers: {
    'checkout': LoggerPreset(
      minLevel: SeverityLevel.info,
      tags: {'area': 'checkout'},
    ),
  },
));

User and request context #

Talaria.getClient()?.setUser('user_01H…');
Talaria.addProcessor((bag) {
  return {
    ...bag,
    'url': currentRequestUrl,
    'requestId': currentRequestId,
  };
});

setTags / setExtra / setUser live on TalariaClient for mutable global context after init.

A ring buffer of 50 breadcrumbs is attached on error events, with traceId / spanId when a span is in scope.

Talaria.addBreadcrumb(Breadcrumb(
  type: 'user',
  category: 'ui',
  message: 'Tapped Pay',
));

Tracing (APM) #

Tracing is off until you set enableTracing: true or tracesSampleRate > 0. Successful transactions default to a 10% sample; error transactions are always sent. Child spans are not billed — only sampled root transactions.

await Talaria.init(TalariaOptions(
  dsn: 'https://api.newtalaria.com',
  apiKey: 'tal_live_…',
  environment: 'production',
  enableTracing: true, // 10% of successful transactions
  // tracesSampleRate: 0.25, // also enables tracing
));

final txn = Talaria.startTransaction('checkout');
try {
  final child = Talaria.startSpan('charge', kind: SpanKind.client);
  try {
    await charge();
    child.setStatus(SpanStatus.ok);
  } finally {
    child.finish();
  }
} catch (e, st) {
  txn.markError(message: e.toString());
  await Talaria.captureException(e, stackTrace: st);
  rethrow;
} finally {
  txn.finish();
}
API Role
startTransaction New trace root. Optional W3C Traceparent parent for distributed continuation.
startSpan Child of the current span (or a new root if none).
SpanKind internal, server, client, producer, consumer
SpanStatus unset, ok, error
markError Marks the span and force-samples the trace

A trace holds at most 200 spans; further startSpan calls return a no-op. When tracing is off, both APIs return NoOpSpan.

Spans POST to /spans/ingestBatch. Events stay on /events/ingestBatch.

Outbound HTTP #

Wrap application package:http clients. Never wrap the ingest client used by HttpTransport.

final httpClient = Talaria.wrapHttpClient(http.Client());
final response = await httpClient.get(Uri.parse('https://api.partner.dev/v1/pay'));

This starts a client span, injects W3C traceparent, and records an HTTP breadcrumb. Talaria ingest URLs are skipped if wrapped by mistake. Talaria.getTraceparent() returns the active header when a span is recording.

There is no talaria_dio package. For Dio, wrap the adapter's http.Client with TalariaHttpClient, or add an interceptor that calls Talaria.startSpan and injects traceparent.

SQL helpers (SqlSanitizer, DbSpan) and concurrent SpanScope live in this package for servers that wrap their own stores. Flutter and Serverpod adapters call them for you.

Shutdown #

await Talaria.flush();
await Talaria.close();

Call this from process shutdown (and Serverpod / isolate teardown) so the last batch leaves the queue.

What this package does not do #

  • Fingerprints — computed on the server
  • Session replay or native crash dumps
  • Host / Kubernetes metrics or continuous profiling
  • Automatic Flutter or Serverpod hooks — use the adapter packages

License #

MIT

0
likes
0
points
1.29k
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Official Dart SDK for Talaria — capture exceptions and logs into triageable issues.

Homepage
Repository (GitHub)
View/report issues

Topics

#error-tracking #logging #observability #tracing #apm

License

unknown (license)

Dependencies

http, meta, stack_trace

More

Packages that depend on talaria