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

expose internal log poller #1674

Merged
merged 10 commits into from
Oct 1, 2021
4 changes: 4 additions & 0 deletions AISKU/src/Initialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@ export class Initialization implements IApplicationInsights {
this.core.pollInternalLogs();
}

public stopPollingInternalLogs(): void {
this.core.stopPollingInternalLogs();
}

public addHousekeepingBeforeUnload(appInsightsInstance: IApplicationInsights): void {
// Add callback to push events when the user navigates away

Expand Down
7 changes: 6 additions & 1 deletion AISKULight/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,18 @@ export class ApplicationInsights {
}

private pollInternalLogs(): void {
this.core.pollInternalLogs()
this.core.pollInternalLogs();
}

public stopPollingInternalLogs(): void {
this.core.stopPollingInternalLogs();
}

private getSKUDefaults() {
this.config.diagnosticLogInterval =
this.config.diagnosticLogInterval && this.config.diagnosticLogInterval > 0 ? this.config.diagnosticLogInterval : 10000;
}

}

export {
Expand Down
1,018 changes: 480 additions & 538 deletions common/config/rush/npm-shrinkwrap.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,72 @@ export class ApplicationInsightsCoreTests extends AITestClass {
}
});

// TODO: test stopPollingInternalLogs
this.testCase({
name: "DiagnosticLogger: stop Polling InternalLogs",
useFakeTimers: true,
test: () => {
// Setup
const channelPlugin = new ChannelPlugin();
const appInsightsCore = new AppInsightsCore();
appInsightsCore.initialize(
{
instrumentationKey: "09465199-12AA-4124-817F-544738CC7C41",
diagnosticLogInterval: 1
}, [channelPlugin]);

Assert.equal(0, appInsightsCore.logger.queue.length, "Queue is empty");

// Setup queue
const queue: _InternalLogMessage[] = appInsightsCore.logger.queue;
queue.push(new _InternalLogMessage(1, "Hello1"));
queue.push(new _InternalLogMessage(2, "Hello2"));
appInsightsCore.pollInternalLogs();

// Assert precondition
Assert.equal(2, appInsightsCore.logger.queue.length, "Queue contains 2 items");

// Act
appInsightsCore.stopPollingInternalLogs();
this.clock.tick(1);

// Assert postcondition
Assert.equal(2, appInsightsCore.logger.queue.length, "Queue is not empty");
}
});

// TODO: test stopPollingInternalLogs and check max size of the queue.
this.testCase({
name: "DiagnosticLogger: stop Polling InternalLogs",
useFakeTimers: true,
test: () => {
// Setup
const channelPlugin = new ChannelPlugin();
const appInsightsCore = new AppInsightsCore();
appInsightsCore.initialize(
{
instrumentationKey: "09465199-12AA-4124-817F-544738CC7C41",
diagnosticLogInterval: 1
}, [channelPlugin]);

appInsightsCore.pollInternalLogs();

// Assert precondition
Assert.equal(0, appInsightsCore.logger.queue.length, "Queue contains 0 items");

// Act
appInsightsCore.stopPollingInternalLogs();
let count = 1002;
while(count > 0) {
appInsightsCore.logger.throwInternal(LoggingSeverity.CRITICAL, count, "Test Error");
--count;
}
// this.clock.tick(1000);
// Assert postcondition
Assert.equal(26, appInsightsCore.logger.queue.length, "Queue is not empty");
}
});

// TODO: test logger crosscontamination
this.testCase({
name: "DiagnosticLogger: Logs in separate cores do not interfere",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ export interface IAppInsightsCore extends IPerfManagerProvider {

pollInternalLogs?(eventName?: string): number;

stopPollingInternalLogs?(): void;

/**
* Return a new instance of the IProcessTelemetryContext for processing events
*/
Expand Down
33 changes: 27 additions & 6 deletions shared/AppInsightsCore/src/JavaScriptSDK/AppInsightsCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import { arrForEach, isNullOrUndefined, toISOString, throwError } from "./Helper
export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
constructor() {
super();
/**
* Internal log poller
*/
let _internalLogPoller: number = 0;

dynamicProto(AppInsightsCore, this, (_self, _base) => {

Expand Down Expand Up @@ -67,17 +71,18 @@ export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
}

/**
* Periodically check logger.queue for
* Periodically check logger.queue for log messages to be flushed
*/
_self.pollInternalLogs = (eventName?: string): number => {
let interval = _self.config.diagnosticLogInterval;
if (!interval || !(interval > 0)) {
interval = 10000;
}

return setInterval(() => {
if(_internalLogPoller) {
_self.stopPollingInternalLogs();
}
_internalLogPoller = setInterval(() => {
const queue: _InternalLogMessage[] = _self.logger ? _self.logger.queue : [];

arrForEach(queue, (logMessage: _InternalLogMessage) => {
const item: ITelemetryItem = {
name: eventName ? eventName : "InternalMessageId: " + logMessage.messageId,
Expand All @@ -86,13 +91,22 @@ export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
baseType: _InternalLogMessage.dataType,
baseData: { message: logMessage.message }
};

_self.track(item);
});
queue.length = 0;
}, interval) as any;
return _internalLogPoller;
}


/**
* Stop polling log messages from logger.queue
*/
_self.stopPollingInternalLogs = (): void => {
if(!_internalLogPoller) return;
clearInterval(_internalLogPoller);
_internalLogPoller = 0;
}

function _validateTelemetryItem(telemetryItem: ITelemetryItem) {
if (isNullOrUndefined(telemetryItem.name)) {
_notifyInvalidEvent(telemetryItem);
Expand Down Expand Up @@ -142,4 +156,11 @@ export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
return 0;
}

/**
* Periodically check logger.queue for
*/
public stopPollingInternalLogs(): void {
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
}
}
3 changes: 1 addition & 2 deletions shared/AppInsightsCore/src/JavaScriptSDK/DiagnosticLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class _InternalLogMessage{
export function safeGetLogger(core: IAppInsightsCore, config?: IConfiguration): IDiagnosticLogger {
return (core || {} as any).logger || new DiagnosticLogger(config);
}

export class DiagnosticLogger implements IDiagnosticLogger {
public identifier = 'DiagnosticLogger';

Expand Down Expand Up @@ -187,7 +187,6 @@ export class DiagnosticLogger implements IDiagnosticLogger {
if (_messageCount === _self.maxInternalMessageLimit()) {
const throttleLimitMessage = "Internal events throttle limit per PageView reached for this app.";
const throttleMessage = new _InternalLogMessage(_InternalMessageId.MessageLimitPerPVExceeded, throttleLimitMessage, false);

_self.queue.push(throttleMessage);
_self.warnToConsole(throttleLimitMessage);
}
Expand Down