OpenTelemetry Angular Interceptor
@jufab/opentelemetry-angular-interceptor is an Angular Library to deploy OpenTelemetry in your Angular application
This library uses opentelemetry-js package
Only works for Angular >= 9.0.0
More info : https://jufab.github.io/opentelemetry-angular-interceptor/
Table of contents
- OpenTelemetry Angular Interceptor
Getting started
Installation
With npm :
npm install @jufab/opentelemetry-angular-interceptor @opentelemetry/web @opentelemetry/exporter-collector @opentelemetry/exporter-zipkin @opentelemetry/propagator-jaeger @opentelemetry/propagator-b3
Configuration
Use the "OpentelemetryConfig" interface to configure the Tracer
export interface OpenTelemetryConfig {
commonConfig: CommonCollectorConfig;
otelcolConfig?: OtelCollectorConfig;
jaegerPropagatorConfig?: JaegerPropagatorConfig;
zipkinConfig?: ZipkinCollectorConfig;
b3PropagatorConfig?: B3PropagatorConfig;
}
Example global Configuration
From the example-app
opentelemetryConfig: {
commonConfig: {
console: true, //(boolean) Display trace on console
production: false, //(boolean) Send trace with BatchSpanProcessor (true) or SimpleSpanProcessor (false) more info : https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-api#tracing
logBody: true, //(boolean) true add body in a log, nothing otherwise
serviceName: 'example-app', //Service name send in trace
probabilitySampler: '0.7', //Samples a configurable percentage of traces, string value between '0' to '1'
logLevel:DiagLogLevel.ALL //(Enum) DiagLogLevel is an Enum from @opentelemetry/api
},
otelcolConfig: {
url: 'http://localhost:55681/v1/trace', //URL of opentelemetry collector
},
jaegerPropagatorConfig: {
customHeader: 'custom-header',
}
}
Common Configuration
- console: (boolean) Display trace on console if true
- production: (boolean)Send trace via BatchSpanProcessor (Async) or SimpleSpanProcessor (Sync) : It's recommend to use BatchSpanProcessor on Production.
- serviceName: (string) Service name in your trace
- probabilitySampler: (string) Samples a configurable percentage of traces, value between 0 to 1
- logBody: (boolean) true add body in a log, nothing otherwise
- logLevel: (DiagLogLevel) log level
OpenTelemetry-collector Configuration
- url: (string) url of opentelemetry collector (default : http://localhost:55681/v1/trace)
- headers: list of custom header (more info: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-exporter-collector)
- attributes : list of custom attributes (more info : https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-exporter-collector)
Jaeger Propagator Configuration
- customHeader: (string) custom header (more info : https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/propagators/opentelemetry-propagator-jaeger)
Zipkin Exporter Configuration
- url: (string) url of zipkin collector (default : http://localhost:9411/api/v2/spans)
- headers: list of custom header (more info : https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-exporter-zipkin)
B3 Propagator Configuration
- multiHeader : (string) Single or Multi Header for b3propagator (default: multi). Value : 'O' (single), '1' (multi) (more info: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-propagator-b3)
Angular module
To insert OpenTelemetryInterceptorModule, you can add in your application module (generally app.module.ts)
Exporter module
There is 3 exporters:
- OtelColExporterModule : OpenTelemetry exporter (more info : https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-exporter-collector)
- ConsoleSpanExporterModule : Console Exporter
- ZipkinExporterModule : Zipkin Exporter (more info : https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-exporter-zipkin)
Propagator module
there is 5 propagators (more info about propagator: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-core)
- NoopHttpTextPropagatorModule : This is a fake propagator
- B3PropagatorModule : Use B3 propagator
- HttpTraceContextPropagatorModule : Use HttpTraceContext propagator
- JaegerHttpTracePropagatorModule : Use JaegerHttpPropagator (more info about this one: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/propagators/opentelemetry-propagator-jaeger)
- CompositePropagatorModule : use all of the propagator
import { NgModule } from '@angular/core';
...
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { OpenTelemetryInterceptorModule, OtelColExporterModule, CompositePropagatorModule } from '@jufab/opentelemetry-angular-interceptor';
import { environment } from '../environments/environment';
...
@NgModule({
declarations: [AppComponent, ...],
imports: [
...
HttpClientModule,
//Insert module OpenTelemetryInterceptorModule with configuration, HttpClientModule is used for interceptor
OpenTelemetryInterceptorModule.forRoot(environment.opentelemetryConfig),
//Insert OtelCol exporter module
OtelColExporterModule,
//Insert propagator module
CompositePropagatorModule,
...
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
(Optional) Logging in OtelColExporterModule
You can add a logger to the OtelColExporterModule with the OTELCOL_LOGGER token.
You can use a custom logger which implements the DiagLogger in @opentelemetry/api.
Or, you can use an existing logger which implements the same functions (error, warn, info, debug) like ngx-logger.
NGXLogger
You can use ngx-logger.
In your appModule, insert LoggerModule and configure it
@NgModule({
...
imports: [
LoggerModule.forRoot(environment.loggerConfig),
]
...
And use OTELCOL_LOGGER token to inject NGXLogger
@NgModule({
...
providers: [
...
{ provide: OTELCOL_LOGGER, useExisting: NGXLogger }
...
]
Don't forget to set "logLevel" in Common Configuration (Level must be the same between NGXLogger and common configuration)
You can see an example in the example-app.
How it works
This library is based on HttpClientModule and the HTTP_INTERCEPTORS
OpenTelemetryInterceptor implement an HttpInterceptor and the intercept method.
This implementation initialise a WebTracerProvider, create a Span and add header propagation in the current call.
The response body is adding by an event in span.
Example
This project have an "example-app" as Angular application example.
You can see how configure and insert this module.
You can althought test opentelemetry-angular-interceptor with this application.
Run
To start this Example application, run command :
npm run start:complete-example-app
and open the application at http://localhost:4200
[Optional] Result in OpenTelemetry-collector
If you want to see the result in a collector *, there's a docker-compose available in this project.
You can start it with this command :
docker-compose -f projects/example-app/collector/docker-compose.yaml up -d
Go to the jaeger application (http://localhost:16686) to see result.
More info about the collector here : https://github.com/open-telemetry/opentelemetry-collector
* without an Agent or a Collector you can see an error in your browser about sending a "trace".
Troubleshoot
Angular 10 Warning
WARNING in xxx/fesm2015/jufab-opentelemetry-angular-interceptor.js depends on '@opentelemetry/web'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
WARNING in xxx/fesm2015/jufab-opentelemetry-angular-interceptor.js depends on '@opentelemetry/core'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
WARNING in xxx/fesm2015/jufab-opentelemetry-angular-interceptor.js depends on '@opentelemetry/tracing'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
WARNING in xxx/fesm2015/jufab-opentelemetry-angular-interceptor.js depends on '@opentelemetry/api'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
WARNING in xxx/fesm2015/jufab-opentelemetry-angular-interceptor.js depends on '@opentelemetry/exporter-collector/build/src/platform/browser'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
Add to your angular.json
"options": {
"allowedCommonJsDependencies": [
"@opentelemetry/web",
"@opentelemetry/core",
"@opentelemetry/tracing",
"@opentelemetry/api",
"@opentelemetry/exporter-collector",
"@opentelemetry/context-base",
"@opentelemetry/propagator-jaeger",
"@opentelemetry/propagator-b3"
],
Other
Error | Fix |
---|---|
error TS2694: Namespace 'NodeJS' has no exported member 'Timeout'. | Need dependence @type/node >= 12.0.2 |
error TS1086: An accessor cannot be declared in an ambient context. | Need dependence typescript >= 3.6.0 |