@allstak/angular
v0.2.0
Published
Official AllStak SDK for Angular — error tracking, structured logs, distributed tracing, and observability for Angular applications.
Maintainers
Readme
@allstak/angular
Official AllStak SDK for Angular. Captures uncaught exceptions, structured logs, navigation spans, outbound HTTP requests, and component render timing — with first-class support for both standalone and NgModule-based apps.
Install
npm install @allstak/angular
# or
pnpm add @allstak/angular
# or
yarn add @allstak/angular@angular/core, @angular/common, and rxjs are peer dependencies; @angular/router is an optional peer (only needed for navigation instrumentation).
Setup
Initialise the SDK once in main.ts, before you bootstrap the app, so the global error handler and router instrumentation see a live client:
import { init } from '@allstak/angular';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
init({
apiKey: 'your-ingest-key',
environment: 'production',
});
bootstrapApplication(AppComponent, appConfig);Standalone apps (provider functions)
Wire the DI pieces in app.config.ts:
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import {
provideAllStak,
provideAllStakErrorHandler,
provideAllStakRouterInstrumentation,
allStakHttpInterceptor,
} from '@allstak/angular';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
// Bootstrap the SDK from DI (alternative to calling init() in main.ts).
provideAllStak({ apiKey: 'your-ingest-key', environment: 'production' }),
// Override Angular's global ErrorHandler — every uncaught error becomes an Issue.
provideAllStakErrorHandler(),
// Open a navigation span per route change.
provideAllStakRouterInstrumentation(),
// Record every outbound HTTP request + open a http.client span.
provideHttpClient(withInterceptors([allStakHttpInterceptor])),
],
};NgModule apps
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { AllStakModule, AllStakHttpInterceptor } from '@allstak/angular';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
// forRoot() initialises the SDK, overrides ErrorHandler, force-instantiates
// the router TraceService, and exposes the [trace] directive.
AllStakModule.forRoot({ apiKey: 'your-ingest-key', environment: 'production' }),
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
{ provide: HTTP_INTERCEPTORS, useClass: AllStakHttpInterceptor, multi: true },
],
bootstrap: [AppComponent],
})
export class AppModule {}Error handling
createErrorHandler() returns an Angular ErrorHandler that forwards to AllStak.captureException. It unwraps the common Angular/zone.js error envelopes (ngOriginalError, promise rejection, HttpErrorResponse.error, ErrorEvent.error) before capture.
import { ErrorHandler } from '@angular/core';
import { createErrorHandler } from '@allstak/angular';
providers: [
{
provide: ErrorHandler,
useValue: createErrorHandler({
logErrors: true, // also console.error the original (default)
extractor: (error, defaultExtractor) =>
(error as { cause?: unknown }).cause ?? defaultExtractor(error),
}),
},
];Router instrumentation
TraceService subscribes to Angular Router events and opens a navigation span per route change (finishing ok on NavigationEnd, error on NavigationCancel / NavigationError), plus a navigation breadcrumb. It must be force-instantiated — provideAllStakRouterInstrumentation() (standalone) or AllStakModule.forRoot() (NgModule) does that for you.
Component render timing
The [trace] directive opens a ui.angular.init span between a component's ngOnInit and ngAfterViewInit. Import TraceDirective directly (standalone) or AllStakTraceModule (NgModule):
// standalone component
import { Component } from '@angular/core';
import { TraceDirective } from '@allstak/angular';
@Component({
standalone: true,
imports: [TraceDirective],
template: `<section trace="dashboard">…</section>`,
})
export class DashboardComponent {}You can also instrument classes/methods with the decorators (the name is required so spans survive minification):
import { TraceClassDecorator, TraceMethodDecorator } from '@allstak/angular';
@TraceClassDecorator({ name: 'CheckoutComponent' })
@Component({ /* … */ })
export class CheckoutComponent {
@TraceMethodDecorator({ name: 'CheckoutComponent.ngOnInit' })
ngOnInit() {}
}HTTP instrumentation
The interceptor records every outbound request as an outbound HTTP item and opens a http.client span around it (finished error on 4xx/5xx or transport failure). Use the functional allStakHttpInterceptor with withInterceptors([...]) or the class AllStakHttpInterceptor with HTTP_INTERCEPTORS. It never mutates the request.
Configuration
init(config), provideAllStak(config), and AllStakModule.forRoot(config) all accept every option that @allstak/js's AllStak.init accepts. Common options:
| Option | Purpose |
|---|---|
| apiKey | Ingest key (required) |
| host | Override the ingest host |
| environment | e.g. 'production' / 'development' |
| release | Release identifier for issue grouping / release health |
| tracesSampleRate | Span sampling rate (0–1) |
| enableWebVitals | Capture web vitals |
| enableAutoSessionTracking | Release-health sessions |
| enableOfflineQueue | Buffer events while offline |
| beforeSend | Mutate/drop events before they are sent |
The full @allstak/js API is re-exported, so you can pull the entire observability surface from one import:
import * as AllStakAngular from '@allstak/angular';
AllStakAngular.AllStak.captureMessage('checkout started', 'info');
const span = AllStakAngular.AllStak.startSpan('checkout.flow', { description: 'review → pay' });
span.finish('ok');License
MIT
