Application Insights не отслеживает необработанные исключения браузера в приложении Angular

У меня возникла проблема с пакетом SDK Microsoft Application Insights для JavaScript, который был закрыт / исправлен некоторое время назад: https://github.com/Microsoft/ApplicationInsights-JS/issues/282

Я создал новое приложение Angular, используя Angular CLI. Затем я внес эти изменения, следуя эту статью.

Добавлен сервис мониторинга:

import {Injectable} from '@angular/core';
import {AppInsights} from 'applicationinsights-js';

@Injectable()
export class MonitoringService {
  private config: Microsoft.ApplicationInsights.IConfig = {
    instrumentationKey: 'KEY_GOES_HERE',
    enableDebug: true,
    verboseLogging: true
  };

  constructor() {
    if (!AppInsights.config) {
      AppInsights.downloadAndSetup(this.config);
    }
  }

  logPageView(name?: string, url?: string, properties?: any, measurements?: any, duration?: number) {
    AppInsights.trackPageView(name, url, properties, measurements, duration);
  }

  logEvent(name: string, properties?: any, measurements?: any) {
    AppInsights.trackEvent(name, properties, measurements);
  }

  trackException(exception: Error) {
    AppInsights.trackException(exception);
  }
}

Добавил в свой app.component.ts:

import {Component, OnInit} from '@angular/core';
import {MonitoringService} from './monitoring.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [MonitoringService]
})
export class AppComponent implements OnInit {
  title = 'app works!';

  constructor(private monitoringService: MonitoringService) { }

  ngOnInit() {
      this.monitoringService.logPageView();
  }

  throwAnException() {
      this.monitoringService.trackException(new Error('manually track exception'));
      throw 'this should appear in app insights'; // but it doesn't
  }
}

Сделал простую кнопку для выброса исключения в моем app.component.html:

<h1>
  {{title}}
</h1>
<div (click)="throwAnException()">Click to throw an exception</div>

Работает регистрация просмотра страницы, а также отслеживание исключения путем явного вызова trackException. При чтении документации и различных статей у меня сложилось впечатление, что неперехваченные исключения всегда автоматически отправляются в Application Insights. Однако я не вижу никого из них на портале.

Что я мог здесь упустить?

Используя эти версии:

applicationinsights-js: 1.0.11
@types/applicationinsights-js: 1.0.4

person chinaowl    schedule 22.08.2017    source источник
comment
похоже, вы также открыли эту проблему как проблему на нашем github: github.com/Microsoft / ApplicationInsights-JS / issues / 505 Я собирался опубликовать это как предложение :)   -  person John Gardner    schedule 23.08.2017
comment
Ага, это был я!   -  person chinaowl    schedule 23.08.2017


Ответы (2)


Я борюсь с тем же самым, и вот что вам нужно знать, чтобы справиться с этим:

Что происходит?

Angular перехватывает все исключения (проглатывает их!) И просто записывает их в консоль. Я не видел, чтобы это поведение явно описывалось в какой-либо документации, но я тестировал это в коде, так что поверьте мне. С другой стороны, автоматически собираются только неперехваченные исключения! (см. здесь). Для сбора пойманных исключений (как это обычно бывает при использовании angular framework) вы должны явно вызвать trackException() в своем коде.

Как это решить:

Мы реализуем службу (называемую MonitoringService в приведенном ниже коде) для взаимодействия с аналитическими сведениями о приложениях Azure. Затем мы скажем angular использовать эту службу для регистрации исключений в azure ai вместо того, чтобы регистрироваться только в консоли браузера, путем расширения класса ErrorHandler.

1) реализовать MonitoringService:

Мы будем использовать службу с именем MonitoringService для обмена информацией о приложениях Azure. Реализуйте эту услугу следующим образом:

import { Injectable } from "@angular/core";
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { environment } from "@env/environment";

@Injectable({
  providedIn: "root",
})
export class MonitoringService {
  private appInsights: ApplicationInsights;
  constructor() {}
  startMonitoring(): void {
    this.appInsights = new ApplicationInsights({
      config: {
        instrumentationKey: environment.appInsights.instrumentationKey,
      },
    });
    this.appInsights.loadAppInsights();
    this.appInsights.trackPageView();
  }  

  logException(exception: Error, severityLevel?: number) {
    this.appInsights.trackException({
      exception: exception,
      severityLevel: severityLevel,
    });
  }
}

startMonitoring() должен вызываться при запуске приложения.

2) начать мониторинг при запуске приложения:

В проектах Angular в основном есть файл app.component.ts, который принадлежит корневому модулю и загружается / инициализируется как первый компонент. Под термином «запуск приложения» я на самом деле подразумеваю время инициализации этого компонента.
Мы создадим экземпляр MonitoringService, и он начнет свою работу:

import { Component } from '@angular/core';
import { MonitoringService } from 'services/monitoring.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  constructor(
    private monitoringService: MonitoringService
  ) {
    this.monitoringService.startMonitoring();
  }
}

3) Регистрируйте ошибки в аналитических данных приложения, прежде чем они будут поглощены фреймворком:

Расширьте класс ErrorHandler в своем проекте. Этот класс на самом деле является ловушкой для централизованной обработки исключений в angular spa. Используйте этот хук, чтобы регистрировать исключения до того, как они будут поглощены фреймворком:

import { Injectable, ErrorHandler } from '@angular/core';
import { MonitoringService } from './monitoring.service';

@Injectable({
  providedIn: 'root'
})
export class GlobalErrorHandlerService implements ErrorHandler {

  constructor(private monitoringService: MonitoringService) { }
  handleError(error: any): void {
    console.error(error);
    this.monitoringService.logException(error);
  }
}

4) Зарегистрируйте ErrorHandler в Angular:

В AppModule не забудьте зарегистрировать этот обработчик с помощью Angular:

@NgModule({
  providers: [{provide: ErrorHandler, useClass: GlobalErrorHandlerService}]
})
class AppModule {}
person Shahryar Saljoughi    schedule 16.05.2020

Я не думаю, что у AppInsights есть какие-либо знания об Angular, и наоборот, Angular не знает о приложениях, поэтому вам, вероятно, придется добавить это самостоятельно, используя собственный ErrorHandler. Ознакомьтесь с официальной документацией ErrorHandler. Если вы поместите свой this.monitoringService.trackException вызов в handleError, он должен работать нормально.

person Almund    schedule 13.11.2018
comment
При этом, просеивая реализацию AppInsights, у них действительно есть функциональность для глобального перехвата исключений. Я предполагаю, что фреймворк Angular может сделать то же самое и предотвратить возникновение исключения в window.onerror: github.com/Microsoft/ApplicationInsights-JS/blob/ - person Almund; 13.11.2018