├── .gitignore ├── .npmignore ├── .nvmrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.ts ├── package-lock.json ├── package.json ├── src └── app-insight.service.ts ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules/* 3 | npm-debug.log 4 | 5 | # TypeScript 6 | *.js 7 | *.map 8 | *.d.ts 9 | 10 | # JetBrains 11 | .idea 12 | .project 13 | .settings 14 | .idea/* 15 | *.iml 16 | 17 | # VS Code 18 | .vscode/* 19 | 20 | # Windows 21 | Thumbs.db 22 | Desktop.ini 23 | 24 | # Mac 25 | .DS_Store 26 | **/.DS_Store 27 | 28 | # Dist files 29 | dist 30 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules/* 3 | npm-debug.log 4 | 5 | # DO NOT IGNORE TYPESCRIPT FILES FOR NPM 6 | # TypeScript 7 | # *.js 8 | # *.map 9 | # *.d.ts 10 | 11 | # JetBrains 12 | .idea 13 | .project 14 | .settings 15 | .idea/* 16 | *.iml 17 | 18 | # VS Code 19 | .vscode/* 20 | 21 | # Windows 22 | Thumbs.db 23 | Desktop.ini 24 | 25 | # Mac 26 | .DS_Store 27 | **/.DS_Store 28 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 12.16.0 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - '12.16.0' 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 9.0.0 4 | - Upgrade for Angular 11 + 12 5 | - 6 | ## 7.0.0 7 | - Upgrade project to latest Angular v7.x to prevent npm warnings 8 | 9 | ## 6.0.3 10 | - Fix Router injector to handle UIRouter and not throw errors (or set up page tracking metrics) 11 | 12 | ## 6.0.0 13 | - Deprecation warning added for `instrumentationKeySetlater` (will be removed in next major version(?)) 14 | - Use `instrumentationKeySetLater` (capital "L") to match correct AppInsights Interface 15 | - AppInsights context & queue now proxied to prevent undefined when not loaded immediately 16 | 17 | ## 5.x 18 | - for Angular 6.x with Rxjs 6.1+ 19 | 20 | ## 4.x 21 | - Angular 5.x with Rxjs 5.5+ (pipeable operators) 22 | 23 | ## 3.x 24 | - Angular 5.x (with older rxjs < 5.5) 25 | 26 | ## 2.x - NG4 27 | - Updated to Angular 4.0 (use version 1.0.0 for Angular 2.x) 28 | 29 | ## 1.0.0 - Live! 30 | - Added @types/applicationinsights-js types 31 | 32 | ## rc.1 33 | 34 | - ** BREAKING ** Refactor to implement Microsoft.ApplicationInsights.IConfig and Microsoft.ApplicationInsights.IAppInsights 35 | - Refactor config into service and expose full config 36 | - Add call to init to module 37 | 38 | ## rc.0 39 | 40 | - Implemented remaining methods 41 | 42 | 43 | ## 0.3 44 | 45 | - ** BREAKING ** Re-released to NPM package via `@markpieszak/ng-application-insights`, remove the `x` from `ngx`. (According to latest Angular naming guidelines) 46 | - Old npm unpublshed/removed. 47 | - Updated to use applicationinsights-js SDK. 48 | 49 | ## 0.2 50 | 51 | - Released to npm with `@markpieszak/ng-application-insights` -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2022 Mark Pieszak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular Azure Application Insights implementation 2 | 3 | ## Connect your Angular client-side to Microsofts Application Insights with this easy-to-use Module 4 | 5 | > Application Insights is an extensible Application Performance Management (APM) service for web developers on multiple platforms. Use it to monitor your live web application. It will automatically detect performance anomalies. It includes powerful analytics tools to help you diagnose issues and to understand what users actually do with your app. 6 | 7 | [![npm](https://img.shields.io/npm/v/@markpieszak/ng-application-insights.svg?label=npm%20version&color=5b1096&style=for-the-badge)](https://www.npmjs.com/@markpieszak/ng-application-insights) 8 | [![Minzipped Size](https://img.shields.io/bundlephobia/minzip/@markpieszak/ng-application-insights?color=e51384&style=for-the-badge)](https://bundlephobia.com/result?p=@markpieszak/ng-application-insights) 9 | [![NPM Downloads](https://img.shields.io/npm/dw/@markpieszak/ng-application-insights.svg?color=b31ae7&style=for-the-badge)](https://www.npmjs.com/@markpieszak/ng-application-insights) 10 | [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge&color=e51384)](/LICENSE) 11 | 12 | --- 13 | 14 |

15 | 16 | Trilon.io - Angular Universal, NestJS, JavaScript Application Consulting Development and Training 17 | 18 |

19 | 20 |

Made with :heart: by Trilon.io

21 | 22 | --- 23 | 24 | ## Installation 25 | 26 | Install & save the library to your package.json: 27 | 28 | ```bash 29 | $ npm i -S @markpieszak/ng-application-insights 30 | 31 | # yarn 32 | 33 | $ yarn add @markpieszak/ng-application-insights 34 | ``` 35 | 36 | --- 37 | 38 | ### AppModule Setup 39 | 40 | Now add ApplicationInsightsModule to your Angular Root `AppModule`: 41 | 42 | ```typescript 43 | // 1) Import the Application Insights module and the service provider 44 | import { ApplicationInsightsModule, AppInsightsService } from '@markpieszak/ng-application-insights'; 45 | 46 | @NgModule({ 47 | imports: [ 48 | // 2) Add the Module to your imports 49 | ApplicationInsightsModule.forRoot({ 50 | instrumentationKey: 'Your-Application-Insights-instrumentationKey' 51 | }) 52 | ], 53 | providers: [ 54 | // 3) Add AppInsightsService to your providers list 55 | AppInsightsService 56 | ] 57 | }) 58 | export class YourRootModule { } 59 | ``` 60 | 61 | ### What if you don't know your instrumentationKey right away? 62 | 63 | ```typescript 64 | // Use instrumentationKeySetLater 65 | ApplicationInsightsModule.forRoot({ 66 | instrumentationKeySetLater: true // <-- 67 | }) 68 | 69 | // Then later in your Application somewhere 70 | constructor( 71 | private appInsightsService: AppInsightsService 72 | ) { 73 | appInsightsService.config = { 74 | instrumentationKey: __env.APPINSIGHTS_INSTRUMENTATIONKEY // <-- set it later sometime 75 | } 76 | // then make sure to initialize and start-up app insights 77 | appInsightsService.init(); 78 | } 79 | 80 | ``` 81 | 82 | ## Usage 83 | 84 | Through out your application you can now use the AppInsightsService class to fire off AppInsights functionality. 85 | 86 | ```typescript 87 | import { AppInsightsService } from '@markpieszak/ng-application-insights'; 88 | 89 | export class ShoppingCartComponent { 90 | public cart: []; 91 | constructor(private appInsightsService: AppInsightsService) {} 92 | 93 | saveCart(user) { 94 | // MOCK Example of sending a trackEvent() 95 | // Saving some sample user & cart product data 96 | this.appInsightsService.trackEvent('ShoppingCart Saved', { 'user': user.id, 'cart': cart.id }); 97 | } 98 | } 99 | ``` 100 | 101 | ## Usage with Aspnetcore-Angular2-Universal repo or JavaScriptServices ( apps w/ Server-side rendering ) 102 | 103 | > ie: 104 | 105 | First, make sure you are only importing the library & the server within the **browser-app.module** NgModule (do not share it within a common one, as the server isn't able to use this library during it's server-renders). 106 | 107 | Secondly, make sure you are calling the `injector` to get AppInsightsService during **ngOnInit**: 108 | 109 | ```typescript 110 | export class HomeComponent implements OnInit { 111 | 112 | private AIService: AppInsightsService; 113 | private isBrowser: boolean; 114 | 115 | constructor(@Inject(PLATFORM_ID) private platformId, private injector: Injector) { 116 | this.isBrowser = isPlatformBrowser(this.platformId); 117 | } 118 | 119 | ngOnInit() { // <-- 120 | if (this.isBrowser) { // <-- only run if isBrowser 121 | this.AIService = this.injector.get(AppInsightsService); // <-- using the Injector, get the Service 122 | this.AIService.trackEvent('Testing', { 'user': 'me' }); 123 | } 124 | } 125 | } 126 | ``` 127 | 128 | ## API 129 | 130 | You can see a list of the API here: 131 | 132 | ```typescript 133 | AppInsightsService.trackEvent() 134 | AppInsightsService.startTrackEvent() 135 | AppInsightsService.stopTrackEvent() 136 | AppInsightsService.trackPageView() 137 | AppInsightsService.startTrackPage() 138 | AppInsightsService.stopTrackPage() 139 | AppInsightsService.trackMetric() 140 | AppInsightsService.trackException() 141 | AppInsightsService.trackTrace() 142 | AppInsightsService.trackDependency() 143 | AppInsightsService.flush() 144 | AppInsightsService.setAuthenticatedUserContext() 145 | AppInsightsService.clearAuthenticatedUserContext() 146 | ``` 147 | 148 | --- 149 | 150 | # How to Contribute? 151 | 152 | ## ng-Application-Insights Development 153 | 154 | To generate all `*.js`, `*.js.map` and `*.d.ts` files: 155 | 156 | ```bash 157 | npm run build 158 | ``` 159 | 160 | To lint all `*.ts` files: 161 | 162 | ```bash 163 | npm run lint 164 | ``` 165 | 166 | ---- 167 | 168 | # License 169 | 170 | [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge&color=e51384)](/LICENSE) 171 | 172 | Copyright (c) 2016-2022 [Mark Pieszak](https://twitter.com/MarkPieszak) 173 | 174 | [![Twitter Follow](https://img.shields.io/twitter/follow/MarkPieszak.svg?style=social)](https://twitter.com/MarkPieszak) 175 | 176 | ---- 177 | 178 | # Trilon - JavaScript, ASP.NET, Node, NestJS - Consulting | Training | Development 179 | 180 | Check out **[Trilon.io](https://Trilon.io)** for more info! 181 | 182 | Contact us at , and let's talk about your projects needs. 183 | 184 |

185 | 186 | Trilon.io - Angular Universal, NestJS, JavaScript Application Consulting Development and Training 187 | 188 |

189 | 190 | ## Follow Trilon online 191 | 192 | Twitter: [@Trilon_io](http://twitter.com/Trilon_io) 193 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders, Optional, SkipSelf } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { AppInsightsConfig, AppInsightsService } from './src/app-insight.service'; 5 | 6 | export { SeverityLevel, AppInsightsConfig, AppInsightsService } from './src/app-insight.service'; 7 | 8 | @NgModule({ 9 | imports: [ CommonModule ], 10 | declarations: [], 11 | exports: [], 12 | providers: [ AppInsightsService ] 13 | }) 14 | 15 | export class ApplicationInsightsModule { 16 | 17 | constructor ( 18 | @Optional() @SkipSelf() parentModule: ApplicationInsightsModule, 19 | appInsightsService: AppInsightsService 20 | ) { 21 | if (!parentModule) { 22 | appInsightsService.init(); 23 | } 24 | } 25 | 26 | static forRoot(config: AppInsightsConfig): ModuleWithProviders { 27 | return { 28 | ngModule: ApplicationInsightsModule, 29 | providers: [ 30 | { provide: AppInsightsConfig, useValue: config }, 31 | AppInsightsService 32 | ] 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@markpieszak/ng-application-insights", 3 | "description": "Microsoft Azure Application Insights for Angular - Brought to you by Trilon.io", 4 | "version": "9.0.2", 5 | "scripts": { 6 | "lint": "tslint -p tsconfig.json", 7 | "clean": "rimraf ./dist", 8 | "clean.install": "rimraf ./dist ./package-lock.json && npm i", 9 | "build": "npm run clean && npm run tsc && ngc && ngcc", 10 | "tsc": "tsc", 11 | "angular:update": "ng update @angular/cli && ng update @angular/{common,compiler,core,forms,platform-browser,platform-browser-dynamic,router" 12 | }, 13 | "homepage": "https://trilon.io", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/TrilonIO/angular-application-insights" 17 | }, 18 | "author": { 19 | "name": "Mark Pieszak | Trilon Consulting", 20 | "email": "hello@trilon.io", 21 | "url": "https://trilon.io" 22 | }, 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/TrilonIO/angular-application-insights/issues" 26 | }, 27 | "main": "./dist/index.js", 28 | "types": "./dist/index.d.ts", 29 | "dependencies": { 30 | "applicationinsights-js": "^1.0.20", 31 | "@types/applicationinsights-js": "^1.0.9" 32 | }, 33 | "peerDependencies": { 34 | "rxjs": "~6.6.0", 35 | "@angular/router": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0" 36 | }, 37 | "devDependencies": { 38 | "@angular-devkit/build-angular": "~0.801.1", 39 | "@angular/cli": "^11.2.9", 40 | "@angular/common": "^11.2.9", 41 | "@angular/compiler": "^11.2.9", 42 | "@angular/compiler-cli": "^11.2.9", 43 | "@angular/core": "^11.2.9", 44 | "@angular/platform-browser": "^11.2.9", 45 | "@angular/router": "^11.2.9", 46 | "codelyzer": "^4.5.0", 47 | "rimraf": "^2.6.2", 48 | "rxjs": "^6.1.0", 49 | "tslint": "^5.7.0", 50 | "typescript": "~4.1.5", 51 | "zone.js": "^0.9.1" 52 | }, 53 | "engines": { 54 | "node": ">=10.0.0" 55 | }, 56 | "keywords": [ 57 | "angular", 58 | "azure application insights", 59 | "ms application insights", 60 | "application insights", 61 | "angular application insights", 62 | "microsoft application insights", 63 | "ms app insights", 64 | "aspnet core app insights", 65 | "trilon", 66 | "trilon.io", 67 | "angular2", 68 | "angular7", 69 | "angular8", 70 | "angular9", 71 | "angular10", 72 | "angular11", 73 | "angular12" 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /src/app-insight.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Optional, Injector } from '@angular/core'; 2 | import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router'; 3 | import { AppInsights } from 'applicationinsights-js'; 4 | import { filter } from 'rxjs/operators'; 5 | 6 | import IAppInsights = Microsoft.ApplicationInsights.IAppInsights; 7 | 8 | // Since AI.SeverityLevel isn't working we can just use our own 9 | export enum SeverityLevel { 10 | Verbose = 0, 11 | Information = 1, 12 | Warning = 2, 13 | Error = 3, 14 | Critical = 4, 15 | } 16 | 17 | export class AppInsightsConfig implements Microsoft.ApplicationInsights.IConfig { 18 | instrumentationKeySetLater?: boolean; 19 | // Will be deprecated in next major version 20 | instrumentationKeySetlater?: boolean; 21 | instrumentationKey?: string; 22 | endpointUrl?: string; 23 | emitLineDelimitedJson?: boolean; 24 | accountId?: string; 25 | sessionRenewalMs?: number; 26 | sessionExpirationMs?: number; 27 | maxBatchSizeInBytes?: number; 28 | maxBatchInterval?: number; 29 | enableDebug?: boolean; 30 | disableExceptionTracking?: boolean; 31 | disableTelemetry?: boolean; 32 | verboseLogging?: boolean; 33 | diagnosticLogInterval?: number; 34 | samplingPercentage?: number; 35 | autoTrackPageVisitTime?: boolean; 36 | disableAjaxTracking?: boolean; 37 | overridePageViewDuration?: boolean; 38 | maxAjaxCallsPerView?: number; 39 | disableDataLossAnalysis?: boolean; 40 | disableCorrelationHeaders?: boolean; 41 | correlationHeaderExcludedDomains?: string[]; 42 | disableFlushOnBeforeUnload?: boolean; 43 | enableSessionStorageBuffer?: boolean; 44 | isCookieUseDisabled?: boolean; 45 | cookieDomain?: string; 46 | isRetryDisabled?: boolean; 47 | url?: string; 48 | isStorageUseDisabled?: boolean; 49 | isBeaconApiDisabled?: boolean; 50 | sdkExtension?: string; 51 | isBrowserLinkTrackingEnabled?: boolean; 52 | appId?: string; 53 | enableCorsCorrelation?: boolean; 54 | namePrefix?: string; 55 | overrideTrackPageMetrics?: boolean; 56 | enableAutoRouteTracking?: boolean; 57 | enableRequestHeaderTracking?: boolean; 58 | enableResponseHeaderTracking?: boolean; 59 | enableAjaxErrorStatusText?: boolean; 60 | enableAjaxPerfTracking?: boolean; 61 | maxAjaxPerfLookupAttempts?: number; 62 | ajaxPerfLookupDelay?: number; 63 | distributedTracingMode?: boolean; 64 | enableUnhandledPromiseRejectionTracking?: boolean; 65 | disableInstrumentaionKeyValidation?: boolean; 66 | enablePerfMgr?: boolean; 67 | perfEvtsSendAll?: boolean; 68 | 69 | } 70 | 71 | @Injectable() 72 | export class AppInsightsService implements IAppInsights { 73 | 74 | get context(): Microsoft.ApplicationInsights.ITelemetryContext { 75 | return AppInsights.context; 76 | } 77 | get queue(): Array<() => void> { 78 | return AppInsights.queue 79 | } 80 | config: AppInsightsConfig; 81 | 82 | constructor( 83 | @Optional() _config: AppInsightsConfig, 84 | private _injector: Injector 85 | ) { 86 | this.config = _config; 87 | } 88 | 89 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackevent 90 | /** 91 | * Log a user action or other occurrence. 92 | * @param name A string to identify this event in the portal. 93 | * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. 94 | * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. 95 | */ 96 | trackEvent(eventName: string, eventProperties?: { [name: string]: string }, metricProperty?: { [name: string]: number }) { 97 | try { 98 | AppInsights.trackEvent(eventName, eventProperties, metricProperty); 99 | } catch (ex) { 100 | console.warn('Angular application insights Error [trackEvent]: ', ex); 101 | } 102 | } 103 | 104 | /** 105 | * Start timing an extended event. Call {@link stopTrackEvent} to log the event when it ends. 106 | * @param name A string that identifies this event uniquely within the document. 107 | */ 108 | startTrackEvent(name: string): any { 109 | try { 110 | AppInsights.startTrackEvent(name); 111 | } catch (ex) { 112 | console.warn('Angular application insights Error [startTrackEvent]: ', ex); 113 | } 114 | } 115 | 116 | /** 117 | * Log an extended event that you started timing with {@link startTrackEvent}. 118 | * @param name The string you used to identify this event in startTrackEvent. 119 | * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. 120 | * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. 121 | */ 122 | stopTrackEvent(name: string, properties?: { [p: string]: string }, measurements?: { [p: string]: number }): any { 123 | try { 124 | AppInsights.stopTrackEvent(name, properties, measurements); 125 | } catch (ex) { 126 | console.warn('Angular application insights Error [stopTrackEvent]: ', ex); 127 | } 128 | } 129 | 130 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackpageview 131 | /** 132 | * Logs that a page or other item was viewed. 133 | * @param name The string you used as the name in startTrackPage. Defaults to the document title. 134 | * @param url String - a relative or absolute URL that identifies the page or other item. Defaults to the window location. 135 | * @param properties map[string, string] - additional data used to filter pages and metrics in the portal. Defaults to empty. 136 | * @param measurements map[string, number] - metrics associated with this page, displayed in Metrics Explorer on the portal. Defaults to empty. 137 | * @param duration number - the number of milliseconds it took to load the page. Defaults to undefined. If set to default value, page load time is calculated internally. 138 | */ 139 | trackPageView(name?: string, url?: string, properties?: { [name: string]: string }, measurements?: { [name: string]: number }, duration?: number) { 140 | try { 141 | AppInsights.trackPageView(name, url, properties, measurements, duration); 142 | } catch (ex) { 143 | console.warn('Angular application insights Error [trackPageView]: ', ex); 144 | } 145 | } 146 | 147 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#starttrackpage 148 | /** 149 | * Starts timing how long the user views a page or other item. Call this when the page opens. 150 | * This method doesn't send any telemetry. Call {@link stopTrackTelemetry} to log the page when it closes. 151 | * @param name A string that idenfities this item, unique within this HTML document. Defaults to the document title. 152 | */ 153 | startTrackPage(name?: string) { 154 | try { 155 | AppInsights.startTrackPage(name); 156 | } catch (ex) { 157 | console.warn('Angular application insights Error [startTrackPage]: ', ex); 158 | } 159 | } 160 | 161 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#stoptrackpage 162 | /** 163 | * Logs how long a page or other item was visible, after {@link startTrackPage}. Call this when the page closes. 164 | * @param name The string you used as the name in startTrackPage. Defaults to the document title. 165 | * @param url String - a relative or absolute URL that identifies the page or other item. Defaults to the window location. 166 | * @param properties map[string, string] - additional data used to filter pages and metrics in the portal. Defaults to empty. 167 | * @param measurements map[string, number] - metrics associated with this page, displayed in Metrics Explorer on the portal. Defaults to empty. 168 | */ 169 | stopTrackPage(name?: string, url?: string, properties?: { [name: string]: string }, measurements?: { [name: string]: number }) { 170 | try { 171 | AppInsights.stopTrackPage(name, url, properties, measurements); 172 | } catch (ex) { 173 | console.warn('Angular application insights Error [stopTrackPage]: ', ex); 174 | } 175 | } 176 | 177 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackmetric 178 | /** 179 | * Log a numeric value that is not associated with a specific event. Typically used to send regular reports of performance indicators. 180 | * To send a single measurement, use just the first two parameters. If you take measurements very frequently, you can reduce the 181 | * telemetry bandwidth by aggregating multiple measurements and sending the resulting average at intervals. 182 | * @param name A string that identifies the metric. 183 | * @param average Number representing either a single measurement, or the average of several measurements. 184 | * @param sampleCount The number of measurements represented by the average. Defaults to 1. 185 | * @param min The smallest measurement in the sample. Defaults to the average. 186 | * @param max The largest measurement in the sample. Defaults to the average. 187 | */ 188 | trackMetric(name: string, average: number, sampleCount?: number, min?: number, max?: number, properties?: { [name: string]: string }) { 189 | try { 190 | AppInsights.trackMetric(name, average, sampleCount, min, max, properties); 191 | } catch (ex) { 192 | console.warn('Angular application insights Error [trackTrace]: ', ex); 193 | } 194 | } 195 | 196 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackexception 197 | /** 198 | * Log an exception you have caught. 199 | * @param exception An Error from a catch clause, or the string error message. 200 | * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. 201 | * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. 202 | * @param severityLevel SeverityLevel | AI.SeverityLevel - severity level 203 | */ 204 | trackException(exception: Error, handledAt?: string, properties?: { [name: string]: string }, 205 | measurements?: { [name: string]: number }, severityLevel?: SeverityLevel | AI.SeverityLevel) { 206 | try { 207 | AppInsights.trackException(exception, handledAt, properties, measurements, severityLevel); 208 | } catch (ex) { 209 | console.warn('Angular application insights Error [trackException]: ', ex); 210 | } 211 | } 212 | 213 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#tracktrace 214 | // trackTrace(message: string, properties?: {[string]:string}, severityLevel?: SeverityLevel | AI.SeverityLevel) 215 | // Log a diagnostic event such as entering or leaving a method. 216 | /** 217 | * Log a diagnostic message. 218 | * @param message A message string 219 | * @param properties map[string, string] - additional data used to filter traces in the portal. Defaults to empty. 220 | */ 221 | trackTrace(message: string, properties?: { [name: string]: string }, severityLevel?: SeverityLevel | AI.SeverityLevel) { 222 | try { 223 | AppInsights.trackTrace(message, properties, severityLevel); 224 | } catch (ex) { 225 | console.warn('Angular application insights Error [trackTrace]: ', ex); 226 | } 227 | } 228 | 229 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackdependency 230 | /** 231 | * Log a dependency call (for instance: ajax) 232 | * @param id unique id, this is used by the backend o correlate server requests. Use Util.newId() to generate a unique Id. 233 | * @param method represents request verb (GET, POST, etc.) 234 | * @param absoluteUrl absolute url used to make the dependency request 235 | * @param pathName the path part of the absolute url 236 | * @param totalTime total request time 237 | * @param success indicates if the request was sessessful 238 | * @param resultCode response code returned by the dependency request 239 | * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. 240 | * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. 241 | */ 242 | trackDependency(id: string, method: string, absoluteUrl: string, pathName: string, totalTime: number, success: boolean, 243 | resultCode: number, properties?: { [name: string]: string }, measurements?: { [name: string]: number }) { 244 | try { 245 | AppInsights.trackDependency(id, method, absoluteUrl, pathName, totalTime, success, resultCode, properties, measurements); 246 | } catch (ex) { 247 | console.warn('Angular application insights Error [trackDependency]: ', ex); 248 | } 249 | } 250 | 251 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#flush 252 | // flush() 253 | // Immediately send all queued telemetry. Synchronous. 254 | // * You don't usually have to use this, as it happens automatically on window closing. 255 | flush() { 256 | try { 257 | AppInsights.flush(); 258 | } catch (ex) { 259 | console.warn('Angular application insights Error [flush]: ', ex); 260 | } 261 | 262 | } 263 | 264 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#setauthenticatedusercontext 265 | /** 266 | * Sets the authenticated user id and the account id. 267 | * User auth id and account id should be of type string. They should not contain commas, semi-colons, equal signs, spaces, or vertical-bars. 268 | * 269 | * By default the method will only set the authUserID and accountId for all events in this page view. To add them to all events within 270 | * the whole session, you should either call this method on every page view or set `storeInCookie = true`. 271 | * 272 | * @param authenticatedUserId {string} - The authenticated user id. A unique and persistent string that represents each authenticated user in the service. 273 | * @param accountId {string} - An optional string to represent the account associated with the authenticated user. 274 | * @param storeInCookie {boolean} - AuthenticateUserID will be stored in a cookie and added to all events within this session. 275 | */ 276 | setAuthenticatedUserContext(authenticatedUserId: string, accountId?: string, storeInCookie: boolean = false) { 277 | try { 278 | AppInsights.setAuthenticatedUserContext(authenticatedUserId, accountId, storeInCookie); 279 | } catch (ex) { 280 | console.warn('Angular application insights Error [setAuthenticatedUserContext]: ', ex); 281 | } 282 | } 283 | 284 | // https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#clearauthenticatedusercontext 285 | /** 286 | * Clears the authenticated user id and the account id from the user context. 287 | */ 288 | clearAuthenticatedUserContext() { 289 | try { 290 | AppInsights.clearAuthenticatedUserContext(); 291 | } catch (ex) { 292 | console.warn('Angular application insights Error [clearAuthenticatedUserContext]: ', ex); 293 | } 294 | } 295 | 296 | _onerror(message: string): any { 297 | console.warn('Angular application insights Error [_onerror]: ', message); 298 | } 299 | 300 | /** 301 | * Initialize Application Insights for Angular 302 | * Make sure your config{} has been set 303 | */ 304 | public init(): void { 305 | if (this.config) { 306 | 307 | // Deprecation Warning(s) 308 | if (this.config.instrumentationKeySetlater) { 309 | console.warn( 310 | `\n\n 311 | Warning: [instrumentationKeySetlater] will soon be deprecated.\n 312 | Use .instrumentationKeySetLater (capital "L" in "L"ater) instead 313 | to prevent any possible errors in the future! 314 | \n\n`); 315 | } 316 | 317 | if (this.config.instrumentationKey) { 318 | try { 319 | AppInsights.downloadAndSetup(this.config); 320 | 321 | // Make sure "router" exists - in case of UIRouterModule where it does not 322 | if (!this.config.overrideTrackPageMetrics && this.router) { 323 | this.router.events.pipe( 324 | filter(event => event instanceof NavigationStart) 325 | ) 326 | .subscribe((event: NavigationStart) => { 327 | this.startTrackPage(event.url); 328 | }); 329 | 330 | this.router.events.pipe( 331 | filter(event => ( 332 | event instanceof NavigationEnd || 333 | event instanceof NavigationCancel || 334 | event instanceof NavigationError 335 | )) 336 | ) 337 | .subscribe((event: NavigationEnd) => { 338 | this.stopTrackPage(event.url); 339 | }); 340 | } 341 | } catch (ex) { 342 | console.warn('Angular application insights Error [downloadAndSetup]: ', ex); 343 | } 344 | } else { 345 | if (!this.config.instrumentationKeySetLater && !this.config.instrumentationKeySetlater) { 346 | // there is no this.config.instrumentationKey AND no this.config.instrumentationKeySetLater => Add log. 347 | console.warn('An instrumentationKey value is required to initialize AppInsightsService'); 348 | } 349 | } 350 | } else { 351 | console.warn('You need forRoot on ApplicationInsightsModule, with or instrumentationKeySetLater or instrumentationKey set at least'); 352 | } 353 | } 354 | 355 | private get router() { 356 | try { 357 | return this._injector.get(Router); 358 | } catch (ex) { 359 | // @angular/router is not included - App must be utilizing UIRouter 360 | return null; 361 | } 362 | } 363 | } 364 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "skipLibCheck": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "importHelpers": true, 9 | "lib": ["es2015", "dom"], 10 | "sourceMap": true, 11 | "declaration": true, 12 | "outDir": "./dist", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true 20 | }, 21 | "files": [ 22 | "index.ts" 23 | ], 24 | "exclude": [ 25 | "node_modules", 26 | "dist" 27 | ], 28 | "angularCompilerOptions": { 29 | "enableIvy": false, 30 | "skipTemplateCodegen": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "class-name": true, 7 | "comment-format": [ 8 | true, 9 | "check-space" 10 | ], 11 | "curly": true, 12 | "eofline": true, 13 | "forin": true, 14 | "indent": [ 15 | true, 16 | "spaces" 17 | ], 18 | "label-position": true, 19 | "max-line-length": [ 20 | true, 21 | 160 22 | ], 23 | "member-access": false, 24 | "member-ordering": [ 25 | true, 26 | "variables-before-functions" 27 | ], 28 | "no-arg": true, 29 | "no-bitwise": true, 30 | "no-console": [ 31 | true, 32 | "debug", 33 | "info", 34 | "time", 35 | "timeEnd", 36 | "trace" 37 | ], 38 | "no-construct": true, 39 | "no-debugger": true, 40 | "no-duplicate-variable": true, 41 | "no-empty": false, 42 | "no-eval": true, 43 | "no-inferrable-types": true, 44 | "no-shadowed-variable": true, 45 | "no-string-literal": false, 46 | "no-switch-case-fall-through": true, 47 | "no-trailing-whitespace": true, 48 | "no-unused-expression": true, 49 | "no-use-before-declare": true, 50 | "no-var-keyword": true, 51 | "object-literal-sort-keys": false, 52 | "one-line": [ 53 | true, 54 | "check-open-brace", 55 | "check-catch", 56 | "check-else", 57 | "check-whitespace" 58 | ], 59 | "quotemark": [ 60 | true, 61 | "single" 62 | ], 63 | "radix": true, 64 | "semicolon": [ 65 | "always" 66 | ], 67 | "triple-equals": [ 68 | true, 69 | "allow-null-check" 70 | ], 71 | "typedef-whitespace": [ 72 | true, 73 | { 74 | "call-signature": "nospace", 75 | "index-signature": "nospace", 76 | "parameter": "nospace", 77 | "property-declaration": "nospace", 78 | "variable-declaration": "nospace" 79 | } 80 | ], 81 | "variable-name": false, 82 | "whitespace": [ 83 | true, 84 | "check-branch", 85 | "check-decl", 86 | "check-operator", 87 | "check-separator", 88 | "check-type" 89 | ], 90 | "directive-selector": [ 91 | true, 92 | "attribute", 93 | null, 94 | "camelCase" 95 | ], 96 | "component-selector": [ 97 | true, 98 | "element", 99 | null, 100 | "kebab-case" 101 | ], 102 | "use-input-property-decorator": true, 103 | "use-output-property-decorator": true, 104 | "use-host-property-decorator": true, 105 | "no-input-rename": true, 106 | "no-output-rename": true, 107 | "use-life-cycle-interface": true, 108 | "use-pipe-transform-interface": true, 109 | "component-class-suffix": true, 110 | "directive-class-suffix": true 111 | } 112 | } 113 | --------------------------------------------------------------------------------