Skip to main content
BetterstackExceptionLogger is the Logger component’s Better Stack error-tracking backend. It wraps the official @sentry/node SDK to capture exceptions (with their tags, contexts, breadcrumbs, and extra data) and ship them, along with structured logs, to Better Stack’s Sentry-compatible ingest. It implements the framework’s ILogger interface, so call sites stay provider-agnostic and you can swap the backend without touching the code that emits errors.

What this backend does

Errors go through Sentry with tags, contexts, and breadcrumbs attached, so you get the detail you need to debug. Pass an IException to error() and its name, status, date, and structured stack trace are attached for you. The other levels (warn, info, debug, log, and success) ship as Sentry logs alongside the exceptions. Since it reuses the Sentry SDK against a Better Stack DSN, your existing Sentry tooling still applies. Delivery is buffered, and flush() drains pending events before the process exits. The class registers with @decorator.logger() and resolves from the container.

Installation

BetterstackExceptionLogger ships with @talosjs/logger and depends on the Sentry Node SDK.

Environment variables

Both values are validated when BetterstackExceptionLogger is constructed, so misconfiguration fails fast at startup.

How it works

On construction, the backend calls Sentry.init() with a DSN assembled from your application token and ingesting host, enabling logs and full trace sampling. error() opens a Sentry scope. A string message is captured as an Error with a breadcrumb (and your data as extras), while an IException is captured with exception.name/exception.status tags, an exception context (name, status, date, stack), a breadcrumb, and your data as extras. The remaining levels ship as Sentry logs: warn, info, and debug map directly, and log/success use info with a level field (LOG / SUCCESS). Delivery is buffered, so flush() waits up to two seconds to drain it.

Usage

error() accepts a plain message or an IException. Given an exception, it attaches the name, status, date, and structured stack trace:
Inject it into a service to capture errors as part of your domain logic:

Use in the app

In an @talosjs/app application, register BetterstackExceptionLogger on the onException slot of your App config. Unlike the general loggers array, onException of AppConfigType is typed as a single LoggerClassType. It’s the dedicated slot for the backend that handles uncaught exceptions: the framework registers it with the container and routes exceptions to it at startup.
Here loggers handles your normal application logs while onException sends uncaught exceptions to Better Stack. The two slots are independent, so you can keep terminal output in development and still capture exceptions remotely. Set BETTERSTACK_EXCEPTION_LOGGER_APPLICATION_TOKEN and BETTERSTACK_EXCEPTION_LOGGER_INGESTING_HOST in your .env.yml (or environment) so the SDK can initialize. You can also inject the logger directly to capture handled errors inside your domain logic:
Because delivery is buffered, flush before the process exits, for example from a shutdown hook:

Exceptions

BetterstackExceptionLogger throws LoggerException on misconfiguration, carrying a machine-readable key.

Getting the most out of it

Call flush() on exit. Delivery is buffered, so drain it before the process terminates or you’ll drop the last events. Pass the IException to error() rather than a string, so its name, status, date, and stack trace are captured as Sentry context. Identifiers like an order id or user id belong in the data argument, where they land as Sentry extras you can search on. Keep the token and host in the environment, loaded from .env, and never hard-code them. This backend is meant for error tracking; for general structured log shipping, pair it with Better Stack Logger. See the Logger component for the provider interface and how logs flow through the framework.