Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: datadog RUM implementation (DEV-50) #546

Merged
merged 6 commits into from Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 91 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -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": {
Expand All @@ -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",
Expand Down
18 changes: 17 additions & 1 deletion src/app/app-init.service.ts
@@ -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({
Expand All @@ -9,6 +10,7 @@ export class AppInitService {

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

config: object;

Expand All @@ -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');
}

Expand Down Expand Up @@ -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;

Expand All @@ -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();
}
Expand Down
7 changes: 6 additions & 1 deletion src/app/app.module.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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),
Expand Down
16 changes: 15 additions & 1 deletion src/app/main/action/login-form/login-form.component.spec.ts
Expand Up @@ -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';

Expand Down Expand Up @@ -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'])
Expand All @@ -74,6 +80,14 @@ describe('LoginFormComponent', () => {
provide: DspApiConnectionToken,
useValue: dspConnSpy
},
{
provide: DspApiConfigToken,
useValue: dspConfSpy
},
{
provide: DspDataDogConfigToken,
useValue: dspDatadogSpy
},
FormBuilder,
SessionService
],
Expand Down
32 changes: 30 additions & 2 deletions src/app/main/action/login-form/login-form.component.ts
@@ -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';

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
});
}
}
);
},
Expand Down
4 changes: 4 additions & 0 deletions src/app/main/declarations/dsp-api-tokens.ts
@@ -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');
7 changes: 7 additions & 0 deletions src/app/main/declarations/dsp-dataDog-config.ts
@@ -0,0 +1,7 @@
export class DspDataDogConfig {
constructor(public dataDogLogging: boolean,
public dataDogApplicationId: string,
public dataDogClientToken: string,
public dataDogSite: string,
public dataDogService: string) { }
}
27 changes: 16 additions & 11 deletions src/config/config.dev.json
@@ -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": ""
}
7 changes: 6 additions & 1 deletion src/config/config.prod.json
Expand Up @@ -9,5 +9,10 @@
"iiifPath": "",
"geonameToken": "knora",
"jsonWebToken": "",
"logErrors": false
"logErrors": false,
"dataDogLogging": false,
"dataDogApplicationId": "",
"dataDogClientToken": "",
"dataDogSite": "",
"dataDogService": ""
}