Skip to content
Permalink
Browse files
feat: datadog RUM implementation (DEV-50) (#546)
* feat: datadog RUM implementation

* test(login-form): fixes tests

* refactor(login-form): adds and uses config token properties for datadog init
  • Loading branch information
mdelez committed Oct 14, 2021
1 parent 77d8a1f commit ec59ee5b8ac1bd7d95cefab09c91e1383c990a0a

Some generated files are not rendered by default. Learn more.

@@ -18,7 +18,7 @@
"test-local": "ng test",
"test-e2e-protractor": "ng e2e --prod=true --protractor-config=./e2e/protractor-ci.conf.js --webdriver-update=false",
"webdriver-update": "webdriver-manager update --standalone false --gecko false --versions.chrome 2.37",
"yalc-add-lib": "rm -rf .yalc/@dasch-swiss && yalc add @dasch-swiss/dsp-js && npm install"
"yalc-add-lib": "rm -rf .yalc/@dasch-swiss && yalc add @dasch-swiss/dsp-js && yalc add @dasch-swiss/dsp-ui && npm install"
},
"private": true,
"dependencies": {
@@ -34,6 +34,7 @@
"@angular/router": "^11.2.9",
"@ckeditor/ckeditor5-angular": "^1.2.3",
"@dasch-swiss/dsp-js": "^4.1.0",
"@datadog/browser-rum": "^3.6.3",
"@ngx-translate/core": "^12.1.2",
"@ngx-translate/http-loader": "5.0.0",
"3d-force-graph": "^1.60.12",
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { KnoraApiConfig } from '@dasch-swiss/dsp-js';
import { DspDataDogConfig } from './main/declarations/dsp-dataDog-config';
import { DspIiifConfig } from './main/declarations/dsp-iiif-config';

@Injectable({
@@ -9,6 +10,7 @@ export class AppInitService {

dspApiConfig: KnoraApiConfig;
dspIiifConfig: DspIiifConfig;
dspDatadogConfig: DspDataDogConfig;

config: object;

@@ -29,7 +31,7 @@ export class AppInitService {


// check for presence of apiProtocol and apiHost
if (typeof dspAppConfig.apiProtocol !== 'string' || typeof dspAppConfig.apiHost !== 'string') {
if (typeof dspAppConfig.apiProtocol !== 'string' || typeof dspAppConfig.apiHost !== 'string') {
throw new Error('config misses required members: apiProtocol and/or apiHost');
}

@@ -60,6 +62,15 @@ export class AppInitService {
iiifPath
);

// init datadog configuration
this.dspDatadogConfig = new DspDataDogConfig(
dspAppConfig.dataDogLogging,
dspAppConfig.dataDogApplicationId,
dspAppConfig.dataDogClientToken,
dspAppConfig.dataDogSite,
dspAppConfig.dataDogService,
);

// get all options from config
this.config = dspAppConfig;

@@ -75,6 +86,11 @@ export class AppInitService {
this.config['iiifPort'] = iiifPort;
this.config['iiifPath'] = iiifPath;
this.config['iiifUrl'] = this.dspIiifConfig.iiifUrl;
this.config['dataDogLogging'] = this.dspDatadogConfig.dataDogLogging;
this.config['dataDogApplicationId'] = this.dspDatadogConfig.dataDogApplicationId;
this.config['dataDogClientToken'] = this.dspDatadogConfig.dataDogClientToken;
this.config['dataDogSite'] = this.dspDatadogConfig.dataDogSite;
this.config['dataDogService'] = this.dspDatadogConfig.dataDogService;

resolve();
}
@@ -26,7 +26,7 @@ import { SelectedResourcesComponent } from './main/action/selected-resources/sel
import { SortButtonComponent } from './main/action/sort-button/sort-button.component';
import { StringLiteralInputComponent } from './main/action/string-literal-input/string-literal-input.component';
import { CookiePolicyComponent } from './main/cookie-policy/cookie-policy.component';
import { DspApiConfigToken, DspApiConnectionToken } from './main/declarations/dsp-api-tokens';
import { DspApiConfigToken, DspApiConnectionToken, DspDataDogConfigToken } from './main/declarations/dsp-api-tokens';
import { DialogHeaderComponent } from './main/dialog/dialog-header/dialog-header.component';
import { DialogComponent } from './main/dialog/dialog.component';
import { AdminImageDirective } from './main/directive/admin-image/admin-image.directive';
@@ -348,6 +348,11 @@ export function httpLoaderFactory(httpClient: HttpClient) {
useFactory: (appInitService: AppInitService) => appInitService.dspApiConfig,
deps: [AppInitService]
},
{
provide: DspDataDogConfigToken,
useFactory: (appInitService: AppInitService) => appInitService.dspDatadogConfig,
deps: [AppInitService]
},
{
provide: DspApiConnectionToken,
useFactory: (appInitService: AppInitService) => new KnoraApiConnection(appInitService.dspApiConfig),
@@ -7,14 +7,16 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
ApiResponseData,
AuthenticationEndpointV2,
KnoraApiConfig,
LoginResponse,
LogoutResponse,
MockUsers,
UsersEndpointAdmin
} from '@dasch-swiss/dsp-js';
import { of } from 'rxjs';
import { AjaxResponse } from 'rxjs/ajax';
import { DspApiConnectionToken } from '../../declarations/dsp-api-tokens';
import { DspApiConfigToken, DspApiConnectionToken, DspDataDogConfigToken } from '../../declarations/dsp-api-tokens';
import { DspDataDogConfig } from '../../declarations/dsp-dataDog-config';
import { Session, SessionService } from '../../services/session.service';
import { LoginFormComponent } from './login-form.component';

@@ -54,6 +56,10 @@ describe('LoginFormComponent', () => {
let sessionService: SessionService;

beforeEach(waitForAsync(() => {
const dspConfSpy = new KnoraApiConfig('http', 'localhost', 3333, undefined, undefined, true);

const dspDatadogSpy = new DspDataDogConfig(false, '', '', '', '');

const dspConnSpy = {
admin: {
usersEndpoint: jasmine.createSpyObj('usersEndpoint', ['getUser'])
@@ -74,6 +80,14 @@ describe('LoginFormComponent', () => {
provide: DspApiConnectionToken,
useValue: dspConnSpy
},
{
provide: DspApiConfigToken,
useValue: dspConfSpy
},
{
provide: DspDataDogConfigToken,
useValue: dspDatadogSpy
},
FormBuilder,
SessionService
],
@@ -1,7 +1,10 @@
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
import { inject } from '@angular/core/testing';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ApiResponseData, ApiResponseError, KnoraApiConnection, LoginResponse, LogoutResponse } from '@dasch-swiss/dsp-js';
import { DspApiConnectionToken } from '../../declarations/dsp-api-tokens';
import { ApiResponseData, ApiResponseError, KnoraApiConfig, KnoraApiConnection, LoginResponse, LogoutResponse } from '@dasch-swiss/dsp-js';
import { datadogRum, RumFetchResourceEventDomainContext } from '@datadog/browser-rum';
import { DspApiConfigToken, DspApiConnectionToken, DspDataDogConfigToken } from '../../declarations/dsp-api-tokens';
import { DspDataDogConfig } from '../../declarations/dsp-dataDog-config';
import { NotificationService } from '../../services/notification.service';
import { Session, SessionService } from '../../services/session.service';

@@ -101,6 +104,8 @@ export class LoginFormComponent implements OnInit {

constructor(
@Inject(DspApiConnectionToken) private _dspApiConnection: KnoraApiConnection,
@Inject(DspApiConfigToken) private _dspApiConfig: KnoraApiConfig,
@Inject(DspDataDogConfigToken) private _dspDataDogConfig: DspDataDogConfig,
private _notification: NotificationService,
private _sessionService: SessionService,
private _fb: FormBuilder
@@ -151,6 +156,29 @@ export class LoginFormComponent implements OnInit {
this.session = this._sessionService.getSession();
this.loginSuccess.emit(true);
this.loading = false;
if (this._dspDataDogConfig.dataDogLogging) {
datadogRum.init({
applicationId: this._dspDataDogConfig.dataDogApplicationId,
clientToken: this._dspDataDogConfig.dataDogClientToken,
site: this._dspDataDogConfig.dataDogSite,
service: this._dspDataDogConfig.dataDogService,
// specify a version number to identify the deployed version of your application in Datadog
// version: '1.0.0',
sampleRate: 100,
trackInteractions: true,
beforeSend: (event, context) => {
// collect a RUM resource's response headers
if (event.type === 'resource' && event.resource.type === 'xhr') {
event.context = { ...event.context, responseHeaders: (context as RumFetchResourceEventDomainContext).response.body };
}
},
});

datadogRum.setUser({
id: identifier,
identifierType: identifierType
});
}
}
);
},
@@ -1,8 +1,12 @@
import { InjectionToken } from '@angular/core';
import { KnoraApiConfig, KnoraApiConnection } from '@dasch-swiss/dsp-js';
import { DspDataDogConfig } from './dsp-dataDog-config';

// config for dsp-js-lib (@dasch-swiss/dsp-js) config object
export const DspApiConfigToken = new InjectionToken<KnoraApiConfig>('DSP api configuration');

// connection config for dsp-js-lib (@dasch-swiss/dsp-js) connection
export const DspApiConnectionToken = new InjectionToken<KnoraApiConnection>('DSP api connection instance');

// config for datadog
export const DspDataDogConfigToken = new InjectionToken<DspDataDogConfig>('DSP DataDog configuration');
@@ -0,0 +1,7 @@
export class DspDataDogConfig {
constructor(public dataDogLogging: boolean,
public dataDogApplicationId: string,
public dataDogClientToken: string,
public dataDogSite: string,
public dataDogService: string) { }
}
@@ -1,13 +1,18 @@
{
"apiProtocol": "http",
"apiHost": "0.0.0.0",
"apiPort": 3333,
"apiPath": "",
"iiifProtocol": "http",
"iiifHost": "0.0.0.0",
"iiifPort": 1024,
"iiifPath": "",
"geonameToken": "knora",
"jsonWebToken": "",
"logErrors": true
"apiProtocol": "http",
"apiHost": "0.0.0.0",
"apiPort": 3333,
"apiPath": "",
"iiifProtocol": "http",
"iiifHost": "0.0.0.0",
"iiifPort": 1024,
"iiifPath": "",
"geonameToken": "knora",
"jsonWebToken": "",
"logErrors": true,
"dataDogLogging": false,
"dataDogApplicationId": "",
"dataDogClientToken": "",
"dataDogSite": "",
"dataDogService": ""
}
@@ -9,5 +9,10 @@
"iiifPath": "",
"geonameToken": "knora",
"jsonWebToken": "",
"logErrors": false
"logErrors": false,
"dataDogLogging": false,
"dataDogApplicationId": "",
"dataDogClientToken": "",
"dataDogSite": "",
"dataDogService": ""
}
Loading

0 comments on commit ec59ee5

Please sign in to comment.